rggplot2ggimagegrimport

Use SVG images as symbols in gglot2


I would like to use vector graphics stored in external files (e.g. SVG) as my plotting symbols in a ggplot2 figure. e.g. following this example from the grImport vignette (Fig. 8) https://cran.r-project.org/web/packages/grImport/vignettes/import.pdf

enter image description here

This example imports a custom shapefile and then plots it using lattice e.g.

xyplot(V8 ~ V7, data = flower, xlab = "Height",
               ylab = "Distance Apart",
               panel = function(x, y, ...) {
                                grid.symbols(PSflower, x, y, units = "native",                     
                                             size = unit(5, "mm"))})

with grid.symbols() coming from the grImport package and PSflower being a Picture object imported elsewhere by grImport.

The ggimage package gets close to doing this, but it converts the image to a raster below plotting, which is what I'm trying to avoid.

Is there any way I could implement something similar in ggplot2?

Mark


Solution

  • This is the solution that I came up with - seems to work pretty well. You can also do a similar trick with grImport. The key is making sure that the normalised plot coordinates of the grob matches up with the native coordinates of ggplot.

    #Setup
    library(grImport2)
    library(ggplot2)
    library(scales)
    src.file <- system.file("SVG", "lwd-rsvg.svg", package="grImport2")
    img <- readPicture(src.file)
    
    #Now createa some data
    d <- data.frame(x=1:5,y=1:5)
    
    #Need to specify xlims and ylims of plot - this lets us calculate the
    #normalised plot coordinates
    xlims <- c(0,6)
    ylims <- c(0,6)
    
    #Create the plot points using symbolsGrob
    sym.grob <- symbolsGrob(img,
                            x=rescale(d$x,from=xlims),
                            y=rescale(d$y,from=ylims),
                            default.units="npc",
                            size=0.3)
    
    #Plot
    ggplot(d,aes(x,y))+
      geom_point()+
      annotation_custom(sym.grob)+
      coord_cartesian(xlim=xlims,ylim=ylims,expand=FALSE) #Don't forget this!
    

    enter image description here