Is it possible to create .eps files with ggsave using the Cairo graphics device?
Asked Answered
M

3

6

Edit: This page provides the code: https://www.andrewheiss.com/blog/2017/09/27/working-with-r-cairo-graphics-custom-fonts-and-ggplot/

ggsave("test_cario.eps", device=cairo_ps)

ggsave("test_cario.pdf", device=cairo_pdf)

However, I am wondering where the commands come from. They are not included in the list of possible devices in the official documentation (https://ggplot2.tidyverse.org/reference/ggsave.html). And, cairo_png does not exist; instead, type="cairo-png" is necessary, e.g.:

ggsave("test_cairo.png", type = "cairo-png")

Does anyone know why the argument is one time device = "" and another time type = ""?


I have tried code like

ggsave("model.eps", type = "cairo")

or

ggsave("model.eps", type = "cairo-ps")

or

ggsave("model.eps", device = "cairo-ps")

but nothing seems to work. In general, is it possible to create .eps files with ggsave using the Cairo graphics device? If so, how?

Marinate answered 1/2, 2018 at 16:25 Comment(3)
have you tried the suggestions here? #4001816Guyon
Could you please clarify the importance to you of using the Cairo device? Is the a shortcoming in using device = "eps"?Knighterrantry
I prefer Cairo because it supports anti-aliasing.Marinate
F
2

TL;DR

You need to call specific pdf and ps cairo devices while the standard png device can be set to produce cario output using its own type parameter.

Explanation

The device parameter of ggsave can take a device function, a character string matching one of a predefined list, or be left as NULL (in which case the device is guessed from the file extension). In any case, a device function will be called. Note that when using the function form, you may need to set some parameters that ggsave would do for you if you used the character or auto-detection forms.

The grDevices package which contains most of the devices used by default also has cario_pdf and cairo_ps devices that you can pass to ggsave.

There is no cairo_png device. However, the png device has a type parameter which takes options from the following vector(on Windows as least): c("windows", "cairo", "cairo-png"). ggsave passes on the type specification to the png device when it calls it.

Fadil answered 24/9, 2018 at 13:42 Comment(2)
Thanks! Do you know if it is possible to produce wmf or emf files with ggsave (and possibly with cairo)? Is that the windows device?Marinate
Yes, that is one of the built in options that can guessed by extension or you can use by using "emf" or "wmf" as the device string. There is no cairo option for the default win.metafile device though.Fadil
P
3

The code you need to look at to understand the differences is in a non-exported function named plot_dev in the ggplot namespace. You get this information by looking at the ggsave code. The line that dispatches to a device is:

dev <- plot_dev(device, filename, dpi = dpi)
# Look at that function
getAnywhere(plot_dev)  # not exported, so need getAnywhere

The logic of plot_dev is to first check to see whether the "device" value was given as a function name and if so to just call that function. That is what happens in the first two calls you offered. If it's not a function and no character value for "device" is given (which is the situation in your third call), then plot_dev dispatchs from a named list of functions based on the extension of the file name offered as "filename". The type argument gets passed to the png function to get the 'cairo' version of png used rather than the default.

This is the list of possible devices and their default arguments. Those defaults can be offered alternate values and the "dots" can be used to specify other device parameters. (See their respective help pages for specifics):

devices <- list(eps = eps, 
                ps = eps, 
     tex = function(filename, ...) 
                    grDevices::pictex(file = filename, ...),
     pdf = function(filename, ..., version = "1.4") 
               grDevices::pdf(file = filename, ..., version = version), 
      svg = function(filename, ...) vglite::svglite(file = filename,  ...), 
     emf = function(...) grDevices::win.metafile(...), 
     wmf = function(...) grDevices::win.metafile(...), 
     png = function(...) grDevices::png(..., res = dpi,
                                       units = "in"), 
     jpg = function(...) grDevices::jpeg(..., res = dpi,
                                         units = "in"), 
     jpeg = function(...) grDevices::jpeg(..., res = dpi,
                                          units = "in"), 
     bmp = function(...) grDevices::bmp(..., res = dpi,
                                      units = "in"), 
      tiff = function(...) grDevices::tiff(..., res = dpi,
                                           units = "in"))

Notice that the first two parameters are given values of eps. That is an internally defined function:

eps <- function(filename, ...) {
       grDevices::postscript(file = filename, ..., onefile = FALSE, 
            horizontal = FALSE, paper = "special")
Pickaninny answered 24/9, 2018 at 5:28 Comment(4)
Thank you very much for this elaborate answer. Do you know if it is possible call cairo directly with the 'device=""' argument?Marinate
Does not look possible in the context of ggsave because a) that would throw an error, and b) there is no corresponding entry in the devices-list, so it's not possible to have the selection driven off an extension. (There's no "cairo" extension recognized by system functions anyway.)Pickaninny
@Marinate You can create your own function wrapper to png with the cario version as the default.Fadil
Thanks! Do you know if it is possible to produce wmf or emf files with ggsave (and possibly with cairo)? Is that the windows device?Marinate
F
2

TL;DR

You need to call specific pdf and ps cairo devices while the standard png device can be set to produce cario output using its own type parameter.

Explanation

The device parameter of ggsave can take a device function, a character string matching one of a predefined list, or be left as NULL (in which case the device is guessed from the file extension). In any case, a device function will be called. Note that when using the function form, you may need to set some parameters that ggsave would do for you if you used the character or auto-detection forms.

The grDevices package which contains most of the devices used by default also has cario_pdf and cairo_ps devices that you can pass to ggsave.

There is no cairo_png device. However, the png device has a type parameter which takes options from the following vector(on Windows as least): c("windows", "cairo", "cairo-png"). ggsave passes on the type specification to the png device when it calls it.

Fadil answered 24/9, 2018 at 13:42 Comment(2)
Thanks! Do you know if it is possible to produce wmf or emf files with ggsave (and possibly with cairo)? Is that the windows device?Marinate
Yes, that is one of the built in options that can guessed by extension or you can use by using "emf" or "wmf" as the device string. There is no cairo option for the default win.metafile device though.Fadil
Z
0

You can save to EPS with

ggsave("model.eps", device = "eps")
Zola answered 20/9, 2018 at 19:11 Comment(2)
It's worth mentioning that the available graphics device options are documented here: ggplot2.tidyverse.org/reference/ggsave.htmlSufficiency
Is that using the Cairo graphics device?Marinate

© 2022 - 2024 — McMap. All rights reserved.