简体   繁体   中英

Add mean, 1st, and 3rd quartile to the legend of box plot combined with point plot in ggplot2

I have a list of data and I am trying to plot a geom_boxplot for the rows that have Sample in the column Names and geom_point for the rows that have Baseline and AASHTO in the column Names . Below is an example of the original data. the data is stored in a list of dataframes Plot . I melt the list plot in order to plot the data into a series of plots using ggplot2 . The row names are changed to a column Names .

> print(92-9)

         Ext_Multi.lane       Ext_Single.lane         Int_Multi.lane         Int_Single.lane
Baseline    0.6032482            0.4538187               0.5231752              0.3322632
Sample1     0.6149284            0.4642462               0.5081119              0.3216861
Sample2     0.6001208            0.4533191               0.5475499              0.3476186
Sample3     0.6046788            0.4554548               0.5202980              0.3325371
Sample4     0.5977068            0.4486637               0.4949881              0.3144831
Sample5     0.6262543            0.4699707               0.5162286              0.3255193
Sample6     0.6215877            0.4660442               0.5074719              0.3237629
Sample7     0.5985551            0.4512014               0.5410862              0.3450809
Sample8     0.5806672            0.4369405               0.5287744              0.3352956
Sample9     0.5997632            0.4516018               0.5185527              0.3279376
Sample10    0.5723757            0.4347169               0.5530330              0.3531976
AASHTO      0.7520000            NA                      0.6620000              0.4260000
Mean        0.6016638            0.4532159               0.5236095              0.332711

The code I use is:

Plot <- map2(Shear_melt, Moment_melt, ~ full_join(.x, .y) %>%
        mutate(Names = str_remove(Names, "\\d+$")))

for (m in 1:length(Plot)) {
  plot.Moment <- ggplot(data = subset(Plot[[m]], Names = "Sample"), aes(x = Type, y = Moment)) + 
    geom_boxplot(outlier.shape = NA) +
    stat_summary(fun = mean, geom="point", shape=23, size=3) + 
    stat_boxplot(geom='errorbar', linetype=1, width=0.5) + 
    geom_point(data = subset(Plot[[m]], Names != "Sample"), aes(colour = Names)) +
    scale_color_manual(values=c("red","green4","black")) + 
    theme(axis.title.x=element_blank()) +
    theme(axis.title.y=element_blank()) +
    labs(title = "Moment Live Load Distribution Factors",
         color =  paste('UG', names(Plot)[m])) +
    theme(plot.title = element_text(hjust = 0.5), 
          legend.title = element_text(hjust = 0.5))
  print(plot.Moment)
}

But I can only get the legend for geom_point to show on the plots. I tried geom_boxplot(outlier.shape = NA) but that messes up the plot. How to I add the labels for mean and quartile to show in thee legend for the geom_boxplot ? 在此处输入图像描述

As I understand, you currently have a legend showing AASHTO and Baseline, and you were looking to also show in a legend the points that you are also adding to the plot (in your case, it's the diamond for the mean as one of the other things you want to add in the legend).

Some general points first: ggplot creates legends for aes(...) calls, and it's not really easy (maybe it's possible) to combine different aes(...) type calls into one legend. So, for example, if you have calls to aes(color=...) and aes(shape=...) , you're going to have the creation of two separate legends unless you add some fancy coding.

So the general idea for your case is to contain your stat_summary(...) call to include "shape" within an aes(...) . Here's a demo dataset to illustrate the point:

df <- data.frame(x=1:100, y=rnorm(100, 0.5), z=rnorm(100, 0.6, 2))
df <- df %>% gather(myThings, myValues, -x)
ggplot(df, aes(x, myValues)) + geom_point(aes(color=myThings)) +
    geom_point(data=data.frame(x=50,myValues=2), shape=23, size=3)

在此处输入图像描述

To get that diamond shape added to appear in the legend, you need to make shape appear in aes(...) . The label in the legend is the label for shape in aes() . So that means if we want to call it "Mean" in the legend, we use this:

ggplot(df, aes(x, myValues)) + geom_point(aes(color=myThings)) + 
    geom_point(data=data.frame(x=50,myValues=2), aes(shape='Mean'))

在此处输入图像描述

You still want it to be a diamond though. So you'd think we could just add shape=23 in there too... but no. This code below just gives you back the original plot. Basically, the second shape=23 call just overrides the aes(..) specification:

ggplot(df, aes(x, myValues)) + geom_point(aes(color=myThings)) + 
    geom_point(data=data.frame(x=50,myValues=2), aes(shape='Mean'), shape=23, size=3)

If you want to specify the actual value that aes() assigns to "Mean", you need to specify that with scale_shape_manual . Something like this:

ggplot(df, aes(x, myValues)) + geom_point(aes(color=myThings)) + 
    geom_point(data=data.frame(x=50,myValues=2), aes(shape='Mean'), size=3) + 
    scale_shape_manual(values=23)

在此处输入图像描述

That should help you add the diamond for "Mean". As for your other points, just specify with aesthetic in a similar way and it will appear as a legend. You can use labs(shape=...) to specify the title of the legend to something other than "shape".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM