16
votes

For a final article submission I have been asked to update my figures so that they meet the following specifications:

  1. axis lines are 0.25 mm
  2. axis lines all around with ticks facing in
  3. data lines are 0.5 mm
  4. font is 10pt
  5. figures should be 80 or 169 mm wide
  6. must be 300 dpi

What I've tried:

library(ggplot2)
library(cowplot)
theme_set(theme_bw())

x <- rnorm(100)
mydata <- data.frame(x = x,
                     y = x^2 + runif(100),
                     z = rep(letters[1:4], 25))

p <- ggplot(data = mydata, aes(x, y)) + 
  geom_point(aes(color = z)) + 
  geom_smooth(color = 'black', se = FALSE, size = 0.5) +
  theme(text = element_text(family = 'Times', size = 10, color = 'black'),
        axis.ticks.length = unit(-0.1, 'cm'),
        axis.text.x = element_text(margin = margin(t = 4, unit = 'mm')),
        axis.text.y = element_text(margin = margin(r = 4, unit = 'mm')),
        panel.grid = element_blank(),
        axis.line = element_line(size = 0.25),
        legend.position = c(0.5, 0.75))

p
ggsave(plot = p, 
       filename = 'myplot.png', 
       width = 80, height = 50, dpi = 300, units = 'mm')

p2 <- cowplot::plot_grid(plotlist = list(p, p, p, p), nrow = 1)
ggsave(plot = p2,
       filename = 'mymultipleplot.png',
       width = 169, height = 50, dpi = 300, units = 'mm')

Which returns the following two plots:

enter image description here

enter image description here

I can figure out how to handle some of the issues here (e.g. legend positions), but am having difficulty with the following:

  1. How can I get ticks around top and right axes?
  2. How can I get the sizes correct ...
    • These look much bigger than 10 pt. (download them or open in new window to see unscaled version)
    • The sizes are not maintained in the two figures despite being specified in the theme (font, line).
    • I don't know how to confirm that the lines are the correct size (in points or mm)... does ggsave do its own scaling?

update For my present task I exported as svg files and edited them in Inkscape. It took a few hours but was easier than getting ggplot to contort to the specifications.

But, it would be helpful to know for the future how to do this programmatically within ggplot2.

1
For question 1 (How can I get ticks around top and right axes?), see the new sec.axis argument in scale_ in ggplot 2.2.0. Try e.g. ggplot(mpg, aes(displ, hwy)) + geom_point() + scale_x_continuous(sec.axis = dup_axis()) + scale_y_continuous(sec.axis = dup_axis()).Henrik
To me it looks like the axis labels "x" and "y" are just about right for 10 pt, and all other text is smaller. At a resolution of 300 dpi (ppi), 10 pt is 10 / 72 * 300 pixels or about 42 pixels.mvkorpel
You should be more specific about what you mean by the sizes not being maintained in the two figures. Line widths and font sizes appear to be the same in both figures.mvkorpel
Maybe this is of help: moc.online.uni-marburg.de/gitbooks/publicationQualityGraphics/… I wrote this a few years ago, so things may well have changed, but there may still be useful hints.TimSalabim

1 Answers

1
votes

Answer to question: 1) as Henrik told in comments:

For question 1 (How can I get ticks around top and right axes?), see the new sec.axis argument in scale_ in ggplot 2.2.0. Try e.g. ggplot(mpg, aes(displ, hwy)) + geom_point() + scale_x_continuous(sec.axis = dup_axis()) + scale_y_continuous(sec.axis = dup_axis())

2) the problem here is that you have the same resolution with different sizes. Since the height of the two figures is the same, you can fix this problem scaling the font size by hand multiplying the font-size with the ratio of the width: e.g.

theme(text = element_text(family = 'Times', size = 10*(80/169), color = 'black')

The whole code should look like this:

library(ggplot2)
library(cowplot)
theme_set(theme_bw())

x <- rnorm(100)
mydata <- data.frame(x = x,
                     y = x^2 + runif(100),
                     z = rep(letters[1:4], 25))

p1 <- ggplot(data = mydata, aes(x, y)) + 
  geom_point(aes(color = z)) + scale_x_continuous(sec.axis = dup_axis()) + 
  scale_y_continuous(sec.axis = dup_axis()) + 
  geom_smooth(color = 'black', se = FALSE, size = 0.5) +
  theme(text = element_text(family = 'Times', size = 10*(80/169), color = 'black'),
        axis.ticks.length = unit(-0.1, 'cm'),
        axis.text.x = element_text(margin = margin(t = 4, unit = 'mm')),


        axis.text.y = element_text(margin = margin(r = 4, unit = 'mm')),

        panel.grid = element_blank(),
        axis.line = element_line(size = 0.25),
        legend.position = c(0.5, 0.75))

p2 <- ggplot(data = mydata, aes(x, y)) + 
  geom_point(aes(color = z)) + scale_x_continuous(sec.axis = dup_axis()) + 
  scale_y_continuous(sec.axis = dup_axis()) + 
  geom_smooth(color = 'black', se = FALSE, size = 0.5) +
  theme(text = element_text(family = 'Times', size = 10, color = 'black'),
        axis.ticks.length = unit(-0.1, 'cm'),
        axis.text.x = element_text(margin = margin(t = 4, unit = 'mm')),


        axis.text.y = element_text(margin = margin(r = 4, unit = 'mm')),

        panel.grid = element_blank(),
        axis.line = element_line(size = 0.25),
        legend.position = c(0.5, 0.75))


p1
ggsave(plot = p1, 
       filename = 'myplot.png', 
       width = 80, height = 50, dpi = 300, units = 'mm')

p2multi <- cowplot::plot_grid(plotlist = list(p2, p2, p2, p2), nrow = 1)

ggsave(plot = p2multi ,
       filename = 'mymultipleplot.png',
       width = 169, height = 50, dpi = 300, units = 'mm')