failed to left-align plots

35 views
Skip to first unread message

hoon

unread,
Oct 2, 2015, 6:25:51 AM10/2/15
to ggplot2
Hello,
I tried to left-align two plots, one of which is a facet by using the scripts below, but I keep failing.
Would you please help me to understand what is wrong with my script below?

thank you in advance,

Hoon

-----------------------------------------------

rm(list=ls())

library(ggplot2)
library(grid)
library(gridExtra)

p1 <- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
  geom_line() +
  ggtitle("Growth curve for individual chicks")

p2 <- ggplot(subset(ChickWeight, Time==21), aes(x=weight, fill=Diet)) +
  geom_histogram(colour="black", binwidth=50) +
  facet_grid(Diet ~ .) +
  ggtitle("Final weight, by diet") +
  theme(legend.position="none")

gp1 <-ggplotGrob(p1)
gp2 <-ggplotGrob(p2)

# This works, but with left-aligned
grid.newpage()
grid.arrange(gp1, gp2)


# I tried to left-align by using the following codes, but it doesn't work.
maxWidth = unit.pmax(gp1$widths[2:3], 
                     gp2$widths[2:3])

gp1$widths[2:3] <- maxWidth
gp2$widths[2:3] <- maxWidth

grid.newpage()
grid.arrange(gp1, gp2)


----------------------------------------------------
sessionInfo()
R version 3.2.2 (2015-08-14)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] gridExtra_0.9      ggplot2_1.0.1.9003

loaded via a namespace (and not attached):
 [1] labeling_0.3     colorspace_1.2-6 scales_0.3.0     magrittr_1.5     plyr_1.8.3       tools_3.2.2      gtable_0.1.2    
 [8] reshape2_1.4.1   Rcpp_0.12.1      stringi_0.5-5    stringr_1.0.0    digest_0.6.8     munsell_0.4.2   


Dennis Murphy

unread,
Oct 2, 2015, 4:22:30 PM10/2/15
to hoon, ggplot2
Hi:

The major problem with your approach is that you didn't realize the impact of the legend in your first plot on the alignment. The easy way out would be to reposition the legend so that it was either inside the plot region, on top or on the bottom before you applied the gtable magic. If you do that, then the remainder of what you tried should work.

Another approach, which might be more visually appealing in some cases, is to extract the legend from the first plot and reposition it on the graphics page. The following is an adaptation of an exchange between Brian Zen and me in this forum about 10 days ago (thread title: move_facet_strip_y). Brian's use case was to align two concurrent time series of different variables stacked on top of one another. My response showed how this could be done somewhat more generally (and pedantically) and that's what I'll show here. The packages grid, gridExtra and ggplot2 need to be loaded. Given your plot objects p1 and p2:


Step 1: Extract the legend from the first plot.
Step 2: Redo the first plot with the legend removed - call it p1a.
Step 3: Create gtables of p1a and p2
Step 4: Edit the gtable objects to align the left margins of the plot regions.
Step 5: Create a layout matrix to position the grobs.
Step 6: Render the graphic using grid.arrange().

To extract the legend, we'll use the following function from 

# ----------------
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]]
    legend
}

# Extract the legend from p1
leg <- g_legend(p1)

# Redo p1 without the legend
p1a <- p1 + theme(legend.position = "none")

# Create gtable objects of p1a and p2
gp1 <- ggplot_gtable(ggplot_build(p1a))
gp2 <- ggplot_gtable(ggplot_build(p2))

# Edit the left margins of the two gtable objects
# in order to align them
maxwidth <- grid::unit.pmax(gp1$widths[2:3], gp2$widths[2:3])
gp1$widths[2:3] <- as.list(maxwidth)
gp2$widths[2:3] <- as.list(maxwidth)

# Create a layout matrix for positioning the grobs
# This one uses 80% of each row for the plot, 20% for the margin
lay <- rbind(c(1, 1, 1, 1, 3), c(2, 2, 2, 2, 3))

# Render the plot
grid.arrange(gp1, gp2, leg,  layout_matrix = lay)

#--------------

Side comment: Please don't post code like this: 'rm(list=ls())'. At the very least, comment it out. Imagine you were trying to help someone in the middle of an extensive R session and you didn't notice this line in a code block you copied and pasted into your session. How would you feel if your entire global environment were wiped out this way? I've seen several folks on R-help who were victimized by this practice over the years and I can assure you they were not thrilled.

Dennis

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages