Search code examples
rggplot2legendsummary

Add total or average to ggplot with color legend


I have a plot with a color legend, and would like to add a total/average geom_... series to it.

For example:

d <- ggplot(data=mtcars, aes(x=cyl, y=mpg, color=factor(vs))) + geom_point()
d + stat_summary(fun.y = "mean", fun.ymin = "mean", fun.ymax = "mean", colour = "black")

example plot

I would like the total geom_ color to be black (which is working in my example), and to have a label of "total" in the legend (which is missing from the example). The new "total" label should be the last value in the legend.

In this example the factor levels of vs are 0 and 1. This oversimplifies my case in two ways:

  1. I have lots of factors levels, so I am looking for a solution that does not require manual manipulation of the colors/labels in the legend.
  2. "Total" is naturally last in this data set (since it comes after 0 and 1, alphabetically), but in my data set it comes somewhere in the middle. So the factors might need to be reordered? For the sake of this example data set assume the "total" should be listed first, to show how to reorder the labels.

Lastly, there will be times that I don't think stat_summary will be able to calculate the mean correctly, so I would like the flexibility of calculating the mean or total manually via a second data set. For example:

d + geom_point(data = as.data.table(mtcars)[, list(avg = mean(mpg)), by = "cyl"] ... )

Solution

  • One approach would be to override another unused geom for total, ala the answer to this related question:

    d <- ggplot(data=mtcars, aes(x=cyl, y=mpg, color=factor(vs))) + geom_point()
    d + stat_summary(fun.y = "mean", fun.ymin = "mean", fun.ymax = "mean", 
                     colour = "black", aes(shape="total"), geom="point") +
        guides(colour=guide_legend(order=1), shape=guide_legend(title=NULL, order=2))
    

    resultant plot