Saving a ggplots as PNG within a loop gives me a wrong plot title for one of the plots.
See reprex below, output corresponds to what I see in RStudio plot pane.
But then, my saved PNG via ggsave()
has wrong "Sr"
title twice where one should be "Fe"
. Other two plot titles are correct.
Is this a bug or am I doing something wrong?
library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.5.1
#> Warning: package 'purrr' was built under R version 4.5.1
df <-
tribble(~var, ~x, ~y,
"Sr", 1, 3,
"Fe", 1, 2,
"Al", 1, 4)
df
#> # A tibble: 3 × 3
#> var x y
#> <chr> <dbl> <dbl>
#> 1 Sr 1 3
#> 2 Fe 1 2
#> 3 Al 1 4
for (i in unique(df$var)){
print(i)
p <-df |>
filter(var == i) |>
ggplot(aes(x, y)) +
geom_point() +
ggtitle(i)
plot(p)
ggsave(paste0("plot_", i, ".png"))
}
#> [1] "Sr"
#> Saving 7 x 5 in image
#> [1] "Fe"
#> Saving 7 x 5 in image
#> [1] "Al"
#> Saving 7 x 5 in image
Created on 2025-08-18 with reprex v2.1.1
My saved "plot_Fe.png" from working directory:
Note, y = 2 is correct for Fe, but the title should not be Sr.
sessionInfo()
R version 4.5.0 (2025-04-11 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26100)
Matrix products: default
LAPACK version 3.12.1
locale:
[1] LC_COLLATE=English_United Kingdom.utf8 LC_CTYPE=English_United Kingdom.utf8 LC_MONETARY=English_United Kingdom.utf8
[4] LC_NUMERIC=C LC_TIME=English_United Kingdom.utf8
time zone: Europe/Berlin
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] lubridate_1.9.4 forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.1.0 readr_2.1.5 tidyr_1.3.1
[8] tibble_3.3.0 ggplot2_3.5.2 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] utf8_1.2.6 generics_0.1.4 stringi_1.8.7 hms_1.1.3 digest_0.6.37 magrittr_2.0.3
[7] evaluate_1.0.4 grid_4.5.0 timechange_0.3.0 RColorBrewer_1.1-3 fastmap_1.2.0 processx_3.8.6
[13] ps_1.9.1 scales_1.4.0 textshaping_1.0.1 cli_3.6.5 rlang_1.1.6 reprex_2.1.1
[19] withr_3.0.2 yaml_2.3.10 tools_4.5.0 tzdb_0.5.0 vctrs_0.6.5 R6_2.6.1
[25] lifecycle_1.0.4 fs_1.6.6 ragg_1.4.0 pkgconfig_2.0.3 callr_3.7.6 clipr_0.8.0
[31] pillar_1.11.0 gtable_0.3.6 glue_1.8.0 systemfonts_1.2.3 xfun_0.52 tidyselect_1.2.1
[37] rstudioapi_0.17.1 knitr_1.50 farver_2.1.2 htmltools_0.5.8.1 rmarkdown_2.29 labeling_0.4.3
[43] compiler_4.5.0
I just ran the code on another machine with a different config (see sessionInfo()
below) and there it does work correctly.
R version 4.4.1 (2024-06-14 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 10 x64 (build 19045)
Matrix products: default
locale:
[1] LC_COLLATE=English_United Kingdom.utf8 LC_CTYPE=English_United Kingdom.utf8 LC_MONETARY=English_United Kingdom.utf8
[4] LC_NUMERIC=C LC_TIME=English_United Kingdom.utf8
time zone: Europe/Berlin
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] lubridate_1.9.3 forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.0.2 readr_2.1.5 tidyr_1.3.1 tibble_3.2.1
[9] ggplot2_3.5.1 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] gtable_0.3.5 compiler_4.4.1 tidyselect_1.2.1 systemfonts_1.1.0 scales_1.3.0 textshaping_0.4.0 R6_2.5.1
[8] labeling_0.4.3 generics_0.1.3 munsell_0.5.1 pillar_1.9.0 tzdb_0.4.0 rlang_1.1.4 utf8_1.2.4
[15] stringi_1.8.4 timechange_0.3.0 cli_3.6.3 withr_3.0.1 magrittr_2.0.3 grid_4.4.1 rstudioapi_0.16.0
[22] hms_1.1.3 lifecycle_1.0.4 vctrs_0.6.5 glue_1.7.0 farver_2.1.2 ragg_1.3.2 fansi_1.0.6
[29] colorspace_2.1-1 tools_4.4.1 pkgconfig_2.0.3
This seems to be a bug, not related to {ggplot2}
, but to {ragg}
. The following workaround works fine:
library(tidyverse)
df <-
tribble(~var, ~x, ~y,
"Sr", 1, 3,
"Fe", 1, 2,
"Al", 1, 4)
for (i in unique(df$var)){
print(i)
p <- df |>
filter(var == i) |>
ggplot(aes(x, y)) +
geom_point() +
ggtitle({{as.symbol(i)}})
plot(p)
ggsave(paste0("plot_", i, ".png"))
}
#> [1] "Sr"
#> Saving 7 x 5 in image
#> [1] "Fe"
#> Saving 7 x 5 in image
#> [1] "Al"
#> Saving 7 x 5 in image
Created on 2025-08-18 with reprex v2.1.1