Exporting Plots: Saving High-Quality Graphics

You've crafted your viusalization — now what? Time to share it! This lesson covers how to export high-quality graphics from R for papers, slides, or social media.

Learn which formats to choose, how to control resolution, and what to watch out for when saving plots across platforms.

Free6 minutes read

🎞️ From Plot to Image

Sharing your plots effectively means more than just exporting an image. Correctly handling dimensions, resolution, and format ensures that your graphics remain sharp, readable, and visually consistent — whether they appear in papers, presentations, or online.

In R with ggplot2, your workhorse is ggsave().
But exporting is usually more than ggsave("my_plot.png").

ggsave() does not only handle the name and format of the file (based on the extension, such as .png,.pdf, .svg), but lets you control the aspect ratio and resolution so the output looks crisp wherever it goes.

💾 Saving Plots

By default, ggsave() exports the last ggplot you generated, and places it in your current working directory. The extension decides the format — .png, .tif, .pdf, ... well, we covered that already.

You specify the file name and extension by passing it to the filename argument. If you want to store the plot in a different folder, you can specify:

Note: Windows uses the backslash \ in file paths, but in R this acts as an escape character. To avoid problems, use / or \\ instead — or simply use file.path() to build the path in a robust way.

You also can store a plot first and then hand over the ggplot object by specifying plot = as well.

Often, users rely on implicit matching here — the filename is provided first, so specifying the argument name (filename =) isn’t necessary, as shown in the second example above.

📐 Controlling the Export

When saving plots, it’s best to set the canvas explicitly so the file is ready for its final destination — whether that’s a paper, a slide deck, or the web.

First, control the  aspect ratio  by setting width andheight:

By default, these numbers are in inches. Prefer centimeters? Millimeters? Or pixels? Just switch the  units :

For raster formats like PNG or TIFF, you’ll also want to set the  resolution  with dpi (dots per inch):

Optionally, set the  background  explicitly with bg — helpful if your plot is placed over colored slide backgrounds or webpages:


The Annoying Process of "Getting the Size Right"...

One of the most asked questions in my live workshops is this:

How do I get the size right so that geometries and theme elements look good — and not so different from what I see in the plot preview pane?

A moment likely every ggplot user has faced — but hates to be reminded of: you’ve fine-tuned a chart you’re proud of, only to realize: the exported graphic looks awful (and sadly not the "awful-as-in-amazing" kind).

Relying on the plot pane in Rstudio or Positron to tweak the size is not helpful as it adjust to the window size and doesn't reflect your export settings.

To avoid surprises, it’s best to decide on your target size early, latest once you have an idea how your plot should look like and what it contains.

Nevertheless, finding the right sizes for all components of the plot can become very time-consuming, as we end up with the classic trial-and-error approach: Save the plot, inspect it, tweak it — and repeat.

For more detailled graphics, this can easily mean: doing that a few hundreds times! To avoid switching between your coding environment and the plot folder but see your future output directly, there are two approaches to simplify your life:

  • Use Quarto notebooks with fig-width, fig-height and fig-dpi set for all plotting chunks like this:

        #| fig-width: 9
        #| fig-height: 6
        #| fig-dpi: 100

    When you preview the plots in-line, they show up as if you export them with the same specifications set in ggsave().

  • Use the camcorder 📦 to automatically capture every generated ggplot with user-specific width, height and resolution. It will not only export the plot — but display the result directly in your IDE!

    Read more about how it works in the dedicated article.

🖨️ High-Quality Output

R uses a to transform your R objects into images. But for professional publications, default devices may not always give the best results.

Issues can arise with custom typefaces, the depiction of symbols and emojis, and even subtle differences in rendering across formats or operating systems.

Two common solutions for high-quality output in R are AGG-based devices provided by the ragg 📦 and Cairo-based devices already included in base R’s grDevices (if R was built with Cairo support).

✨ Rendering Raster Files with ragg

The ragg package provides raster devices built on the AGG (Anti-Grain Geometry) rendering library, that is known for smooth anti-aliasing and reliable text output. It makes high DPI images easy to create and ensures fonts, symbols, emojis, and also right-to-left scripts render fast and consistently, even across platforms.

By default, ggsave() uses AGG-based devices now — if the ragg package is installed. To enable them, simply install the package with install.packages("ragg").

To specify it explictly, use the device argument:

✨ Rendering PDF Files with Cairo Devices

Cairo devices produce high-quality vector (and also raster) output with robust font and symbol support. It's ideal for plots with complex text, ligatures, or annotations, that are exported as PDF vector files.

You can render your PDF by specifying the cairo_pdf as device:



The graphics backends has a huge impact on how your visualizations are rendered. The example below illustrates the differences, suming up nicely why choosing the right device matters for high-quality graphics — especially when running the code on different operating systems.

A comparison of several devices with left-to-right and right-to-left text (left) and a combinaion of symbols (right).
A comparison of several devices rendering raster files displaying left-to-right and right-to-left text (left) and a combination of symbols (right). In the original blog post, "Modern Text Features in R", Thomas Lin Pedersen highlights the advanced rendering features of the devices provided by the ragg package.

Live demo

This lesson was quite technical, and we believe it’s easier to follow when you see it in action. Here’s a video of Cédric saving a few charts and tackling some of the most common issues!

📋 Recap

We encourage you to open your own R environment and experiment with the concepts covered here. The usual in-course sandbox isn’t suited for this lesson.

To wrap up, check your understanding with a short quiz and see how well you’ve mastered the key ideas!

What's the go-to function to save a ggplot2 chart?

png()
save()
ggsave()
plot()

.png and .jpg are formats known as raster files.

True
False

When should you start thinking about the final size and format of your plot?

Only after finishing the plot in the RStudio/Positron preview pane
Right from the start, once you know the plot’s destination
It doesn’t matter, ggplot will adapt automatically
Only when your boss or a journal requests a file

Which file type should you use if you want a plot that scales infinitely without losing quality?

PNG
JPG
PDF
TIFF

What does the dpi argument in ggsave() control?

The Document Print Interface
The resolution of raster images
The file extension
The aspect ratio

Why is relying on the RStudio/Positron plot pane misleading when adjusting plot sizes?

It displays all text in 12pt Arial.
It adapts to the window size, not export settings.
It only works for raster formats.
It ignores ggplot themes.

How do you control the output format of a plot when using ggsave()?

By using the 'file_format' argument.
By renaming the ggplot object passed to the function.
By adding the extension to the filename.
By setting 'options = list(format = ...)'.

By default, ggsave() saves the most recent ggplot2 plot. How can you save a plot that you've generated earlier?

You can’t, ggsave can only export the latest plot.
Pass the plot object to ggsave using the 'plot' argument.
Reprint the plot in the console and then run ggsave.
Run 'history()' to retrieve the previous plots.
← Previous

Scales

Next →

Project