trevorld / ggpattern

ggplot geoms with pattern fills
https://trevorldavis.com/R/ggpattern/dev/
Other
359 stars 18 forks source link

poppler (cairo) backend pdf viewer bug when viewing 'pdf()' device output with alpha masks #70

Closed trevorld closed 2 years ago

trevorld commented 2 years ago
library(ggplot2)
library(sf)
library(rnaturalearth)
library(ggpattern)

shapefile <- ne_countries(continent = 'europe', returnclass = "sf", scale = 110)

options(ggpattern_use_R4.1_masks = TRUE)
pdf("mask_bug.pdf")
ggplot(shapefile) +
  geom_sf_pattern(aes(geometry = geometry, fill = name, pattern_fill = name),
                  size = 4, 
                  pattern = "stripe") +
  xlim(-10, 30) +
  ylim( 37, 60) +
  theme_bw() +
  theme(legend.position = 'none')
dev.off()

pdf_masking_bug

Workarounds

trevorld commented 2 years ago

Apparently this is a pdf viewer bug in evince (my default pdf viewer) and not a bug in the pdf file. The pdf looks fine in other pdf viewers such as firefox and okular and reportedly xpdf and chrome.

trevorld commented 2 years ago

More minimal example of pdf output to explore pdf viewer bug with alpha masks:

library("grid")

x <- c(0.1, 0.9, 0.9, 0.1, 0.1, 0.3, 0.7, 0.7, 0.3, 0.3)
y <- c(0.1, 0.1, 0.9, 0.9, 0.1, 0.3, 0.3, 0.7, 0.7, 0.3)
id.lengths <- c(5L, 5L)
rule <- "evenodd"
gp <- gpar(fill = "black", lwd = 0L)
masker <- pathGrob(x, y, id.lengths = id.lengths, rule = "evenodd", gp = gp)

masked <- rectGrob(height = unit(0.7, "npc"),
                   gp = gpar(fill = "yellow", lwd = 4, col = "blue"),
                   vp = viewport(mask = masker))

grDevices::pdf("mask_bug.pdf")
grid.draw(masked)
dev.off()

Looking at the output of pdftocairo -png -f 1 -l 1 mask_bug.pdf -o cairo-output and pdftoppm -png -f 1 -l 1 mask_bug.pdf -o splash-output it appears that the bug is in poppler's "cairo" backend and not poppler's "splash" backend. This is why the pdf looks fine in okular (uses poppler's "splash" backend) but not evince (uses poppler's "cairo" backend) even though both use poppler as their pdf backend.

trevorld commented 2 years ago

Bug reported upstream to poppler: https://gitlab.freedesktop.org/poppler/poppler/-/issues/1202

kongdd commented 2 years ago

Is this problem solved?

trevorld commented 2 years ago

Is this problem solved?

kongdd commented 2 years ago

@trevorld Thanks for your detailed explanation.

kongdd commented 2 years ago

I need a line pattern. Any idea how to make it?

trevorld commented 2 years ago

1.1, 2.1, 2.2 - Yes, the non-alpha mask alternative is a rasterGrob() approximation. However you can increase the resolution via the pattern_res aesthetic or alternatively by setting the ggpattern_res option via options().

1.2 - The cairo_pdf() alpha mask error should theoretically go away if you upgrade to R 4.2

kongdd commented 2 years ago

Thanks for your solution. R 4.2 is not available on the official website. Do you know how to upgrade to 4.2? I am using ubuntu and win10.

trevorld commented 2 years ago
trevorld commented 2 years ago

Also {svglite} recently added support for the R 4.1 alpha masking feature. If you really need a vectorized image format could try saving an "svg" file with svglite::svglite() and then converting to pdf...