1
votes

I want to produce two figures using base R, both showing barplots. The first figure should contain two bar plots and the second figure should contain four bar plots.

I used par(mfrow = c(...)) to arrange multiple bar plots in one figure. I don't have trouble to produce the figures themselves, but when I save the figures bar widths and tick labels are different in size.

To my understanding, when I produce the second figure with four bar plots and chose double the width of the first figure when exporting, bars and labels should be displayed with the same size in the file. However, the labels are much smaller and the bars have a different width in the second figure. Can anyone tell me why?

Here a simple example:

png(filename="plot1.png", width=200, height=300, bg="white")
par(mfrow = c(1, 2), mar = c(1, 2, 1, 1), oma = c(0, 0, 0, 0))

barplot(height = c(2,3), width = 1, xlim = c(0,2))
barplot(height = c(2,3), width = 1, xlim = c(0,2))
dev.off()

png(filename="plot2.png", width=400, height=300, bg="white")
par(mfrow = c(1, 4), mar = c(1, 2, 1, 1), oma = c(0, 0, 0, 0))

barplot(height = c(2,3), width = 1, xlim = c(0,2))
barplot(height = c(2,3), width = 1, xlim = c(0,2))
barplot(height = c(2,3), width = 1, xlim = c(0,2))
barplot(height = c(2,3), width = 1, xlim = c(0,2))
dev.off()

Plot 1:

Figure 1

Plot 2:

Figure 2

1
Unfortunately not. Even when I use the code to export the plots as suggested in this answer, my problems of unequal bar widths and tick labels remains. I edited my question to make it more clear.Vincent H.

1 Answers

0
votes

Probably par and pdf(width, height) should be equal.

png(filename="plot1.png", width=400, height=300, bg="white")
par(mfrow=c(1, 4), mar=c(1, 2, 1, 1), oma=c(0, 0, 0, 0))
replicate(2, barplot(height=c(2,3), width=1, xlim=c(0,2)))
dev.off()

png(filename="plot2.png", width=400, height=300, bg="white")
par(mfrow=c(1, 4), mar=c(1, 2, 1, 1), oma=c(0, 0, 0, 0))
replicate(4, barplot(height=c(2,3), width=1, xlim=c(0,2)))
dev.off()

Another solution is to use layout.

def.par <- par(no.readonly=TRUE) # save par default, for resetting...

# 1 x 2 plot
layout(matrix(c(1:2, 0, 0), nrow=1, ncol=4, byrow=TRUE))
layout.show(n=2)  # to inspect layout                        # MARK
replicate(2, barplot(height=c(2,3), width=1, xlim=c(0,2)))

# 1 x 4 plot
layout(matrix(c(1:4), nrow=1, ncol=4, byrow=TRUE))
layout.show(n=4)  # to inspect layout
replicate(4, barplot(height=c(2,3), width=1, xlim=c(0,2)))

# 2 x 4 plot
layout(matrix(c(1:2, 0, 0, 3:6), nrow=2, ncol=4, byrow=TRUE))
layout.show(n=6)  # to inspect layout
replicate(2, barplot(height=c(2,3), width=1, xlim=c(0,2)))
replicate(4, barplot(height=c(2,3), width=1, xlim=c(0,2)))

par(def.par)  # reset to default

However, both solutions bring a half empty plot 1, the reason can be seen in code above at # MARK.

We could use the magick package to "chop" the first plot to the desired content. First we create the *.pngs with the second method.

clr <- "#ED7C22"  # color

png(filename="plot1.png", width=400, height=300, bg="white")
layout(matrix(c(1:2, 0, 0), nrow=1, ncol=4, byrow=TRUE))
replicate(2, barplot(height=c(2,3), width=1, xlim=c(0,2), col=clr, border=0))
dev.off()

png(filename="plot2.png", width=400, height=300, bg="white")
layout(matrix(c(1:4), nrow=1, ncol=4, byrow=TRUE))
replicate(4, barplot(height=c(2,3), width=1, xlim=c(0,2), col=clr, border=0))
dev.off()

Now, using image_chop we trim plot1.png to it's left half.

library(magick)
(i <- image_read("plot1.png"))
i.chopped <- image_chop(i, "200x+200")  # says: trim by 200px at pos. 200

Finally, we export the chopped image.

image_write(i.chopped, path="plot1.ch.png", format="png")

Plot 1 ("chopped")

enter image description here

Plot 2

enter image description here