rlegendedgesarrowsggraph

How do I avoid plotting the arrows in the aesthetic legends of the edges using ggraph in R?


I am trying to do a network flow graph using the ggraph in R. However, I am having several problems while plotting the legend of the different aesthetics of geom_edge_fan. My graph is as follows:  ggraph flow network

As you can see, the legend item pointed to by the blue arrow is distorted, and I am having a lot of problems solving it. The best thing that would help me is not plotting the arrows in the legends of the different aesthetics; however, I still want the arrows in the network plot. I have tried a lot of things to avoid this problem but can't solve it. My code is the following:

ggraph(graph, coords) +
  ggtitle(glue('Viatges entre dos estacions en el barri {nom_barri} el dia {start_date}')) +
  geom_edge_fan(aes(color=type, width=frecuency, alpha=frecuency), 
                arrow = arrow(type = "closed", length = unit(7, 'mm'))
                ) +
  scale_edge_width(limits=c(minimum, maximum), breaks=c(minimum, maximum), name="Freqüència segons gruix") +
  scale_edge_alpha(limits=c(minimum,maximum), breaks=c(minimum, maximum), name="Freqüència segons opacitat") +
  scale_edge_color_discrete( name="Tipus de viatge", labels=c("anada", "tornada")) +
  geom_node_point(size = 9, colour = "#1f77b4") +
  geom_node_text(aes(label = name), colour = 'white') + 
  guides(width = guide_legend(title = "Gruix segons freqüència", override.aes = list(arrow = NULL))) +
  theme(plot.title = element_text(size = 20, hjust = 0.5, family = "Calibri"), legend.key.height = unit(10, "mm"), legend.key.size = unit(3,"line"))

As you can see, I have tried to erase the arrows from the legends using guides, but it doesn't work. I would be grateful if somebody could help me. I'm not proficient in ggraph and I have spent a lot of hours trying to solve it. Thank you in advance.

I have tried several things, like erasing the arrows from the legend using guides (with no results). I want the arrows in the graph but not in the legend, and I haven't been able to find anybody who could help me.


Solution

  • As the arrow argument isn't an aesthetic using the override.aes argument of guide_legend will not work. But one option to get rid of the arrows would be to use a custom draw key function, which is the part which is defines and draws the legend keys. To this end you could simply copy and paste the original draw key function called by geom_edge_fan which is GeomEdgePath$draw_key and remove the arrow argument.

    As you provided no example data I created my own reproducible example based on the default example from ggraph.

    First let's reproduce your issue:

    library(ggraph)
    library(tidygraph)
    
    # Create graph of highschool friendships
    graph <- as_tbl_graph(highschool) %>%
      mutate(Popularity = centrality_degree(mode = "in"))
    
    p <- ggraph(graph, layout = "kk") +
      scale_edge_width(name = "Freqüència segons gruix") +
      scale_edge_alpha(name = "Freqüència segons opacitat") +
      scale_edge_color_discrete(name = "Tipus de viatge", labels = c("anada", "tornada")) +
      geom_node_point() +
      theme_graph(foreground = "steelblue", fg_text_colour = "white")
    
    p +
      geom_edge_fan(aes(color = factor(year), width = after_stat(index), alpha = after_stat(index)),
        arrow = arrow(type = "closed", length = unit(1, "mm"))
      )
    #> Warning: Using the `size` aesthetic in this geom was deprecated in ggplot2 3.4.0.
    #> ℹ Please use `linewidth` in the `default_aes` field and elsewhere instead.
    

    Now, to get rid of the arrows in the legend I add a custom draw key function draw_key_cust and set the key_glyph argument of geom_edge_fan to use this custom function, i.e. key_glyph = "cust":

    # Copy and paste from ggplot2
    "%||%" <- function(a, b) if (is.null(a)) b else a
    # Copy and paste from GeomEdgePath$draw_key
    # ... but removed the arrow argument from grid::segmentsGrob
    draw_key_cust <- function(data, params, size) {
      grid::segmentsGrob(0.1, 0.5, 0.9, 0.5,
        gp = grid::gpar(
          col = alpha(
            data$edge_colour,
            data$edge_alpha
          ), fill = alpha(params$arrow.fill %||%
            data$edge_colour %||% data$edge_fill %||% "black", data$edge_alpha),
          lwd = data$edge_width * .pt, lty = data$edge_linetype,
          lineend = "butt"
        )
      )
    }
    
    p +
      geom_edge_fan(aes(color = factor(year), width = after_stat(index), alpha = after_stat(index)),
        arrow = arrow(type = "closed", length = unit(1, "mm")), key_glyph = "cust"
      )