2
votes

When drawing labels or legends in plots, it's sometimes useful to use figure spaces, unicode U+2007, to properly align figures with a different numbers of digits. For the on-screen device, simply embedding \u2007 in the output makes this work reasonably well (and better on Windows or with X11(type="Xlib") than with my Linux default using cairo).

plot(runif(20), ylim=c(0,1.2), pch=c("x", "o"))
legend("top", c("\u20075%", "10%"), pch=c("x", "o"))

But when I set the output device to postscript in order to create an EPS file, things break:

setEPS()
postscript()
plot(runif(20), ylim=c(0,1.2), pch=c("x", "o"))
legend("top", c("\u20075%", "10%"), pch=c("x", "o"))
dev.off()

will result in messages like this:

Warning messages:
1: In strwidth(legend, units = "user", cex = cex, font = text.font) :
  conversion failure on ' 5%' in 'mbcsToSbcs': dot substituted for <e2>

The same message gets repeated for <80> and <87> which together form the UTF-8 sequence of U+2007. The whole thing repeats three times for different function invocations.

Is there some magic which I can use to make this work? I can think of two possible approaches.

  1. One would be creating my own font encoding which makes the character accessible. But I don't know the Postscript font name for figure space, and I don't know how to find out. I also guess that I might have to choose NimbusSan or some other font which has a sufficient set of glyphs, since ancient Helvetica likely won't have that specified.

  2. The other approach I can think of would be somehow letting the postscript engine know that this is a spacing symbol and that instead of actually printing something, a suitable amount of kerning can be introduced instead. Perhaps one can do this with the right fond metric file. But where to get that?

It might well be that these two approaches have to be mixed in some fashion, that choosing a good font requires using a good font metrics file, or that to use kerning I still have to ensure some single-bit encoding which can carry that character.

1
Did you try with cairo_ps() instead of postscript()?user3710546
Anyway, my suggestion doesn't solve your problem.user3710546

1 Answers

1
votes

The following is not throwing an error:

setEPS()
cairo_ps()
plot(runif(20), ylim=c(0,1.2), pch=c("x", "o"))
legend("top", c("\u20075%", "10%"), pch=c("x", "o"))
dev.off()

Apparently, the cairo driver will define encodings based on which letters are actually used, and it knows about unicode. The name used in the encoding to denote the figure space is /uni2007.

The font in use will have to actually contain that unicode character, though, so you might have to specify a suitable font using the family parameter. Otherwise cairo will silently substitute a suitable replacement character, which in this case is a “normal” space, U+0020.