Side by side graph of ggplot2

I want to use ggplot2 package Place two graphs side by side, that is, make the equivalent term of par(mfrow=c(1,2)).

For example, I want the following two figures to show side by side at the same scale.

x <- rnorm(100)
eps <- rnorm(100,0,.2)

Do I need to put them in the same data.frame?

qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()

#1 building

Yes, you need to arrange the data appropriately. One way is to:

X <- data.frame(x=rep(x,2),
                y=c(3*x+eps, 2*x+eps),
                case=rep(c("first","second"), each=100))

qplot(x, y, data=X, facets = . ~ case) + geom_smooth()

I'm sure there will be better techniques for plyr or reshaping - I still haven't really mastered all of Hadley's powerful features.

#2 building

Using reshape packaging, you can do the following.

wide <- data.frame(x = rnorm(100), eps = rnorm(100, 0, .2))
wide$first <- with(wide, 3 * x + eps)
wide$second <- with(wide, 2 * x + eps)
long <- melt(wide, id.vars = c("x", "eps"))
ggplot(long, aes(x = x, y = value)) + geom_smooth() + geom_point() + facet_grid(.~ variable)

#3 building

Update: the answer is very old. Now we recommend gridextra:: grid. Array(). If it can be useful, I'll leave it here.

blog (see post for application instructions) Stephen Turner arrange() Stephen Turner Arrange() posted the arrange() function on the blog (see post for application instructions)

vp.layout <- function(x, y) viewport(layout.pos.row=x, layout.pos.col=y)
arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE) {
 dots <- list(...)
 n <- length(dots)
 if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)}
 if(is.null(nrow)) { nrow = ceiling(n/ncol)}
 if(is.null(ncol)) { ncol = ceiling(n/nrow)}
        ## NOTE see n2mfrow in grDevices for possible alternative
pushViewport(viewport(layout=grid.layout(nrow,ncol) ) )
 ii.p <- 1
 for(ii.row in seq(1, nrow)){
 ii.table.row <- ii.row 
 if(as.table) {ii.table.row <- nrow - ii.table.row + 1}
  for(ii.col in seq(1, ncol)){
   ii.table <- ii.p
   if(ii.p > n) break
   print(dots[[ii.table]], vp=vp.layout(ii.table.row, ii.col))
   ii.p <- ii.p + 1

#4 building

One disadvantage of grid. Array based solutions is that, as most journals require, they make it difficult to mark charts with letters (A, B, etc.).

I wrote. cowplot Package to solve this (and other) problem, especially the function plot_grid():


iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot() + theme_bw()

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) + theme_bw() +
  theme(legend.position = c(0.8, 0.8))

plot_grid(iris1, iris2, labels = "AUTO")

The object returned by plot_grid() is another ggplot2 object, which you can save with ggsave() as usual:

p <- plot_grid(iris1, iris2, labels = "AUTO")
ggsave("plot.pdf", p)

In addition, you can also use the cowplot function save ﹣ plot(), which is about a thin package ggsave(), which can easily get combined parcels, such as the correct size:

p <- plot_grid(iris1, iris2, labels = "AUTO")
save_plot("plot.pdf", p, ncol = 2)

(the save plot() ncol = 2 parameter tells save plot() that there are two graphs side by side, and save plot() makes the saved image twice as wide.)

For a more in-depth description of how to lay out a diagram in a grid, see this Illustration. There is also a small illustration of how to use Shared legend Draw up .

A common source of confusion is that the Cowplot package changes the default ggplot2 theme. This package has this capability because it was originally written for internal lab use and we never use the default theme. If this causes problems, you can solve them in one of three ways:

1. Manually set the theme for each figure. I think it's a good habit to always assign a specific theme to each plot, just like I used + theme_bw() in the above example. If you specify a specific topic, the default topic does not matter.

2. Restore the default theme to ggplot2. You can do this with a single line of code:


3. Call the cowplot function without wrapping. You can't call library(cowplot) or require(cowplot), but you can call the cowplot function by adding cowplot:: before cowplot::. For example, the example above that uses the default theme of ggplot2 will change to:

## Commented out, we don't call this
# library(cowplot)

iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) +
  theme(legend.position = c(0.8, 0.8))

cowplot::plot_grid(iris1, iris2, labels = "AUTO")

To update:

  • Starting with cowplot 1.0, the default ggplot2 theme is no longer changed.
  • Starting with ggplot2 3.0.0, you can tag the graph directly. See Here.

#5 building

Any ggplots side by side (or n graphs on the grid)

gridExtra The function grid.arrange() in the package merges multiple graphs; that's how you place the two side by side.

plot1 <- qplot(1)
plot2 <- qplot(1)
grid.arrange(plot1, plot2, ncol=2)

This is useful when both graphs are not based on the same data, for example, if you want to draw different variables without using reshape().

This draws the output as a side effect. To print side effects to a file, specify a device driver (for example, pdf, png, etc.), for example

grid.arrange(plot1, plot2)

Or, use arrangeGrob() with ggsave(),

ggsave("foo.pdf", arrangeGrob(plot1, plot2))

This is equivalent to drawing two different graphs using par(mfrow = c(1,2)). This not only saves time in sorting out data, but also is necessary when two different graphs are needed.

Appendix: use of facets

Facets help to draw similar graphs for different groups. This is indicated in many of the answers below, but I want to highlight this approach with an example equivalent to the chart above.

mydata <- data.frame(myGroup = c('a', 'b'), myX = c(1,1))

qplot(data = mydata, 
    x = myX, 
    facets = ~myGroup)

ggplot(data = mydata) + 
    geom_bar(aes(myX)) + 

Update information

The plot grid function cowplot It is worth checking as an alternative to grid. Array. See @ Claus Wilke's Answer and This illustration For an equivalent method; however, this function can be This small illustration Better control of drawing location and size.

Posted on Fri, 20 Mar 2020 01:54:34 -0700 by besly98