Home > other >  ggplot2 multiple legends when size is defined in more than one layer
ggplot2 multiple legends when size is defined in more than one layer

Time:10-12

I am plotting a collaborator network, where point size is scaled by the number of articles written in a country and lines between points represent collaborations, with line width and opacity scaled by number of collaborations. E.g.

library(tidyverse)

# data for lines
df_links <- structure(list(from = c("Argentina", "Argentina", "Canada",
                        "Austria", "Austria", "Italy", "Austria",
                        "Italy", "New Zealand"),
               to = c("Canada", "Germany", "Germany", "Italy",
                      "New Zealand", "New Zealand", "Panama",
                      "Panama", "Panama"), 
               collabs = c(1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L),
               x = c(-64, -64, -106, 15, 15, 13, 15, 13, 175),
               y = c(-38, -38, 56, 48, 48, 42, 48, 42, -41),
               x_end = c(-106, 10, 10, 13, 175, 175, -81, -81, -81),
               y_end = c(56, 51, 51, 42,-41, -41, 9, 9, 9)),
          row.names = c(NA, -9L),
          class = c("tbl_df", "tbl", "data.frame"))

# data for points 
df_points <- structure(list(name = c("Argentina", "Austria", "Australia", 
                        "Canada", "Germany", "France", "United Kingdom", 
                        "Italy", "New Zealand", "Panama", "Venezuela"),
               papers = c(1L, 1L, 1L, 22L, 3L, 2L, 1L, 1L, 2L, 1L, 1L),
               x = c(-64, 15, 134, -106, 10, 2, -3, 13, 175, -81, -67),
               y = c(-38, 48, -25, 56, 51, 46, 55, 42, -41, 9, 6)),
          row.names = c(NA, -11L),
          class = c("tbl_df", "tbl", "data.frame"))

#plot
ggplot()   
  geom_curve(data = df_links,
             aes(x = x, y = y,
                 xend = x_end,
                 yend = y_end,
                 size = collabs,
                 alpha = collabs),
             curvature = 0.33)  
  geom_point(data = df_points,
             aes(x = x,
                 y = y,
                 size = papers),
             colour = "red")  
  coord_fixed(xlim = c(-150, 180), ylim = c(-55, 80))  
  theme_void()

enter image description here

My problem is with the legends. I want:

  1. a legend named collabs which has line thickness and line opacity
  2. a legend named papers which is point size

Instead I have papers and collabs (line size and point size) in one legend and opacity in a second. I think the issue is because I am using size inside aes for both geom_curve and geom_point?

E.g. I want something like this (edited in inkscape) enter image description here

Any advice would be much appreciated!

CodePudding user response:

This could be achieved via the ggnewscale package which allows for multiple scales and legends for the same aesthetic:

library(tidyverse)
library(ggforce)
library(ggnewscale)

ggplot()   
  geom_curve(data = df_links,
             aes(x = x, y = y,
                 xend = x_end,
                 yend = y_end,
                 size = collabs,
                 alpha = collabs),
             curvature = 0.33)  
  new_scale("size")  
  geom_point(data = df_points,
             aes(x = x,
                 y = y,
                 size = papers),
             colour = "red")  
  coord_fixed(xlim = c(-150, 180), ylim = c(-55, 80))  
  theme_void()

  • Related