Home > Mobile >  Custom ggplot legend by group
Custom ggplot legend by group

Time:12-23

I want to create a graph like below but with a custom legend by group. I have two samples names A and B and a target (Y) associated. what I want is to group the legend with one side :
sample A : true vs obs
and other side
sample B : true vs obs
with the corresponding shape and color. Below, this is what I already had.

library(ggplot2)
sites = rep(seq(0.55,0.58,0.01), times = 4)
sites = sort(sites)

org = rep(c("Y_A", "Y_A_obs", "Y_b", "Y_b_obs"), times = 4)
values = rnorm(16)

df = data.frame(sites = sites, origine = org, values = values)

ggplot(df, aes(x=sites, y=values, color=origine))   
  geom_point(aes(shape=origine, color=origine), size=3) 
  scale_shape_manual(values=c(0, 15, 2, 17)) 
  scale_color_manual(values=c("blue", "purple", "red", "orange"))

enter image description here

And this is what I want: enter image description here

Thanks for any help !

CodePudding user response:

One option to achieve your desired result would be to make use of the ggnewscale package which allows for multiple scales and legends for the same aesthetic(s). Drawback of this method is that it doubles the lines of code:

library(ggplot2)
library(ggnewscale)

set.seed(123)

sites = rep(seq(0.55,0.58,0.01), times = 4)
sites = sort(sites)

org = rep(c("Y_A", "Y_A_obs", "Y_b", "Y_b_obs"), times = 4)
values = rnorm(16)

df = data.frame(sites = sites, origine = org, values = values)

ggplot()   
  geom_point(data = subset(df, grepl("^Y_A", org)), aes(x=sites, y=values, shape=origine, color=origine), size=3) 
  scale_shape_manual(name = "A", values=c(Y_A = 0, Y_A_obs = 15), 
                     labels=c(Y_A = "y_true", Y_A_obs = "y_pred"), 
                     guide = guide_legend(order = 1)) 
  scale_color_manual(name = "A", 
                     values=c(Y_A = "blue", Y_A_obs = "purple"), 
                     labels=c(Y_A = "y_true", Y_A_obs = "y_pred"), 
                     guide = guide_legend(order = 1))  
  new_scale_color()  
  new_scale("shape")  
  geom_point(data = subset(df, grepl("^Y_b", org)), aes(x=sites, y=values, shape=origine, color=origine), size=3) 
  scale_shape_manual(name = "B", 
                     values=c(Y_b = 2, Y_b_obs = 17), 
                     labels=c(Y_b = "y_true", Y_b_obs = "y_pred"), 
                     guide = guide_legend(order = 2)) 
  scale_color_manual(name = "B", 
                     values=c(Y_b = "red", Y_b_obs = "orange"), 
                     labels=c(Y_b = "y_true", Y_b_obs = "y_pred"),
                     guide = guide_legend(order = 2))

  • Related