Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent resizing of fonts, plot objects etc. in R?

Tags:

plot

r

I want to have multiple plots in the same image, and I want to have a different number of plots depending on image. To be precise, I first create a 1x2 matrix of plots, and then a 3x2 matrix of plots. I want to use the same basic settings for these two images - the same font sizes especially, since this is for a paper and the font size has to be at least 6 pt for a plot.

In order to achieve this, I wrote the following code for R:

filename = "test.png"
font.pt = 6    # font size in pts (1/72 inches)
total.w = 3    # total width in inches
plot.ar = 4/3  # aspect ratio for single plot
mat.col = 2    # number of columns
mat.row = 1    # number of rows
dpi = 300

plot.mar = c(3, 3, 1, 2) + 0.1
plot.mgp = c(2, 1, 0)
plot.w = total.w / mat.col - 0.2 * plot.mar[2] - 0.2 * plot.mar[4]
plot.h = plot.w / plot.ar
total.h = (plot.h + 0.2 * plot.mar[1] + 0.2 * plot.mar[3]) * mat.row

png(filename, width = total.w, height = total.h, res = dpi * 12 / font.pt, units = "in")

par(mfrow = c(mat.row, mat.col), mai = 0.2 * plot.mar, mgp = plot.mgp)

plot(1, 1, axes = T, typ = 'p', pch = 20, xlab = "Y Test", ylab = "X Test")

dev.off()

As you can see, I set a total width of 3 inches and then calculate the total height for my image, so that the aspect ratio of the plots is correct. The font size only changes the resolution by a factor. Anyway, the problem is now that the font size changes significantly when I go from mat.row = 1 to mat.row = 3. Other things change as well, for example the labelling of the axes and the margins, even though I specifically set those before in inches. Have a look:

When 3 rows are set (cropped image):

3 rows

When only 1 row is set (cropped image):

1 row

How can I prevent this? As far as I can see, I did everything I could. This took me quite a while, so I'd like to get this to work instead of switching to gglplot and learning everything from scratch again. It's also small enough that I really hope I'm just missing something very obvious.

like image 698
PoorYorick Avatar asked Jan 02 '17 18:01

PoorYorick


1 Answers

In ?par we can find:

In a layout with exactly two rows and columns the base value of "cex" is reduced by a factor of 0.83: if there are three or more of either rows or columns, the reduction factor is 0.66.

Therefore, when you change mfrow values from (2, 1) to (2, 3) the cex value changes from 0.83 to 0.66. cex affects font size and text line height.

So, you can manually specify cex value for your plots.

par(mfrow = c(mat.row, mat.col), mai = 0.2 * plot.mar, mgp = plot.mgp, cex = 1)

Hope, it is what you need.

Plot for mat.row = 1 (cropped): mat.row = 1 (cropped) And plot for mat.row = 3 (cropped): mat.row = 3 (cropped)

like image 145
Istrel Avatar answered Nov 06 '22 02:11

Istrel