1

I have an issue with creating a legend for a histogram. I want to make a grid of histograms with a common legend. I have two issues.

  1. Each histogram has a geom-vline showing a mean while the histogram shows all values. I want to make a legend which shows the colour of the geom_vline and the default grey fill of the histogram. I do not seem to be able to do this as to make a legend for fill you seem to need to have histograms split by a factor. Nor can I make a legend for the histogram using scale_colour_manual(). Similarly, I can't make a legend for the vline using scale_fill_manual()

  2. I want to be able to centre the legend under the arranged histograms.

below is the code and the output showing my histograms adapted for the iris dataset

library(ggplot2)
library(mosaic)
library(grid)
library(gridExtra)
data("iris")

    setosaHistogram <-ggplot(data=iris)+geom_histogram(mapping=aes(x=Petal.Length,color='Petal Histogram'))+xlab('Petal Length') +
      theme(plot.title = element_text(size = 10, face = "bold",hjust = 0.5),legend.position="none") +
      ggtitle(paste("Setosa"))+
      geom_vline(aes(xintercept = mean(iris[iris$Species=='setosa','Petal.Length']), color = "Species Mean"),linetype=2)+ 
      scale_fill_manual(name = 'Legend',values=C("Petal Histogram"='grey','Species Mean' ="red"))

    versicolorHistogram <-ggplot(data=iris)+geom_histogram(mapping=aes(x=Petal.Length,color='Petal Histogram'))+xlab('Petal Length') +
      theme(plot.title = element_text(size = 10, face = "bold",hjust = 0.5),legend.position="none") +
      ggtitle(paste("Versicolor"))+
      geom_vline(aes(xintercept = mean(iris[iris$Species=='versicolor','Petal.Length']), color = "Species Mean"),linetype=2)+ 
      scale_fill_manual(name = 'Legend',values=C("Petal Histogram"='grey','Species Mean' ="red"))

    virginicaHistogram <-ggplot(data=iris)+geom_histogram(mapping=aes(x=Petal.Length,color='Petal Histogram'))+xlab('Petal Length') +
      theme(plot.title = element_text(size = 10, face = "bold",hjust = 0.5),legend.position="none") +
      ggtitle(paste("Virginica"))+
      geom_vline(aes(xintercept = mean(iris[iris$Species=='virginica','Petal.Length']), color = "Species Mean"),linetype=2)+ 
      scale_fill_manual(name = 'Legend',values=C("Petal Histogram"='grey','Species Mean' ="red"))

    g <- ggplotGrob(setosaHistogram + 
                      theme(legend.position = 'bottom'))$grobs
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]

    arrangedPlots<-grid.arrange(setosaHistogram,versicolorHistogram,virginicaHistogram,legend,ncol=3, nrow=2)

enter image description here

Daniel Wigmore
  • 87
  • 1
  • 1
  • 9
  • 1
    Could you make your problem reproducible by sharing a sample of your data so others can help (please do not use `str()`, `head()` or screenshot)? You can use the [`reprex`](https://reprex.tidyverse.org/articles/articles/magic-reprex.html) and [`datapasta`](https://cran.r-project.org/web/packages/datapasta/vignettes/how-to-datapasta.html) packages to assist you with that. See also [Help me Help you](https://speakerdeck.com/jennybc/reprex-help-me-help-you?slide=5) & [How to make a great R reproducible example?](https://stackoverflow.com/q/5963269) – Tung Feb 22 '19 at 19:00
  • to center the legend I would look into the `layout_matrix` of `grid.arrange` (also in `arrange.grob`) – Mike Feb 22 '19 at 19:17
  • `plot_grid` from the cowplot package is another option. It also has the function `get_legend`, which extracts the legend for you. – Z.Lin Feb 23 '19 at 03:32
  • Hello L.Zin, I apologise for using local data. I have redone it using the iris dataset, please see the reprex below – Daniel Wigmore Feb 23 '19 at 12:42
  • The question has been edited to show the reprex with reproducible data. Thank you for the advice so far – Daniel Wigmore Feb 23 '19 at 12:50

0 Answers0