Home > Mobile >  Map write multiple ggplot png files using Purrrr
Map write multiple ggplot png files using Purrrr

Time:01-21

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

CodePudding user response:

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

CodePudding user response:

Your code has several issues:

  • you filter for Sepal.Length, but you actually provide the Species names, so you have to filter for Species
  • you've had a typo in versicolor
  • if you're only interested in the side effect of a function, use walk instead of map
  • for ggplots, the preferable way to save them is ggsave
library(dplyr)
library(purrr)
library(ggplot2)

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


walk(.x = c("setosa", "versicolor", "virginica"),
     .f = function(x) {
       foo <- df %>% 
         filter(Species == x) %>% 
         ggplot(aes(Sepal.Length)) 
         geom_histogram()
       
       ggsave(paste0(x," test.", "png"),
              plot = foo,
              width = 1300,
              height = 1600,
              units = "px")
       
     })
  • Related