How do I preserve transparency in ggplot2?
Asked Answered
O

6

31

I love the plots that ggplot generates. However, it is still somewhat cumbersome to get publication quality plots directly. I usually have to do some post processing in Illustrator (i.e. changing fonts, numbering figures etc). While I could save as tiff or png, eps is best for manipulating figures in Illustrator (I can ungroup objects, move the legend/text etc).

When I save a ggplot object with some transparency (either in points or a smoother) I get this error:

Warning message:
In grid.Call.graphics("L_points", x$x, x$y, x$pch, x$size) :
  semi-transparency is not supported on this device: reported only once per page

Is there a workaround?

Ot answered 22/10, 2010 at 22:5 Comment(3)
Below also an easily solution to export in an editable vector-based format directly to Powerpoint, where you can easily fix minor formatting issues, and with full preservation of transparency. See if that suits you...Venetic
I think my answer below more accurately and fully answers your question, so you might like to check that one as the correct answer - well, see what you think...Venetic
Added a solution below using the new export package - I think that one should be flagged as the correct answer in fact...Venetic
A
19

R's eps "device" doesn't support partial transparency, but, if I remember correctly, its PDF device does. Illustrator ought to be able to read PDFs with equal facility to EPSes, or if not, try converting them after generation with pdftops (not pdf2ps, they are totally different programs and pdf2ps's output is ... inferior).

Note that R doesn't try to optimize its PDF output at all, so even if you do get a plot that needs no postproduction, you will want to run it through a compression utility like qpdf at the very least.

Atharvaveda answered 22/10, 2010 at 22:19 Comment(5)
Thanks! For those of you on OSX, <a href="tex.aanhet.net/epspdf/#install">here</a> is an easy tool to convert from pdf to eps.Ot
Er... this doesn't work. Unless I'm missing an option, if I try pdftops -eps graph.pdf graph.eps, where graph has semi-transparent vector lines, then those parts of the graph will be rasterised in the EPS. This is pretty much useless (I may as well convert to jpeg). tex.stackexchange.com/a/24287/13192 indicates that postscript doesn't support semi-transparency at all...Workingman
@Workingman Huh, I thought that had been added to postscript at some point. I don't know what your situation is, but I would try to eliminate the use of EPS files altogether -- pdfTeX for instance can slurp in PDF-format graphics just fine (in fact this is easier than getting it to eat EPSes).Atharvaveda
Zack: I know. It works for me. I can't help that the journal I'm submitting to is technologically backward though.Workingman
@Workingman Yeah, you may be up a creek, sorry.Atharvaveda
C
49

This works:

ggsave("filename.eps", device=cairo_ps)
Carissacarita answered 5/8, 2013 at 10:23 Comment(8)
This does work. Why was it downvoted without comment?Mcewen
I agree--this is a great solution that I plan to use frequently.Encratis
As pointed out here https://mcmap.net/q/470350/-can-transparency-be-used-with-postscript-eps cairo_ps automatically rasterizes transparency, but does so at low resolution (72 dpi)Energy
You can also add the argument fallback_resolution to control the resolution at which semi-transparent areas are rasterized (this was introduced in a recent R update), e.g. you can now use ggsave("filename.eps", device=cairo_ps, fallback_resolution = 600)Venetic
I get an unused argument error when I try to add the fallback_resolution? @TomWenseleersViridian
Well for me this works though: cairo_ps(file = "test.eps",onefile = FALSE,fallback_resolution=600) qplot(Sepal.Length, Petal.Length, data = iris, color = Species, size = Petal.Width, alpha = I(0.7)) dev.off()Venetic
And I don't get an error when I try ggsave("filename.eps", device=cairo_ps, fallback_resolution=600) either... I'm working under Windows, and you?Venetic
This is under R 3.3.3 - I know it's been introduced relatively recently though, so is the R version you are using a recent one?Venetic
S
24

I had the same issues with using the postscript function. I found that cairo_ps from the grDevices package does support transparency (at least in Ubuntu 10.04 with R version 2.10.1). Usage would be:

cairo_ps(filename='filename.eps', width=7, height=7)
plot(x,y)
dev.off()
Saphra answered 8/12, 2010 at 12:37 Comment(2)
You can also add the argument fallback_resolution to control the resolution at which semi-transparent areas are rasterized (this was introduced in a recent R update) (e.g. fallback_resolution=600 for 600 dpi)Venetic
Upvote to this solution as it provides a wide range of functionality for the problem. In my case I was using grid.arrange for multiple plots and the other solutions would not have workedConcourse
A
19

R's eps "device" doesn't support partial transparency, but, if I remember correctly, its PDF device does. Illustrator ought to be able to read PDFs with equal facility to EPSes, or if not, try converting them after generation with pdftops (not pdf2ps, they are totally different programs and pdf2ps's output is ... inferior).

Note that R doesn't try to optimize its PDF output at all, so even if you do get a plot that needs no postproduction, you will want to run it through a compression utility like qpdf at the very least.

Atharvaveda answered 22/10, 2010 at 22:19 Comment(5)
Thanks! For those of you on OSX, <a href="tex.aanhet.net/epspdf/#install">here</a> is an easy tool to convert from pdf to eps.Ot
Er... this doesn't work. Unless I'm missing an option, if I try pdftops -eps graph.pdf graph.eps, where graph has semi-transparent vector lines, then those parts of the graph will be rasterised in the EPS. This is pretty much useless (I may as well convert to jpeg). tex.stackexchange.com/a/24287/13192 indicates that postscript doesn't support semi-transparency at all...Workingman
@Workingman Huh, I thought that had been added to postscript at some point. I don't know what your situation is, but I would try to eliminate the use of EPS files altogether -- pdfTeX for instance can slurp in PDF-format graphics just fine (in fact this is easier than getting it to eat EPSes).Atharvaveda
Zack: I know. It works for me. I can't help that the journal I'm submitting to is technologically backward though.Workingman
@Workingman Yeah, you may be up a creek, sorry.Atharvaveda
S
6

You could also try exporting as SVG via the svg device. Not sure if Illustrator can read SVG, but Inkscape can, and it's open source :) I've done some good things with R output to SVG in Inkscape, and the groupings are preserved as with EPS. Can't be 100% sure it handles opacity but I'm sure its in the SVG standard.

Shiprigged answered 22/10, 2010 at 22:28 Comment(1)
SVG works too although it created weird, large, semitransparent letters in the background. There was a really big O,X,Y in the background. But I was able to remove those. So this is another option that allows for skipping the conversion. thanks.Ot
V
6

The EPS format in principle does not support semi-transparency - if you want semi-transparency and be able to edit in Illustrator or Inkscape you would better export to SVG or PDF. If you are really tied to the EPS format you could use the cairo device though, and specify at what resolution semi-transparent objects need to be rasterized (only the non-semitransparent elements stay as vector format then though, semi-transparant areas are rasterized to bitmap). The syntax to do this is:

cairo_ps(file = "test.eps", onefile = FALSE, fallback_resolution = 600)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species, size = Petal.Width, alpha = I(0.7))
dev.off()

or

ggsave("filename.eps", device=cairo_ps, fallback_resolution = 600)

An alternative option is to export to MS Office Powerpoint in vector format, and do any layout editing there. This can be done easily using my new export package, see https://cran.r-project.org/web/packages/export/index.html and for demo https://github.com/tomwenseleers/export

Typical syntax is very easy, e.g.:

install.packages("export")
library(export)
library(ggplot2)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species, 
      size = Petal.Width, alpha = I(0.7))     
graph2ppt(file="ggplot2_plot.pptx", width=6, height=5) 

This results in a fully editable, high quality Powerpoint graph in native Office vector-based DrawingML format, with full support for transparency. In there you can easily fix minor formatting issues, and export to a high quality PDF by printing to PDF.

You can also use it to export to Word, Excel, Latex or HTML and you can also use it to export statistical output of various R stats objects.

It also has a graph2eps(file="plot.eps", width=6, height=5, fallback_resolution=600) function to export to eps with rasterizing of semi-transparent areas...

Venetic answered 26/6, 2015 at 16:55 Comment(0)
D
-3

I found an easy way to do so.

Use "zoom" in R plot and click right mouse to copy the picture. You can get a plot with shadow.

Declaim answered 22/10, 2018 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.