Search code examples
rggplot2purrr

Map write multiple ggplot png files using Purrrr


I'm trying to use the purrr map function to efficiently write many ggplot images through one call. I wrote example code that's simple for example sake. The approach I took below results in empty png files. It will write and I can open the file but it's all blank. I'm guessing something wrong in the paste0 call? Maybe there's a better way to automate the file name.

structure(list(Sepal.Length = c(5.8, 5.7, 5.7, 7, 6.9, 6.8, 7.7, 
7.7, 7.7, 7.9, 7.7), Sepal.Width = c(4, 4.4, 3.8, 3.2, 3.1, 2.8, 
3.8, 2.6, 2.8, 3.8, 3), Petal.Length = c(1.2, 1.5, 1.7, 4.7, 
4.9, 4.8, 6.7, 6.9, 6.7, 6.4, 6.1), Petal.Width = c(0.2, 0.4, 
0.3, 1.4, 1.5, 1.4, 2.2, 2.3, 2, 2, 2.3), Species = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), levels = c("setosa", 
"versicolor", "virginica"), class = "factor")), class = 
c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -11L), groups = 
structure(list(
Species = structure(1:3, levels = c("setosa", "versicolor", 
"virginica"), class = "factor"), .rows = structure(list(1:3, 
    4:6, 7:11), ptype = integer(0), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))), row.names = c(NA, -3L), class = 
c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE))

library(gapminder)

df <- dput(iris %>% 
  group_by(Species) %>% 
  top_n(3, wt = Sepal.Length))


map(.x = c("setosa", "veriscolor", "virginica"),
.f = function(x) {
  foo <- df %>% 
    filter(Sepal.Length == x) %>% 
    ggplot(aes(Sepal.Length))+
    geom_histogram()
  
  Cairo(width = 1300, height = 1600, paste0(x," test.", "png"))
  print(foo)
  dev.off()
  
  
})

output [[1]] null device 1

[[2]] null device 1

[[3]] null device 1


Solution

  • There are couple of updates required

    1. in filter replace the Sepal.Length == x with Species == x
    2. I dont see a function like Cairo, replace with ggsave
    3. when we use ggsave, it will save the plots to default location so check that folder
    4. changed the width and height of plots in ggsave

    code

    map(.x = c("setosa", "veriscolor", "virginica"),
        .f = function(x) {
          foo <- df %>% 
            filter(Species == x) %>% 
            ggplot(aes(Sepal.Length))+
            geom_histogram()
          
          ggsave(width = 14, height = 7, paste0(x," test.", "png"))
          print(foo)
          dev.off()
        })
    
    

    Created on 2023-01-20 with reprex v2.0.2

    check the default location with getwd() and in that location check the saved plots