-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Inconsistent expression and font rendering between ggsave(cairo_pdf) and Cairo::CairoPDF + grid.draw() #6480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
For those of us without eyes trained to spot kerning problems, can you point out where this goes wrong? As an aside:
This should not work. One shouldn't be able to put naked expressions into ggplot2 because they are not vectors. You can use |
Thanks for the example, yeah that is much clearer and objectively terrible. It is different than what I get on my local machine. What version of R and what platform are you using? As I cannot locally reproduce, does this give you the same problem? library(grid)
txt <- textGrob(expression('example formula: '*alpha^{2} + beta), 0.5, 0.5)
grDevices::cairo_pdf("grDevices_cairo.pdf")
grid.newpage()
grid.draw(txt)
dev.off()
Cairo::CairoPDF("Cairo_cairo.pdf")
grid.newpage()
grid.draw(txt)
dev.off() |
I kind of remember that on a previous platform running Debian 10, things worked properly but I have changed my config recently and can't manage to make it works. > sessionInfo()
R version 4.4.3 (2025-02-28)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 24.04.2 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
locale:
[1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
[3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=fr_FR.UTF-8
[5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
[7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
time zone: Europe/Paris
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.4.3 So the But if I use the first way of plotting with |
Thanks for checking this out! So it does seem that the problem isolates to a ggplot2 if the grDevices cairo renders plain grid normally, but bungles ggplot2 text. Unfortunately, this is hard for me to debug for me personally. Maybe @thomasp85 has been tortured enough by text rendering at this point that he has a glimpse on what might be going on. |
Ok I got my hands on an R session running on a Linux machine and can now reproduce the issue myself. txt <- textGrob(
expression('example formula: '*alpha^{2} + beta),
x = 0.5, y = 0.5,
gp = gpar(fontsize = 3)
) It 'feels' like the device is trying to pixel-snap the letters and gets weird kerning that way, but it wouldn't make sense to pixel-snap in a vector graphic. In any case, ggplot2 wouldn't be able to fix this problem if it is an issue with the device, so I'm leaning towards closing it. |
I think the reason you are seeing this is because you are sizing your text extremely small (1.5pt). While glyphs can be scaled down indefinitely, their kerning value and dimensions are aware of the underlying pixel grid and will snap to specific fractional values. This is usually never an issue, except when you render text at the size where these fractional values are a meaningful proportion of the glyph size. There is nothing ggplot2 can do about this. |
(was responding while Teun posted - we are in agreement on the larger parts) |
(the reason why you see better kerning in one over the other is probably that the "correct" looking one is calculating glyph positions at a higher resolution than the other (e.g. 72ppi vs 300ppi)) |
OK, thanks @thomasp85 and @teunbrand for your time. But what should I do, since I'm still having problems with these plots ? library(ggplot2)
library(grid)
# example 1
txt = ggplot() + theme_void() +
annotate("text",
x=0.5, y=0.5, size=1.5,
label="'example formula: '*alpha^{2} + beta",
parse=TRUE) +
scale_x_continuous(limits=c(0, 1),
expand=c(0, 0)) +
scale_y_continuous(limits=c(0, 1),
expand=c(0, 0))
# example 2
txt <- textGrob(
expression('example formula: '*alpha^{2} + beta),
x = 0.5, y = 0.5,
gp = gpar(fontsize = 3)
) Here I have expression supported but kerning issue # kerning issue but expression supported
grDevices::cairo_pdf("grDevices_cairo.pdf")
grid.newpage()
grid.draw(txt)
dev.off() And here, I don't have kerning issue but expression are not supported # no kerning issue but no expression support
Cairo::CairoPDF(file="base_cairo.pdf")
grid.newpage()
grid::grid.draw(txt)
dev.off() I need to use expressions and a small font, though perhaps not that small in practice, it's for emphasizing the issue here. But the kerning problem is still visible in my plots with expression. I don’t understand how there isn’t a solution, given that R is a scientific language. The use of mathematical expressions seems fundamental, and using smaller fonts for graphics annotations also seems like a reasonable need. Right now, I just feel stuck without a simple solution. |
I also had problems with wiggly kerning in pdf once and I fixed my problem by using |
I can understand your frustration. The "brave" solution is to bring this issue to the ones that can fix it (i.e. R Core). A hack could be to scale everything up (size of pdf along with size of text, line width etc). Or you could not use pdf but svg as Teun suggested. In any case it is outside of the hands of ggplot2 |
That is what i wanted to clarify ! Not shure that i am brave enough for that yet haha but i will definitly try to find a solution or a workaround as you suggested. Thanks again for your time ! |
Uh oh!
There was an error while loading. Please reload this page.
I encountered a kerning issue when using
ggsave()
withcairo_pdf
in R. While searching for a solution using base Cairo utilities, I ran into a problem with rendering Rexpression
.What I expected was a simple and reliable way to eliminate kerning issues while still being able to use Cairo's PDF rendering capabilities, especially for mathematical expressions in plots (by using
latex2exp
package).Here is a minimal reproducible example illustrating the issue:
Note: Rasterizing fonts using the
showtext
package is not a suitable solution in my view, as I need to keep text fully vectorized in the output PDF.The text was updated successfully, but these errors were encountered: