Домашнее задание: Визуализация графов

Анализ по датасету Записок о Гальской войне

Author

Ярослав Курганов

Published

09.03.2026

Abstract
Домашнее задание по визуализации сетей на основе латинского текста.
library(udpipe)
library(tidyverse)
library(tidygraph)
library(ggraph)
library(httr)

#Загружаем данные
set_config(config(ssl_verifypeer = 0L))
url <- "https://github.com/locusclassicus/text_analysis_2024/raw/main/files/bg_latinpipe.conllu"
caesar <- udpipe_read_conllu(url)

#расчет существительных
cooc_data <- cooccurrence(
    caesar |> filter(upos == "NOUN"), 
    term = "lemma", 
    group = c("doc_id", "sentence_id")
  ) |> 
  as_tibble() |> 
  filter(cooc > 40)

#создаем граф
graph_data <- as_tbl_graph(cooc_data, directed = FALSE) |>
  mutate(
    degree = centrality_degree(),
    group = ifelse(degree > 3, "Частые", "Редкие"),
    component = group_components()
  ) |> 
  filter(component == 1)

#визуализация
set.seed(21092024)

ggraph(graph_data, layout = "fr") + 
  geom_edge_arc(aes(edge_width = cooc),
                color = "#2C3E50", 
                alpha = 0.8, 
                strength = 0.1, 
                arrow = arrow(angle = 25, 
                              length = unit(0.2, "cm"), 
                              ends = "both", 
                              type = "closed"),
                start_cap = circle(10, "mm"), 
                end_cap = circle(10, "mm"),
                show.legend = FALSE) +
  
  geom_node_point(aes(size = degree, fill = group), 
                  shape = 21, 
                  color = "black", 
                  stroke = 1.2) +
  
  geom_node_text(aes(label = name), 
                 nudge_y = 1.2, 
                 size = 4.5, 
                 fontface = "bold") +
  
  #прописываем цвета
  scale_fill_manual(values = c("Частые" = "#0000FF", "Редкие" = "#FF0000")) +
  scale_size(range = c(4, 10), guide = "none") +
  scale_edge_width(range = c(0.8, 3.5)) +
  
  scale_y_continuous(expand = expansion(mult = c(0.2, 0.3))) +
  scale_x_continuous(expand = expansion(mult = 0.2)) +
  
  theme_graph(base_family = "sans") +
  theme(legend.position = "bottom") +
  labs(
    title = "Сеть связей существительных",
  )

Стоит отметить: при рендеринге почему-то не отображаются все связи с необходимыми “стрелками”. Для ясности прикрепляю финальный вариант.