Using svglite with web fonts by @ellis2013nz

[This article was first published on free range statistics - R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

OK, no stats today, just fidgeting about with graphics devices and type faces. Caveat – the details of graphics formats and typefaces is not my area of real expertise, this blog post is me noting down things that I found useful and others might too. As always, corrections and comments are very welcome.

There are two main types of computer graphic formats:

  • vector graphics, where the file is basically a set of instructions (start at x, draw a line at 30 degrees angle for y units, draw a circle of radius w centred at z, etc). Like something you generated with Inkscape or Adobe Illustrator.
  • raster or bitmap graphics which are basically an array of numbers telling the computer which how to colour each pixel. Like a digital photograph.

Generally vector formats are far superior if you have the choice but large complex graphics (eg with millions of points, or maps with many fiddly bits) can be slow to render (and large to store). And until relatively recently many users’ web browsers could only show bitmap graphics. Internet Explorer 8 was the last high-use browser of this sort we had to worry about.

For my blog I work almost purely with Scalable Vector Graphic (SVG) format by choice, and PNG (a relatively efficient and high quality bitmap format) when I have to.

My graphics workflow for this blog is generally:

  1. Write the graphic to a Scalable Vector Graphic (SVG)
  2. Convert the SVGs to PNGs in batches using ImageMagick

I use the SVGs on the web pages that make up this blog; I need the PNG copies for posting on Twitter, Facebook and LinkedIn which don’t take SVGs, and also for some complex objects that would be too large as SVGs.

A quick aside on anti-aliasing

To get in the groove of thinking about graphics I’m going to start with the concept of anti-aliasing. Here are three closeups of a straight line in a computer graphic, generated in R by three different graphics devices. From left to right these were generated by CairoSVG(), CairoPNG() and png().

Aliasing (in graphics) refers to the jagged staircase-like bits of an image from approximating an ideal shape with crude collections of pixels. Anti-aliasing is basically the smoothing or blurring process to try to make the problem less obvious.

On a Windows machine (where I spend nearly all my working time), the png() device, no matter high a resolution you specify, will not use anti-aliasing and close ups of the image will reveal jagged bits like that in the right of the three options above. At the opposite end, a graphic that has been saved as SVG won’t have any aliasing at all coming from the file format itself; any jaggedness comes from the final rendering of the information in the file onto the screen (in the end, everything has to become pixels to get on the screen), not from how you generated the file.

The Cairo option in the middle has anti-aliasing taking place when the PNG file itself was generated. Files generated with CairoPNG() look much better than those from png(), but still can’t compete with the vector format even when the PNG is high resolution (eg 720 or more dots per inch).

Here’s the code that generated these examples

library(Cairo)
library(svglite)
library(frs)
library(clipr)

png("0150-antialias-none.png", 8 * 600, 4 * 600, res = 600)
plot(1:2, 1:2, type = "l", bty = "n", main = "No anti-alias png() device")
dev.off()

CairoPNG("0150-antialias-cairo.png", 8 * 600, 4 * 600, dpi = 600)
plot(1:2, 1:2, type = "l", bty = "n", main = "Anti-aliased CairoPNG device")
dev.off()

CairoSVG("0150-antialias-cairo.svg", 8, 4)
plot(1:2, 1:2, type = "l", bty = "n", main = "CairoSVG device")
dev.off()

Potentially useful whimsical tip: once your awareness is raised about the need for anti-aliasing, you might become painfully aware of those unprofessional looking jagged bits in graphics. When working interactively in RStudio on Windows, all the graphics in your plot pane will look this way. If this hurts you like it hurts me, you can bring up a anti-aliased window with CairoWin() and plots will be rendered nicely on that window, and look much better than the crude default renditions. If you’re using two screens it’s also convenient for placing on your second screen.

Different flavours of SVG

Until recently I’ve been generating my SVG files with CairoSVG(). However, I’ve gotten very disatisfied with how text is rendered by that format. It’s hard to put my finger on what is wrong, but it looks blurry, particularly when it’s about 10 point in size which of course is nearly all the time in statistical graphics. Sometimes the problem goes away when you zoom in, but that isn’t really the point.

I eventually solved this problem by moving to the excellent svglite package by Hadley Wickham, Lionel Henry, T Jake Luciani, Matthieu Decorde and Vaudor Lis. svglite creates smaller and faster SVGs and has a much better treatment of text in particular. But svglite alone wasn’t enough for the way I needed typefaces treated – I’ll get to that later.

To go into this further, here are three different SVG files, rendered in this web page as images, created by Cairo::CairoSVG(), grDevices::svg() and svglite::svglite().



The first two approaches are very similar, but the svglite philosophy is quite different. CairoSVG and svg take text and turn it into many tiny shapes to draw; whereas svglite keeps the text as text in the SVG file and leaves it to the end user’s computer to render it. Zoom in close on any of those images above and the text will magnify nicely; but something about the relatively complicated approach of the first two makes them look a little blurred and complex when they’re looked at from a distance. This is the process of turning the text into individual shapes, interacting with the final rendering on the screen in some way that I don’t want to have to understand.

SVG files are just text files (in XML format) so we can look at the actual code (a huge advantage of SVG over other formats). Here’s the full text of the SVG generated by CairoSVG:































  





  
  
  
  
  
  
  
  
  
  
  



… and here it is for the SVG generated by svglite:




  

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)