usando glifos Unicode ‘dingbat-like’ en gráficos R, en dispositivos y plataformas, especialmente en PDF

Algunos de ustedes pueden haber visto mi publicación en el blog sobre este tema, donde escribí el siguiente código después de querer ayudar a un amigo a producir círculos medio llenos como puntos en un gráfico:

TestUnicode <- function(start="25a0", end="25ff", ...) { nstart <- as.hexmode(start) nend <- as.hexmode(end) r <- nstart:nend s <- ceiling(sqrt(length(r))) par(pty="s") plot(c(-1,(s)), c(-1,(s)), type="n", xlab="", ylab="", xaxs="i", yaxs="i") grid(s+1, s+1, lty=1) for(i in seq(r)) { try(points(i%%s, i%/%s, pch=-1*r[i],...)) } } TestUnicode(9500,9900) 

Esto funciona (es decir, produce una cuadrícula casi completa de símbolos de dingbatty geniales):

  • en Ubuntu 10.04, en un dispositivo X11 o PNG
  • en la distribución de Mandriva Linux, los mismos dispositivos, con R construido localmente, una vez que se instaló pango-devel

Falla en diversos grados (es decir, produce una rejilla parcial o totalmente llena de puntos o rectangularjs vacíos), ya sea en silencio o con advertencias:

  • en la misma máquina Ubuntu 10.04 en PDF o PostScript (intenté configurar font = “NimbusSan” para usar fonts URW, no ayuda)
  • en MacOS X.6 (cuarzo, X11, El Cairo, PDF)

Por ejemplo, probando todas las familias de fonts de PDF disponibles:

 flist <- c("AvantGarde", "Bookman","Courier", "Helvetica", "Helvetica-Narrow", "NewCenturySchoolbook", "Palatino", "Times","URWGothic", "URWBookman", "NimbusMon", "NimbusSan", "NimbusSanCond", "CenturySch", "URWPalladio","NimbusRom") for (f in flist) { fn <- paste("utest_",f,".pdf",sep="") pdf(fn,family=f) TestUnicode() title(main=f) dev.off() embedFonts(fn) } 

en Ubuntu, ninguno de estos archivos contiene los símbolos.

Sería bueno hacer que funcione en tantas combinaciones como sea posible, pero especialmente en algunos formatos de vectores y dobles, especialmente en PDF.

Cualquier sugerencia sobre las configuraciones de fuente / dispositivo de gráficos que harían que esto funcione sería bienvenida.

Creo que no tienes suerte, Ben, ya que, según algunas notas de Paul Murrell, el pdf() solo puede manejar codificaciones de un solo byte. Las codificaciones de múltiples bytes deben convertirse a un equivalente de un solo byte, y ahí reside el problema; por definición, las codificaciones de un solo byte no pueden contener todos los glifos que se pueden representar en una encoding multibyte como UTF-8, por ejemplo.

Las notas de Paul se pueden encontrar aquí donde sugiere un par de soluciones usando dispositivos PDF basados ​​en Cairo, utilizando cairo_pdf() en sistemas Linux y Mac OS dotados adecuadamente, o mediante el paquete Cairo bajo MS Windows.

He encontrado que el dispositivo cairo_pdf es completamente insuficiente: la salida es marcadamente diferente de la representación en pdf y en pantalla, y su soporte de diagtwigción es incompleto.

Sin embargo, hay una solución bastante simple en OS X: use el dispositivo de quartz “normal” y configure su type en pdf :

 quartz(type = 'pdf', file = 'output.pdf') 

Desafortunadamente, en mi computadora esto ignora la familia de fonts y siempre usa Helvetica (aunque la documentación afirma que el valor predeterminado es Arial).

Hay al menos otros dos inconvenientes:

  • pdf convierte guiones a menos . Esto puede no ser siempre lo que quieres, pero es bastante útil para escribir correctamente los números negativos. El hilo vinculado describe soluciones para esto.
  • Por supuesto, es específico de la plataforma y solo funciona en OS X.

(Me doy cuenta de que OP menciona brevemente el dispositivo de Quartz, pero este hilo se ve con frecuencia y creo que esta solución necesita más protagonismo).

Otra solución podría ser utilizar tikzDevice, que ahora puede usar XeLaTeX con caracteres Unicode. El archivo tex resultante se puede comstackr para producir un pdf. El problema sigue siendo que debe tener una fuente en su sistema que contenga los caracteres.

 library(tikzDevice) options(tikzXelatexPackages=c(getOption('tikzXelatexPackages'), '\\setromanfont{Courier New}')) tikz(engine='xetex',standAlone=T) TestUnicode(9500,9900) dev.off() 

La primera vez, esto tomará mucho tiempo.

¿Intentó incrustar una fuente en el PDF o incluir una para usuarios de Mac que funcionaría?