17

I am trying to save a ggplot2 plot in svg format. I am not using the ggsave function because the plot is generated as part of a knitr document - the device I specify for plotting is 'svg'.

The problem is that text elements from the original plot appear as paths in the svg file, at least when opened in inkscape. The source code of the svg does not look like it contains any text either.

My plotting function is defined in a separate file:

## @knitr plot_histogram ggplot(mainFrame[complete.cases(mainFrame),]) + geom_boxplot(aes(x=source, y = pPfam, fill = source)) + scale_y_continuous(limits = c(0,1)) 

In the knitr document, I call the function and save the image using the 'svg' device.

```{r plot_histogram, dev = 'svg', fig.width= 7, fig.height=4, fig.show='hold', fig.path="figure/summary"} ``` 

So I'm not sure how to tell the 'svg' device or ggplot2 that I want to preserve text when saving svg? I would also be happy to use another graphics device if that solves the problem.

Many thanks in advance.

3 Answers 3

16

Neither the svg() device in base R nor the CairoSVG() device in the Cairo package supports this. All texts are turned into glyphs like

<symbol overflow="visible" id="glyph0-2"> <path style="stroke:none;" d="M 3.921875 -2.046875 L 3.921875 0.... "/> </symbol> 

I do not know why this has to be the case, and you may want to file a feature request to the r-devel mailing list. This question is not specific to ggplot2/knitr. It comes from the SVG device.

Update

The OP pointed out that the RSvgDevice actually works, and we can specify the device by:

my_svg <- function(file, width, height) { library(RSvgDevice) devSVG(file = file, width = width, height = height, bg = "white", fg = "black", onefile = TRUE, xmlHeader = TRUE) } 

Then in knitr code chunks, use the option dev='my_svg'.

Sign up to request clarification or add additional context in comments.

10 Comments

Yihui thanks for your answer - I might try and request this from the r-devel list then because I think it would be very useful to keep the text selectable/editable.
Seems there is already a device that supports text. It's called RSvgDevice. This links to it on cran
So this works with a custom graphics device for knitr eg. my_svg <- function(file, width, height){ devSVG(file = file, width = width, height = height, bg = "white", fg = "black", onefile=TRUE, xmlHeader=TRUE)} and setting dev = 'my_svg'. Perfect!
@TobiO You may install the svglite package and use dev = 'svglite'
I finally got it to work. After export with svglite open the file once in inkscape, make some spurious change and save the file Then use a text editor and remove all the lines that have the follwing format: lengthAdjust="spacingAndGlyphs" and textLength="8.00px" (use regex textLength.*\n ) Save and enjoy in inkscape
|
2

Now ggsave("plot_using_svglite.svg",device = svglite::svglite)

renders the text correctly.

Comments

1

You can also save the plots as PDF; after, convert them to SVG (optimised: for a small size; and the precision have to be bigger than 4 for good images) using the Inkscape.

2 Comments

that could have been a comment.
however, when using this with ggplot geom_points, the pch is not conserved. all standard dots (pch 16 i think) are shown as 'q'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.