Adding multiple legends to ggplot

后端 未结 1 883
傲寒
傲寒 2021-01-15 16:21

I have following multi-layered plot:

df <- data.frame(number = 1:10, 
                 values = rnorm(10), 
                 decision = factor(rbinom(10,1         


        
相关标签:
1条回答
  • 2021-01-15 16:47

    To add legends, the first thing to do is to actually map something to the desired aesthetic. For example, right now you've set the point shape as x, but you didn't map it inside of aes so you don't get a legend. You can map to constants as well as to variables to force a legend.

    For your geom_point layer, you can just move shape inside aes, mapped to whatever constant you like. Using some value that indicates what it is will make the legend editing easier.

    geom_point(data=df, aes(x=number, y=expValues, shape = "Expected value"), size = 5, color = "blue")
    

    For the geom_hline, you'll need a dataset specific to the layer for mapping purposes. Depending on the route you go, you may also need to set show_guide to TRUE in this layer.

    geom_hline(data = data.frame(yint = mean(df$values)), aes(...), show_guide = TRUE)
    

    You could make two separate legends. You could also combine the line and shapes into a single legend as in this answer here. Both options will involve setting values in the appropriate scale_xxx_manual and using override.aes in guide_legend.

    Here is how you could make a single new legend. Notice I had to add geom_hline before geom_line to make the decision legend look right.

    ggplot(df, aes(x = number, y = values, color=decision, group = NA)) +
        geom_hline(data = data.frame(yint = mean(df$values)),
            aes(yintercept = yint, shape = "Cut value"), 
                 color="blue", linetype = 2, show_guide = TRUE) +
        geom_line(size = 1) + 
        geom_point(size = 3,shape = 16) + 
        geom_smooth(data = df, aes(ymin = values-bandwidth , ymax = values+bandwidth), 
                  stat = "identity") +
        geom_point(data=df, aes(x=number, y=expValues, shape = "Expected value"), 
                 size = 5, color = "blue") +
        geom_text(data = data.frame(x = Inf, y = max(df$values), label = "Mean  = 12"), 
            aes(label=label, x =  x, y = y),
            hjust = 1, vjust = -0.1, color = "brown", size = 10) +      
        theme(text=element_text(size=20)) +
        scale_shape_manual(name = "", values = c("x", "x")) +
        guides(shape = guide_legend(override.aes = list(linetype = c(2, 0), 
                                                shape = c(NA, "x"))))
    

    Edit Add a legend for the error band ribbon

    I couldn't quite get things working with fill to add a third legend based on the error band ribbon. You could do this as three separate legends, although I don't think the spacing is as nice:

    ggplot(df, aes(x = number, y = values, color=decision, group = NA)) +
        geom_hline(data = data.frame(yint = mean(df$values)),
            aes(yintercept = yint, linetype = "Cut value"), 
                 color="blue", show_guide = TRUE) +
        geom_line(size = 1) + 
        geom_point(size = 3,shape = 16) + 
        geom_smooth(data = df, aes(ymin = values-bandwidth , ymax = values+bandwidth, fill = "Error band"), 
                  stat = "identity") +
        geom_point(data=df, aes(x=number, y=expValues, shape = "Expected value"), 
                 size = 5, color = "blue") +
        geom_text(data = data.frame(x = Inf, y = max(df$values), label = "Mean  = 12"), 
            aes(label=label, x =  x, y = y),
            hjust = 1, vjust = -0.1, color = "brown", size = 10) +  
        theme(text=element_text(size=20)) +
        scale_shape_manual(name = "", values = "x") +
        scale_linetype_manual(name = "", values = 2) +
        scale_fill_manual(name = "", values = "grey") +
        guides(shape = guide_legend(override.aes = list(linetype = 0)),
              fill = guide_legend(override.aes = list(linetype = 0)),
              color = guide_legend(override.aes = list(fill = NA)))
    

    Alternatively, with some work inside override.aes, this could be done with the combination of colour and size along with linetype and shape.

    ggplot(df, aes(x = number, y = values, color=decision, group = NA)) +
        geom_hline(data = data.frame(yint = mean(df$values)),
            aes(yintercept = yint, shape = "Cut value"), 
                 color="blue", linetype = 2, show_guide = TRUE) +
        geom_line(size = 1) + 
        geom_point(size = 3,shape = 16) + 
        geom_smooth(data = df, aes(ymin = values-bandwidth , ymax = values+bandwidth, shape = "Error band"), 
                  stat = "identity", show_guide = FALSE) +
        geom_point(data=df, aes(x=number, y=expValues, shape = "Expected value"), 
                 size = 5, color = "blue") +
        geom_text(data = data.frame(x = Inf, y = max(df$values), label = "Mean  = 12"), 
            aes(label=label, x =  x, y = y),
            hjust = 1, vjust = -0.1, color = "brown", size = 10) +  
        theme(text=element_text(size=20)) +
        scale_shape_manual(name = "", values = rep("x", 3)) +
        guides(shape = guide_legend(override.aes = list(linetype = c(2, 1, 0), 
                                               size = c(.5, 10, 5),
                                               shape = c(NA, NA, "x"),
                                               colour = c("blue", "grey75", "blue"))))
    
    0 讨论(0)
提交回复
热议问题