4

I know that a very similar question already exists here, but the provided answer did not work for me.

This is my usual workflow: I generate a plot and adjust the size of the plot in the "Plots" Panel of RStudio until I am satisfied. I then call dev.size() to get the exact size. Afterwards, I save the plot with ggsave(...,dpi=300) and specify the previously determined width and height. The problem is, that after saving, the plot looks completely different, especially the text sizes.

If I use the "Export" option from RStudio the plot looks exactly as it does in the preview, but the quality is quite bad and doing this manually is tedious.

Here is the picture, that hopefully illustrates what I mean: enter image description here

The code I use to save the plot looks like this:

library(ggplot2)

ggplot(mtcars, aes(x = mpg, y = wt)) + 
  geom_point() + 
  facet_grid(vs + am ~ gear, margins = "vs") +
  theme_Publication()
ggsave("plot.png", width=4, height=3.2, dpi=300)

I would love to know, if there is an option to "programmatically" save a plot which exactly recreates the "Plots" preview in high quality.

Thanks a lot in advance!

bretauv
  • 7,756
  • 2
  • 20
  • 57
nhaus
  • 786
  • 3
  • 13
  • 3
    When I ggsave using the dev.size as dimensions, I get a plot that looks very similar to what the RStudio device shows, with no weird text aberrations. Could you include full code for a (dummy) plot to make it easier to test solutions? – teunbrand Jan 05 '23 at 15:06
  • I edited my question. Also, have you changed the text size using the `theme` argument? This is what I often do. – nhaus Jan 05 '23 at 15:11
  • Thanks that is helpful. I haven't tried that yet. Where i `theme_Publication()` from? If it is a custom theme, could you give relevant text sizes? – teunbrand Jan 05 '23 at 15:32
  • Sorry, my bad. I copy pasted it from here: https://rpubs.com/Koundy/71792 – nhaus Jan 05 '23 at 15:51
  • 1
    I can't replicate the issue either. Note that if you don't specify width/height it should automatically use the current graphics device size. And 300 is the default dpi so you shouldn't really need to specify that either. – MrFlick Jan 05 '23 at 16:00
  • That is really odd... I just tried it on a different machine (one Linux and one Windows) and I still observe the same problem... I am using `options(bitmapType='cairo')`, might this be an issue? – nhaus Jan 05 '23 at 16:06
  • How to get the plot as it's appeared when in the window is in full screen? – Julien Jun 15 '23 at 21:29
  • Have a try with the solution I just posted using my export package. As a bonus you also get a Powerpoint in the exact same size. – Tom Wenseleers Jun 17 '23 at 08:23

4 Answers4

1
  1. In RStudio, click on "Zoom", and then zoom the plot to the size and aspect ratio that satisfy you;
  2. Right click on the plot, then "Copy Image Address", paste the address somewhere, you get the width (www) and height (hhh) information in the address;
  3. ggsave("plot.png", width = www/90, height = hhh/90, dpi = 900) ggsave("plot.pdf", width = www/90, height = hhh/90)
tanqiaoguo
  • 19
  • 2
1

You can use dev.print:

dev.print(pdf, 'filename.pdf')

This will save the plot as it appears in the RStudio plot tab. pdf can be replaced with other file formats.
To obtain a .svg file that is easy to import into word processors use

dev.print(svg, 'filename.svg')

An SVG file does not consist of fixed pixels but can be scaled to any height or width.

png/jpeg/bmp

In part 2 of this answer it is claimed that the filetype for dev.print can also be png, jpeg and bmp. But in my experience simply using dev.print(png, 'filename.png') will result in a plot with too small text. Instead, if the output must be a fixed-pixel format such as png, using the package 'rsvg' produces better results:

#install.packages("rsvg")
library(rsvg)

#Create a temporary file
tmp <- tempfile()

#Put the current plot into the tempfile in the svg format
dev.print(svg,tmp)

#Convert the svg temp file to png and store it in plot.png
rsvg_png(tmp, "plot.png",height=2000)

Only setting the height or width (could replace height with width above) preserves the aspect ratio of the plot as it shown in RStudio. Increase the number of pixels (2000 for height in the above) to improve the resolution of the image.

  • How make it appear in full screen then? – Julien Jun 18 '23 at 07:06
  • For full screen I would adjust the Plots window so it approximately matches the aspect ratio of the target screen. Then use `dev.print(svg,"myplot.svg")` to generate a Scalable Vector Graphic (SVG) image file. SVG's can scale infinitely so the .svg made this way would fit any target screen resolution. – Olympus Mons Jun 18 '23 at 08:14
  • If by full screen you mean a .png that matches the resolution of your monitor, try obtaining a .png by running the lower code-box, but adjusting the pixels. If your monitor resolution is e.g. 1920x1080 (HD) try replacing height=2000 with either width=1920 or height=1080 – this should give a plot image file that is close to the dimensions of the full screen. – Olympus Mons Jun 18 '23 at 16:55
1
  1. I found this resource very helpful for understanding resolution and text sizes in ggplot2: https://www.christophenicault.com/post/understand_size_dimension_ggplot2/
  1. It sounds like you'd benefit from using the camcorder package, which offers an alternate workflow. https://thebioengineer.github.io/camcorder/index.html Instead of showing each plot tweak in the Plots window with a fidgety resolution and size that might not match your ultimate destination, camcorder::gg_record will render the plot to your dimensional specifications and show it in the Viewer pane as a final plot. It's equivalent to saving each plot with ggsave and opening each result -- but all automatic and within the RStudio IDE.

