Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get exact font, line, point and figure sizes in ggplot2?

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.

like image 901
David LeBauer Avatar asked Nov 14 '16 17:11

David LeBauer


People also ask

What is default text size ggplot?

The base font size is 11 pts by default. You can change it with the base_size argument in the theme you're using.

What is DPI in Ggsave?

To go from the dimension in inches to a number of dots, ggsave uses the number of dots per inches (dpi). So if we create a plot in ggplot and save it with a dimension of 12 x 10 with the default dpi of 300 for ggsave, the file will be a matrix of (12 * 300) x (10 * 300) = 3600 x 3000 dots.

What is the default font in ggplot2?

R and ggplot can create fantastic graphs, but the default Arial/Helvetica font is too boring and standard. You can change the font used in a plot fairly easily three different ways: All of the built-in ggplot themes have a base_family argument for setting the overall font family for the plot.

How do I make the font bigger in ggplot2?

To increase the X-axis labels font size using ggplot2, we can use axis. text. x argument of theme function where we can define the text size for axis element. This might be required when we want viewers to critically examine the X-axis labels and especially in situations when we change the scale for X-axis.


1 Answers

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')
like image 161
FedRo Avatar answered Sep 22 '22 18:09

FedRo