9

I am arranging plots generated by ggplot2. I have to use print to print out plots and grid.draw to display legend.

Sample Code:

p0 <- ggplot(data = iris, geom = 'blank',
         aes(y = Petal.Width, x = Petal.Length, color = Species)) + geom_point() +
      theme(axis.title.x = element_blank(),
            axis.title.y = element_blank(),
            legend.position = "none")

p1 <- ggplot(data = iris, geom = 'blank',
         aes(y = Petal.Length, x = Petal.Width, color = Species)) + geom_point() +
       theme(axis.title.x = element_blank(),
             axis.title.y = element_blank(),
             legend.position = "none")

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)
}

p <- ggplot(data = iris, geom = 'blank',
        aes(y = Petal.Width, x = Petal.Length, color = Species)) + geom_point()


grid.newpage() 
pushViewport(viewport(layout = grid.layout(2, 4)))
print(p0,vp = viewport(layout.pos.row = 1, layout.pos.col = 1))
print(p0,vp = viewport(layout.pos.row = 1, layout.pos.col = 2:3))
print(p1,vp = viewport(layout.pos.row = 2, layout.pos.col = 2:3))
grid.text("This is x label",gp=gpar(fontsize = 14), vjust = 11,
          vp = viewport(layout.pos.row = 2, layout.pos.col = 2))
grid.text("This is y label",gp=gpar(fontsize = 14), vjust = -11, rot = 90,
          ![enter image description here][1]vp = viewport(layout.pos.row = 2, layout.pos.col = 2))

grid.draw(g_legend(p))

I would like to put the legend at the fourth column. How can I do it? Thanks.

baptiste
  • 75,767
  • 19
  • 198
  • 294
Autumn
  • 575
  • 1
  • 9
  • 20

3 Answers3

9

enter image description hereusing gridExtra

         library(gridExtra)
         grid.arrange(p0 , p1,  g_legend(p), ncol=3,
         heights=c(10, 1),widths =c(1,2,1) ,as.table =TRUE)
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • Thanks. Is there away to stick to pushviewpoint? I am arranging multiple plots and I need to set the length and position for each one, and also need to use grid.text to add text to the plot. – Autumn Dec 05 '12 at 15:05
  • you are not ok with this answer ? if is the case validate it before and then it is better to ask a new question where you detail you request( many plots, gtext,..) – agstudy Dec 05 '12 at 15:07
  • I edited the sample code and plot. Could you help me with it? – Autumn Dec 05 '12 at 15:12
  • As I said, "I have to use print to print out plots and grid.draw to display legend." I just have to stick to print. I know grid.arrange, it does not work. That's why I have this question – Autumn Dec 05 '12 at 15:47
  • @Lin Your original question was answered by `agstudy`. Please don't edit your question to ask a new, different question. If your new question still remains, then ask a new question. And mark this answer as the accepted, correct answer. – Andrie Dec 05 '12 at 15:59
  • @Andrie Thanks. agstudy's answer works but ignored the "print" function. I mentioned to use "print" function in the very first beginning of my question. – Autumn Dec 05 '12 at 16:30
  • @agstudy I am a newbie and do not know the rules. hope you explained to me with patience. thanks. – Autumn Dec 05 '12 at 16:32
5

You can manually change the x and y coordinates in the TableGrob object. For example, you could do the following to position the legend in the center of the plot:

leg <- g_legend(p)
leg$vp$x <- unit(.5, 'npc')
leg$vp$y <- unit(.5, 'npc')

When you call grid.draw(leg), it will be positioned in the center. Use different values to put it wherever you like.

arvi1000
  • 9,393
  • 2
  • 42
  • 52
pmetzner
  • 95
  • 1
  • 2
  • 1
    I think you meant: leg$vp$x <- unit(.5, 'npc') leg$vp$y <- unit(.5, 'npc') and then as you said, grid.draw(leg) – maia Mar 12 '15 at 17:22
2

In grid, the idea would be to push a viewport where you want to draw,

pushViewport(viewport(layout.pos.row = 2, layout.pos.col = 4))
grid.draw(g_legend(p))

or, alternatively, assign the viewport to the legend grob,

leg = g_legend(p)
leg$vp = viewport(layout.pos.row = 2, layout.pos.col = 4)
grid.draw(leg)
baptiste
  • 75,767
  • 19
  • 198
  • 294