10

I have some datasets that contain more legend entries than can comfortably be distinguished with colors or at all displayed with symbols. It's effectively a rainbow, but across so many legend entries that they make the plots much higher than wide.

Since the legends are not really as important as comfortable sizing of the plot, I merely preview and remove them before saving the plots to PNGs.

Like this:

library(ggplot2)
p <- ggplot(diamonds, aes(cut, depth)) + geom_point(aes(colour = factor(carat), size = price))
p
p <- p + theme(legend.position = "none")
p

However, having only the choice of either skewing the plot height or kicking the legend out completely, is a bit frustrating. A neat compromise would be to have the legend in a separate PNG, so it can be checked when really necessary. Is there a way to do this?

Katrin Leinweber
  • 1,316
  • 13
  • 33
  • http://stackoverflow.com/a/13650878/1412059 – Roland Jan 08 '15 at 15:40
  • Though, you should probably consider a different plot. More than 8 to 10 different colours can't be distinguished well anyway, so what is the sense in having so many discrete colors in a plot? – Roland Jan 08 '15 at 15:44
  • Please find [an example with real data here](http://www.konscience.de/uber-uns/#flattr-auswertung). The scatterplot would not look very good in monochrome IMHO. Moving the legend would move the problem as well, and/or require some additional code for sizing the plots relative to the number of legend items. I haven't tried facetting, but I'm guessing it would result in each plot being too small to be useful. Exporting the legend as a separate file would IMHO be best, if that is possible at all. – Katrin Leinweber Jan 08 '15 at 15:53
  • I'm not saying you shouldn't use colors at all. I'm just saying you should limit yourself to about eight colors (and use colorbrewer2.org to chose them). I'm not going to design a better plot for you (you could ask at stats.stackexchange.com), but your color categories cannot be distinguished well. However, if you just need the colors to have a colorful plot ... – Roland Jan 08 '15 at 16:01
  • I did not mean to imply that I was asking for someone to "design a better plot" :-O My apologies if it came across as such. – Katrin Leinweber Jan 08 '15 at 17:04

2 Answers2

6
library(ggplot2)
p <- ggplot(diamonds, aes(cut, depth)) + geom_point(aes(colour = factor(carat), size = price))

#extract legend
#https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend <- function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)
}

mylegend <- g_legend(p)
library(grid)
grid.draw(mylegend)

Just plot to different devices.

Roland
  • 127,288
  • 10
  • 191
  • 288
  • OK, thanks! This solves the main part of my problem. I am however stuck at exporting this legend object to a file. RStudio cuts it off at the limit of it's Plots tab. `png()` seems to require dimensions again, which I'd rather have determined automatically, like by `ggsave()`. – Katrin Leinweber Jan 09 '15 at 10:38
  • `ggsave` uses default values as does `png`. You should probably set the `nrow` parameter in `guide_legend`: http://docs.ggplot2.org/0.9.3.1/guide_legend.html – Roland Jan 09 '15 at 10:47
  • The legend entries tend to be several words long, so pushing the items into several columns would also transpose the dimension problem. I guess I'll bite the sour apple and leave the legend in the plot, and add some code to calculate its size via the number of entries. Nonetheless, thanks for your time :-) – Katrin Leinweber Jan 09 '15 at 17:49
6

This is possible with cowplot and ggpubr.

library(cowplot)
my_legend <- get_legend(your_ggplot_object)
library(ggpubr)
as_ggplot(my_legend)
derelict
  • 3,657
  • 3
  • 24
  • 29