Search code examples
rsvgggplot2knitr

How to preserve text when saving ggplot2 as .svg?


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.


Solution

  • 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'.