Here's an example:

library(ggplot2)
library(camcorder)
camcorder::gg_record() 

This will now overwrite the plotting device so each plot will be saved to a temporary directory and displayed in the Viewer.

p <- ggplot(mtcars, aes(x = mpg, y = wt)) + 
       geom_point() + 
       facet_grid(vs + am ~ gear, margins = "vs")
p

enter image description here

I can now see that plot in the Viewer. Maybe I don't like the dimensions, so I run:

gg_resize_film(
  height = 4,
  width = 7,
  units = "in",
  dpi = 300
)

That changes the output from now on to 7x4". But now the text is too large for what I want.

enter image description here

So I can tweak that:

p + theme_gray(base_size = 8)

enter image description here

Good, I like that. If I navigate to my tempdir(), I see the files I made. If I want to keep any of those, I should move them into a real folder, otherwise they'll be deleted after this R session. Or I could initially specify a non-temp folder for all the outputs to go with gg_record(dir = "my_dir").

Camcorder also has a neat camcorder::gg_playback() function which makes a gif out of all the drafts -- neat for documenting your process visually.

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53
0

You can export a graph in a programmatic way to various formats (png, ppt, pdf, svg, doc) using my export package, including in the size at which the graph is shown on-screen.

Plot in RStudio Plots window after sizing window to a good size :

enter image description here

Note: if you would like to have your plot in a separate window that you manually resize you can call x11() first (or windows(), but x11() works on both Windows & Mac+Ubuntu, windows() only on Windows) :

x11()

Make plot :

library(ggplot2)
library(export)
# theme_Publication() sourced from rpubs.com/Koundy/71792

ggplot(mtcars, aes(x = mpg, y = wt)) + 
     geom_point() + 
     facet_grid(vs + am ~ gear, margins = "vs") + theme_Publication()

Resize plot window to appropriate size.

Export plot in size of plot window to png & Powerpoint :

# export to PNG at current size:
graph2png(file="plot.png", width=dev.size(units="px")[[1]]/90, height=dev.size(units="px")[[2]]/90, dpi=900)
# note: this would be equivalent to ggsave(file="plot.png", width=dev.size(units="px")[[1]]/90, height=dev.size(units="px")[[2]]/90, dpi=900)

enter image description here

# export to Powerpoint (in editable vector format) at current size:
graph2ppt(file="plot.pptx", width=dev.size(units="px")[[1]]/90, height=dev.size(units="px")[[2]]/90)

enter image description here

# export to pdf (but you need pdf editor to edit) at current size:
graph2pdf(file="plot.pdf", width=dev.size(units="px")[[1]]/90, height=dev.size(units="px")[[2]]/90)

# export to svg (vector format, you can use InkScape to edit) at current size:
graph2svg(file="plot.svg", width=dev.size(units="px")[[1]]/90, height=dev.size(units="px")[[2]]/90)

For publication, I typically use either Powerpoint format (can be edited in PPT after right clicking & pressing ungroup, print to PDF once you are happy with the result) or PDF or SVG, as they are vector format and print much better than a bitmap format like PNG.

To close the plot window you can call

dev.off()
Tom Wenseleers
  • 7,535
  • 7
  • 63
  • 103
  • It doesn't work better than `ggsave`. The Y axis is cropped on the image, at least on my code – Julien Jun 17 '23 at 15:32
  • Strange because I get exactly the same plot in my output than shown on-screen in my RStudio plot window - I've pasted all 3 (plot in RStudio Plots window & PNG & Powerpoint output). What do you get for dev.size() in your case? I suppose it's just something with the dpi scaling, so maybe you need to use something different than that /90? It looks like a factor 2 off or something in your case... – Tom Wenseleers Jun 17 '23 at 15:50
  • The problem seems to come from from the software on Windows that display the photo, it looks good on Paint – Julien Jun 17 '23 at 15:54
  • How to save it as the same as it appeared after expanding the windows to full size on RStudio? – Julien Jun 17 '23 at 15:56
  • Ha just call x11() first before making the plot to have it in a graphics plot window that you can resize to the size you like... – Tom Wenseleers Jun 17 '23 at 16:00
  • 1
    Note that for publication it is best to use a vector format like Powerpoint, PDF or SVG, not a bitmap format like PNG. That will print much more nicely & can also be edited if you like (e.g. adding annotations or to make slight changes in formatting). – Tom Wenseleers Jun 17 '23 at 16:04
  • Feel free to check my answer as the correct one if it solved your problem :-) – Tom Wenseleers Jun 17 '23 at 16:05
  • What do ypu mean by "call x11() first" ? – Julien Jun 17 '23 at 16:06
  • x11() (or on Windows you can also use windows()) will make a separate plot window and if you then call your ggplot code & size that window you can export your plot in that size... – Tom Wenseleers Jun 17 '23 at 16:22
  • So did this work for you @Julien? If it does please feel free to check this is the correct answer... – Tom Wenseleers Jun 18 '23 at 06:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254125/discussion-between-julien-and-tom-wenseleers). – Julien Jun 18 '23 at 07:13