0

I was wondering if there is a way to have a common legend and at the same time identical plot widths for a multi-panel plot. I know how to get identical plot widths without a legend, or with a legend that is not vertically centered.

Here's Hadley's fix that I use for the common legend (https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs):

library(ggplot2)
library(gridExtra)
dsamp <- diamonds[sample(nrow(diamonds), 1000), ] 

p1 <- qplot(carat, price, data=dsamp, colour=clarity)
p2 <- qplot(carat, price, data=dsamp, colour=clarity, geom="path")

g_legend<-function(p){
tmp <- ggplotGrob(p)
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}

legend <- g_legend(p1)
lwidth <- sum(legend$width)

## using grid.arrange for convenience
## could also manually push viewports
grid.arrange(arrangeGrob(p1 + theme(legend.position="none"),
                                    p2 + theme(legend.position="none"),
                                    main ="this is a title",
                                    left = "This is my global Y-axis title"), legend, 
                 widths=unit.c(unit(1, "npc") - lwidth, lwidth), nrow=1)

To illustrate my point, I changed p2 by adding two other variables of the same dataset keeping clarity as the common legend:

p1 <- qplot(carat, price, data=dsamp, colour=clarity)
p2 <- qplot(depth, table, data=dsamp, colour=clarity, geom="path")

g_legend<-function(p){
tmp <- ggplotGrob(p)
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}

legend <- g_legend(p1)
lwidth <- sum(legend$width)

## using grid.arrange for convenience
## could also manually push viewports
grid.arrange(arrangeGrob(p1 + theme(legend.position="none"),
                                    p2 + theme(legend.position="none"),
                                    main ="this is a title",
                                    left = "This is my global Y-axis title"), legend, 
                 widths=unit.c(unit(1, "npc") - lwidth, lwidth), nrow=1)

This may not make sense in this example, but I have four different measurements on the same experimental units, which I want to graphically display in 2 plots with same plot widths and a common vertically centered legend.

Stefan
  • 727
  • 1
  • 9
  • 24
Stefan
  • 1
  • 2

1 Answers1

0

I think you can achieve your goal better with faceting:

ggplot(dsamp, aes(x = carat, y = price, colour = clarity)) +
  geom_point(data = cbind(dsamp, group = 1)) +
  geom_path(data = cbind(dsamp, group = 2)) +
  facet_grid(group ~ .) +
  theme(strip.text.y = element_blank(),
        strip.background = element_blank()) +
  ggtitle("this is a title")

enter image description here

I've assumed that you have identical variables in your plots as in your example. Otherwise, I've had to use a lot of tinkering when I needed to align plots myself: See scatterplot with alpha transparent histograms in R for an example.

Community
  • 1
  • 1
Roland
  • 127,288
  • 10
  • 191
  • 288
  • No I don't have identical variables so this won't work. I edited my post above to give more detail. Thanks for the link though! – Stefan Nov 30 '14 at 16:20