Search code examples
rplotlegendigraph

How to customize the min and max vertex size when plot igraph object and create legend at selected vertex size


Here is an igraph object with 10 vertices and each vertex is assigned one of two colors. I want to plot this graph with vertex size varying by a variable called val, which is a vector of length 10 and ranges from 1 to 10, corresponding to the 10 vertices in the graph.

library(igraph)

g <- make_ring(10)

val = 1:10
pal <- c("pink", "steelblue")
V(g)$color <- c(rep("pink", 5), rep("steelblue", 5))

pdf("aa.pdf", width = 7, height = 7)
plot(g, layout = layout_with_fr, 
     vertex.size = val, cex = 0.5,
     vertex.frame.color = NA, edge.color = adjustcolor("#c7c7c7", alpha.f = 0.9))
legend(-1.3, -0.9, legend = val, 
       pch = 21, 
       pt.bg = pal, # Color of filled legend
       col = pal, # Color of legend symbol border
       bty="n", #Remove legend border
       # horiz = T, 
       ncol = 5
       )
dev.off()

Here is the output graph: enter image description here

If I understand correctly, the size of the 10th vertex in the graph is val[10], which is 10. The size of the first vertex in the graph is val[1], which is 1. Q1: How to customize the size of vertices such that vertices size still vary by val but the largest vertex size (i.e., the 10th vertex) is plotted with point size 15 and the smallest vertex size (i.e., the first vertex) is plotted with point size 2, and other vertices sizes are scaled accordingly between 2 and 15 in some way?

Q2: In addition, how to create a legend of black (not colored) points showing the size of vertices only at val values of 1, 4, 8, and 10?


Solution

  • This level of customization is much easier using the tidygraph / ggraph ecosystem:

    library(igraph)
    library(tidygraph)
    library(ggraph)
    
    make_ring(10) %>%
      as_tbl_graph() %>%
      mutate(val = 1:10, color = rep(c('pink', 'steelblue'), each = 5)) %>%
      ggraph() +
      geom_edge_link() +
      geom_node_point(aes(size = val, fill = color), shape = 21) +
      geom_node_text(aes(label = val)) +
      scale_fill_identity() +
      scale_size_area(max_size = 15, breaks = c(1, 4, 8, 10),
                      guide = guide_legend(override.aes = list(fill = 'black'))) +
      coord_equal(clip = 'off') +
      theme_graph() +
      theme(legend.position = 'bottom')
    

    enter image description here