wilkelab / ggtext

Improved text rendering support for ggplot2
https://wilkelab.org/ggtext/
GNU General Public License v2.0
655 stars 37 forks source link

Font color not vectorized properly for strip.text #105

Closed wkumler closed 12 months ago

wkumler commented 1 year ago

I'm running into problems when I try to supply a vector of colors with strip.text = element_markdown(). It looks like only a single color is plotted, but I think that all of the colors are actually getting plotted on top of each other:

library(ggplot2)
library(ggtext)
ggplot(data.frame(x=1, y=1, facet=c(1,2))) +
  geom_point(aes(x, y)) +
  facet_wrap(~facet) +
  theme(strip.text = element_markdown(color = c("red", "blue")))

image

It seems like it's overplotting rather than vectorizing because 1) there's a halo of red around the blue number visible at high magnification and 2) the order of colors in the vector determines the final color, with the last color provided becoming the one visible on "top".

Other element_markdown options seem to work just fine (and I expected strip.text to behave similarly to others so I don't think this is expected behavior):

rgb_vec <- c("red", "blue", "green")
ggplot(data.frame(x=1, y=1, facet=c(1,2,3))) +
  geom_point(aes(x, y)) +
  facet_wrap(~facet) +
  scale_x_continuous(breaks = seq(0.95, 1.05, 0.05)) +
  theme(strip.text = element_markdown(color = rgb_vec, face = "bold"),
        axis.text.x = element_markdown(color = rgb_vec, hjust = c(0, 0.5, 1)))

image

In a very mysterious case using facet_grid with two coordinates, however, the labels on the right of the plot are colored using only(?) the first color provided in the vector, while the labels at top continue with the overplotting behavior described above (unless specified explicitly using strip.text.x and strip.text.y.

ggplot(data.frame(x=1, y=1, facet1=1:3, facet2=3:1)) +
  geom_point(aes(x, y)) +
  facet_grid(facet1~facet2) +
  theme(strip.text = element_markdown(color = c("red", "green", "blue")))

image

The conversation at https://github.com/tidyverse/ggplot2/issues/3492 implies that element_markdown is intended to handle vectorized text. The issue seems similar to the one raised here but I don't think this is a case of inheritance problems, and is maybe connected to the issue with fonts in R 4.2.0 even though I'm on 4.3.1? Is this expected behavior or am I doing something wrong in my calls to element_markdown?

> sessionInfo()
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.utf8  LC_CTYPE=English_United States.utf8   
[3] LC_MONETARY=English_United States.utf8 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

time zone: America/Los_Angeles
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggtext_0.1.2  ggplot2_3.4.2

loaded via a namespace (and not attached):
 [1] vctrs_0.6.3       cli_3.6.1         xfun_0.39         rlang_1.1.1       stringi_1.7.12   
 [6] generics_0.1.3    glue_1.6.2        labeling_0.4.2    colorspace_2.1-0  markdown_1.7     
[11] gridtext_0.1.5    scales_1.2.1      fansi_1.0.4       grid_4.3.1        munsell_0.5.0    
[16] tibble_3.2.1      lifecycle_1.0.3   stringr_1.5.0     compiler_4.3.1    dplyr_1.1.2      
[21] Rcpp_1.0.11       pkgconfig_2.0.3   rstudioapi_0.15.0 farver_2.1.1      R6_2.5.1         
[26] tidyselect_1.2.0  utf8_1.2.3        pillar_1.9.0      commonmark_1.9.0  magrittr_2.0.3   
[31] tools_4.3.1       withr_2.5.0       gtable_0.3.3      xml2_1.3.5
teunbrand commented 12 months ago

ggplot2 doesn't officially support vectorisation through the theme elements. They way one should 'vectorise' colours is through the text itself by using HTML, though that might give some order issues:

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.3.1
library(ggtext)
#> Warning: package 'ggtext' was built under R version 4.3.1
ggplot(data.frame(x=1, y=1, facet=c("<span style = 'color:red'>1</span>",
                                    "<span style = 'color:blue'>2</span>"))) +
  geom_point(aes(x, y)) +
  facet_wrap(~facet) +
  theme(strip.text = element_markdown())

Created on 2023-10-06 with reprex v2.0.2

bwiernik commented 12 months ago

Yes theme elements aren't vectorized in ggplot. Apply colors by embedding this in HTML as part of the strip title and the using element_markdown()