53

R question.

I got so confused by the width, height, dpi and unit.

Why the following two size different?

ggsave(filename = "foo.png",ggplot(mtcars, aes(x=wt, y=mpg)) +
    geom_point(size=2, shape=23),width = 5, height = 4, dpi = 300, units = "in", device='png')

and

ggsave(filename = "foo.png",ggplot(mtcars, aes(x=wt, y=mpg)) +
           geom_point(size=2, shape=23),width = 5, height = 4, dpi = 72, units = "in", device='png')

I set both of the picture's size 5 (inches) * 4 (inches). But why when I change the dpi, the size changes?

How to understand the relationship between height, width, unit and dpi?

Or how to translate these four parameters into unit of pixels, which is easier for me to understand?

Henrik
  • 65,555
  • 14
  • 143
  • 159
WCMC
  • 1,602
  • 3
  • 20
  • 32
  • 6
    "*how to translate these four parameters into unit of pixels*" set `units = "in"`, then you can multiply `height` by dpi or `width` by `dpi` to get pixels in the vertical and horizontal. [Wikipedia on dpi](https://en.wikipedia.org/wiki/Dots_per_inch). – Gregor Thomas Jun 23 '17 at 00:41
  • I think the size has to be set in terms of physical size to make sure font sizes stay consistent. If you set the size in pixels only, you don't know what size the text will be once you put it on a page with a certain physical size. And if you put both of your example plots on a page at the same physical size, the font sizes should be the same. – Marius Jun 23 '17 at 01:23
  • 3
    @Marius, I agree with you. I prefer physical size than pixels as well. It just confuse me that even I set physical size of 5 * 4, by changing dpi, which is not a physical size parameter, the .png plot size changes. – WCMC Jun 23 '17 at 01:25

2 Answers2

61

To understand why the DPI is important, consider these two plots:

ggsave(filename = "foo300.png", ggplot(mtcars, aes(x=wt, y=mpg)) +
           geom_point(size=2, shape=23) + theme_bw(base_size = 10),
       width = 5, height = 4, dpi = 300, units = "in", device='png')
ggsave(filename = "foo150.png", ggplot(mtcars, aes(x=wt, y=mpg)) +
           geom_point(size=2, shape=23) + theme_bw(base_size = 10),
       width = 10, height = 8, dpi = 150, units = "in", device='png')

The resulting files have the same pixel dimensions, but the font size in each is different. If you place them on a page with the same physical size as their ggsave() calls, the font size will be correct (i.e. 10 as in the ggsave() call). But if you put them on a page at the wrong physical size, the font size won't be 10. To maintain the same physical size and font size while increasing DPI, you have to increase the number of pixels in the image.

Marius
  • 58,213
  • 16
  • 107
  • 105
  • 2
    Could you elaborate on the * place them on a page with the same physical size as their*, I am a little confused... Say I am viewing both images in my system viewer, which will render them in the same-sized window. Should I decrease one window, to be half of the other one ? Thanks! – Matifou Jul 03 '19 at 01:22
  • 1
    @Matifou: If you're viewing the image files after saving, I think you want them to be in the same size window, because then they will have the same "physical size" on your monitor. The DPI is all about what the image will look like once it's actually printed out in a document, so it's hard to understand while viewing them on a computer. – Marius Jul 03 '19 at 01:27
  • 1
    @Marius can you let me know if we can increase the device size in R ? I have a Q posted here https://stackoverflow.com/questions/64756969/creating-large-image-collage-in-r-or-python – user5249203 Nov 10 '20 at 20:39
7

The two examples you gave have the same image 'scaling' but different 'image quality', if you pull the saved png into a .docx file, drag them to the same size, you will see they are the same image with just different 'image quality'. So in this way, we understand width and height as image 'scaling' and dpi as 'image quality'.

If you want to shape your figure to fit a journal's need while having decent font size and element size, this would be the best practice:

  1. ggplot first
 ggplot(mtcars, aes(x=wt, y=mpg)) +
           geom_point(size=2, shape=23)
  1. Check the figure in Rstudio Plots window, if not satisfied, click Zoom, drag the pop-out window to your preferred size

  2. right click the figure and choose Inspect element

then you see the line

<img id="plot" width="100%" height="100%" src="plot_zoom_png?width=214&amp;height=151">

The above line suggests that your best width is 2.14 and best height at 1.51

  1. ggsave() what you have just seen
ggsave(filename = "foo3.png",width = 2.14, height = 1.51, dpi = 300)
# set the dpi as journal requirement, now the dpi only changes image quality, not image content
  • 1
    This is a cool option, is there a way to do this automatically whitout having to manually inspect the element? – CyG Sep 14 '22 at 15:51
  • @CyG I guess the idea is to use this method to decide what width and height fit your image. It cannot be done automatically? – Johanna Sörensen Jan 02 '23 at 12:54
  • For many journals, the image width might be set, meaning that you can only choose the image height (and size of lines, etc.). – Johanna Sörensen Jan 02 '23 at 12:54