0

I have the following code that has created two violin plots:

ggplot(both,aes(x=levelsname,y=loginc,fill=levelsname))+
geom_violin() +
  stat_summary(fun.y = mean,
               aes(shape="Mean"),
               colour='black',
               geom="point",
               size=3)+
    scale_shape_manual("Summary Statistics", values=c("Mean"="+"))+  
  scale_fill_manual(values=c('gray70','orange','red'))+
  scale_x_discrete(name="Site Category")+
  scale_y_continuous(name = "Log(Incidence/100,000")+
  guides(fill=guide_legend(title = "Site Category"))+
  facet_grid(~ANA)+
  theme_classic()+
  theme(axis.text.x=element_blank())

Violin plot

Everything is correct for these plots apart from the legend. I am attempting to remove the black circles from the legend under site category and replace them with the + symbol. I also would like to move the + and mean legend symbol underneath the site category legend items, such that it looks like one legend.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
geoscience123
  • 164
  • 1
  • 11
  • Add `show.legend = FALSE` to the stat call – camille Mar 12 '20 at 17:09
  • Likely a dupe. [Remove legend ggplot 2.2](https://stackoverflow.com/questions/35618260/remove-legend-ggplot-2-2) – tjebo Mar 12 '20 at 17:30
  • @camille Adding show.legend=FALSE removes the circle inside the site category legend, but also removes the Mean from the legend. – geoscience123 Mar 12 '20 at 17:43
  • Oh, got it. You can use `override.aes` for a specific legend type, in this case the fill legend. Seems like [this](https://stackoverflow.com/q/11417517/5325862) post should have you covered, and [this](https://stackoverflow.com/q/29941900/5325862) one might help as well – camille Mar 12 '20 at 18:01
  • @Tjebo they don't want to remove any entire legends, which is what that post is about – camille Mar 12 '20 at 18:02
  • @camille fair. Was just a two second google because this is most likely a dupe. may not be the best choice though – tjebo Mar 12 '20 at 18:36

1 Answers1

0

You shouldn't have shape="Mean" within the aes call. It is not an aesthetic mapping! Having it in the aes makes ggplot think you are setting shape to be mapped to a character variable that always takes the value "mean". Hence the weird legend.

You can just use shape="+" as an argument in the stat_summary call to get the effect you want. You'll probably have to take out the scale_shape_manual("Summary Statistics", values=c("Mean"="+")) line as well, because there is no longer a shape scale.

To answer the last part of your question, if you want to have a separate "mean" line for your legend you can add an extra level "Mean" to the variable mapped to the fill aesthetic (then manually set its fill to transparent). See below:

d <- data.frame(x=factor(c(1,2)), y=rnorm(100))

ggplot(d, aes(x,y, group=x, fill=x)) + 
   geom_violin() + 
   stat_summary(shape="+", fun="mean", aes(fill="Mean"), geom="point", size=3) +
   scale_fill_manual(values=c("blue", "red", "#00000000"), limits=c(1,2,"Mean"))

enter image description here

Edit: I found a way to get rid of the box around the + in the Mean line of the legend but it's a horrible hack. You need two stat_summary layers, one with color set to transparent with an aesthetic mapping (so that the legend box is transparent, but this makes the legend "+" transparent also) and then second with color="black" directly which replaces the "+" in the legend but not the box.

ggplot(d, aes(x,y, group=x, fill=x, color=x)) + 
   geom_violin() + 
   stat_summary(shape="+", fun="mean", aes(fill="Mean",color="Mean"), geom="point", size=3)+
   stat_summary(shape="+", fun="mean",color="black", geom="point", size=3) +
   theme_classic() + 
   scale_fill_manual(values=c("lightblue", "red", "#00000000"), limits=c(1,2,"Mean"))+  
   scale_color_manual(values=c("black", "black", "#00000000"), limits=c(1,2,"Mean"))

enter image description here

George Savva
  • 4,152
  • 1
  • 7
  • 21
  • 1
    This seems to work, the only problem I am having is that my legend is automatically ordered alphabetically, causing "Mean" to be put in the center of my legend and throwing off the color scales. – geoscience123 Mar 13 '20 at 15:44
  • @coconn41 apologies I didn't think of that.. you'll have to set the order levels in the `scale_fill_manual` layer. I will update my answer.. – George Savva Mar 13 '20 at 15:56
  • @coconn41 I have edited, if Mean isn't alphabetically last then you need to set the order of the levels in the `limits()` option for each scale. – George Savva Mar 13 '20 at 15:59