Насколько я понимаю здесь проблема, ggrepel
, который является пакетом, используемым geom_node_text
, имеет доступ только к слою, на котором находятся узлы, и не «видит» края. Это делает ggrepel
не очень подходящим для сетей (или я что-то упускаю).
К сожалению, у меня тоже нет очень хорошего решения этой проблемы, хотя я уже давно ищу его. Вот два предложения, как вы (или кто-либо другой) могли бы перейти к лучшему способу маркировки с помощью ggraph()
:
1: текст как узлы
Поэтому у меня была одна идея - позволить алгоритму компоновки сети делать всю работу за нас. Я делаю еще один набор узлов, содержащих только метки. Узлы меток подключены только к одному соответствующему узлу в сети, которую они маркируют. Вот так:
library(dplyr)
library(ggraph)
library(tidygraph)
set.seed(123)
reprex <- tibble(from = sample(1:10, 100, replace = TRUE),
to = sample(1:10, 100, replace = TRUE)) %>%
as_tbl_graph() %>%
activate(edges) %>%
mutate(color = "grey")
Я добавляю здесь серый цвет края, так как на финальном графике у нас будет два разных цвета.
nodes <- reprex %>%
activate(nodes) %>%
as_tibble() # extract data.frame of nodes
# create new graph with just the lables
labels <- tibble(from = 1:10,
to = 11:20) %>%
as_tbl_graph() %>%
activate(nodes) %>%
mutate(label1 = "label",
is_label = !name %in% nodes$name) %>%
activate(edges) %>%
mutate(color = "black")
# join graph and labels
new_graph <- graph_join(labels, reprex, by = "name")
Теперь, когда у нас есть новый граф с узлами меток, мы можем построить. Обратите внимание, что я добавил переменную is_label
в новый граф, чтобы мы могли использовать разные формы узлов и убедиться, что помечены только узлы меток:
reprex_plot <- new_graph %>%
ggraph() +
geom_edge_link(aes(color = color)) +
geom_node_point(aes(filter = !is_label, shape = "circle"), show.legend = FALSE) +
scale_edge_color_identity() +
geom_node_text(aes(filter = is_label, label = label1), hjust = -0.1) +
theme_void()
reprex_plot
Ясно, что есть ОЧЕНЬ возможности для улучшения. Метки теперь очень далеко от узлов. Они по-прежнему перекрываются своими собственными краями (хотя, я думаю, это можно решить, предоставив лучшие значения hjust). И хотя это хорошо работает с автоматическим макетом, другие макеты могут делать странные вещи в зависимости от ваших данных. Я очень надеюсь, что кто-то другой найдет лучшее решение. Но я подумал, что можно было бы выложить это здесь. Может, кто-то почувствует вдохновение.
2: метки вместо текста
Другой способ обойти проблему - использовать белый фон для текста. Это решение основано на том, как программы с графическим интерфейсом для построения сетевых графиков решают эту проблему. Мы можем использовать для этого geom_label
ggplot2
, хотя geom_node_label()
добьется того же. Это решение намного более простое, но также ограниченное. Вот все это в одной трубе:
tibble(from = sample(1:10, 100, replace = TRUE),
to = sample(1:10, 100, replace = TRUE)) %>%
as_tbl_graph() %>%
activate(nodes) %>%
mutate(label1 = "label") %>%
ggraph() +
geom_edge_link(color = "grey") +
geom_node_point() +
geom_label(aes(x = x, y = y, label = label1), nudge_y = 0.1, label.size = NA) +
theme_void()
Я удалил границу с этикеток и поместил их прямо над их узлами (nudge_y = 0.1
). Ваши результаты могут отличаться в зависимости от размера графика, поэтому вам может потребоваться изменить это значение.
В более крупных сетях белые прямоугольники меток могут закрывать другие узлы.
person
JBGruber
schedule
02.04.2019