ADBlock is blocking some content on the site

ADBlock errore
  •   r
  •  | 
  •  | 
  •   ( words)


Is there a way to put a .png in a grid. I wanted to display 4 .png single charts in one, using grid.

enter image description here

No correct solution


As others have said it's probably not a great idea, but


img <- rasterGrob(readPNG(system.file("img", "Rlogo.png", package="png")),
width=unit(1,"npc"), height=unit(1,"npc"))

grid.arrange(img, img, img, img, ncol=2)

will display 2x2 png files on a device.

There are at least three ways to do this in base graphics.

  1. Use layout() (which is my favourite):

    layout(matrix(1:4, ncol = 2))
    for(i in 1:4)
    layout() # reset

    With layout() you pass in a matrix that contains integers which index the sub-plots that the device has been split into. How these indexes are arranged in the matrix controls the layout. The 2x2 layout is given by this matrix

    R> matrix(1:4, ncol = 2)
         [,1] [,2]
    [1,]    1    3
    [2,]    2    4

    Note that fills by columns. To fill by rows, use byrow = TRUE in the matrix() call

    R> matrix(1:4, ncol = 2, byrow = TRUE)
         [,1] [,2]
    [1,]    1    2
    [2,]    3    4

    A more complex layout that the 2x2 one can be achieved by creating the indexes in the matrix as you want the device to look. For example, for a device with 3 rows, with first row containing 1 plot region on right of the device, the second row with a single plot region covering the whole row and on the third row 2 plot regions, we would do this

             3,4), ncol = 2, byrow = TRUE)

    Filling that with plots gives

                    3,4), ncol = 2, byrow = TRUE))
    for(i in 1:4)
    layout(1) # reset

    enter image description here

    Similar layouts can be achieved with split.screen(). See 3 below.

  2. Use the mfrow or mfcol parameters. The former fills the device with plots by rows and the latter by columns

    op <- par(mfrow = c(2,2))
    for(i in 1:4)
    par(op)  # reset
  3. A third way is to use split.screen()

    for(i in 1:4) {
    close.screen(all = TRUE) # reset

    split.screen() can also take a matrix input, like layout().

Depending on how many plot regions you split the device into, you may need or want to shrink margins of the plots. For that see ?par and the various ways in which the margins can be defined (e.g. parameter mar).

To get these as a PNG file, wrap all commands in

png(file = "foo.png", .....) ## the ..... is where you place options, see ?png

## plotting commands here



png("layout.png", height = 600, width = 600, pointsize = 14)
                3,4), ncol = 2, byrow = TRUE))
for(i in 1:4)
layout(1) # reset

[which is what I used to create the plot figure I showed above.]

If you are familiar with ggplot, facet_grid() might be what you are looking for:

df <- data.frame( x = rnorm(40), y = rnorm(40) )
df <- cbind( df, expand.grid( c('A', 'B'), c('C', 'D' ) )  )
head( df )

            x          y Var1 Var2
1 -1.27990165  1.1697183    A    C
2 -0.65083905  0.4743215    B    C
3  0.23181562  0.5092162    A    D
4 -0.01370950 -0.1704988    B    D
5 -1.20182791 -0.3525845    A    C
6  0.04877524  0.8801793    B    C

library( "ggplot2" )
g <- ggplot( df ) +
  geom_point( aes(x = x, y = y) ) +
  facet_grid( Var1 ~ Var2 )
ggsave( "plot.png", g )

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow