【问题标题】:Error while plotting with ggsave and other save functions使用 ggsave 和其他保存功能绘图时出错
【发布时间】:2021-01-03 19:50:37
【问题描述】:

我有关于函数 ggsave() 的问题,如果能提供任何帮助和/或建议/解决方案,我将不胜感激。我正在创建四个图并将它们全部放在一个大图中,并且由于我想使用数据框中的所有列循环整个函数,因此我想将创建的图保存在指定的文件夹中(最好使用识别名称)。

    plotting_fun3 <- function(Q){
  
  plot1 <- plot_likert(
    t(Q),
    title = "Total population",
    legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
    grid.range = c(1.6, 1.1),
    expand.grid = FALSE,
    axis.labels = c(" "),
    values = "sum.outside",
    show.prc.sign = TRUE,
    catcount = 4,
    cat.neutral = 3,
    
  )
  
  plot2 <- plot_likert(
    t(Q[survey$animal=="Dogs"]),
    title = "Female",
    legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
    grid.range = c(1.6, 1.1),
    expand.grid = FALSE,
    axis.labels = c(" "),
    values = "sum.outside",
    show.prc.sign = TRUE,
    catcount = 4,
    cat.neutral = 3,
    
  )
  
  plot3 <- plot_likert(
    t(Q[survey$animal=="Cats"]),
    title = "Male",
    legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
    grid.range = c(1.6, 1.1),
    expand.grid = FALSE,
    axis.labels = c(" "),
    values = "sum.outside",
    show.prc.sign = TRUE,
    catcount = 4,
    cat.neutral = 3,
    
  )
  
  plot4 <- plot_likert(
    t(Q[survey$animal=="Turtle"]),
    title = "Others",
    legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
    grid.range = c(1.6, 1.1),
    expand.grid = FALSE,
    axis.labels = c(" "),
    values = "sum.outside",
    show.prc.sign = TRUE,
    catcount = 4,
    cat.neutral = 3,
    
  )
  
  theplot <- ggarrange(plot1, plot2, plot3, plot4, 
                       labels = NULL,
                       common.legend = TRUE,
                       legend = "bottom",
                       ncol = 1, nrow = 4)
  
  #ggsave(filename=paste(Q,".png",sep=""), plot=theplot, device = "png")
  
  #ggsave(filename=paste("animal_plot", ID, ".jpeg"), plot=plots[[x]])
  
  #ggsave(path = "/myDirectory",
  #       device = "png", filename = "animal_plot", plot = theplot)
  
  #save_plot(filename = "hello", plot = theplot, 
  #          "/myDirectory",
  #          device = "png")

  #ggsave(sprintf("%s.pdf", Q), device = "pdf")
  
  return(theplot)
}

注释行显示了我尝试将绘图保存在我的目录中的各种方式。我遇到了 2 个不同的问题:

要么:我在堆栈溢出中发现的大多数 ggsave 建议。其中有几个不包括device = "png" 行。如果我省略这行代码,我总是会得到这样的结果:

 Fehler: `device` must be NULL, a string or a function.
Run `rlang::last_error()` to see where the error occurred. 

如果我遵循该命令,我会得到:

<error/rlang_error>
`device` must be NULL, a string or a function.
Backtrace:
 1. global::plotting_fun3(survey[, 9])
 2. ggplot2::ggsave(sprintf("%s.pdf", Q))
 3. ggplot2:::plot_dev(device, filename, dpi = dpi)
Run `rlang::last_trace()` to see the full context.
> rlang::last_trace()
<error/rlang_error>
`device` must be NULL, a string or a function.
Backtrace:
    █
 1. └─global::plotting_fun3(survey[, 9])
 2.   └─ggplot2::ggsave(sprintf("%s.pdf", Q))
 3.     └─ggplot2:::plot_dev(device, filename, dpi = dpi)

所以在网上找了有相同或类似问题的人,建议一直使用device = "png"或类似的。

现在,如果我这样做,我会遇到不同的问题: 绘图保存在正确的目录中,但名称错误。通常名称是“3.png”或“3.pdf”或取决于我创建的内容。如果“3.png”已经存在,它会给文件另一个编号。

三个月前我在一个较旧的项目中遇到了这个问题,无法解决,现在我又遇到了。

不管怎样,我使用的是 macOS Mojave 10.14.6,我的 R 版本是 1.3.1093 版

提前感谢您的任何想法、建议或其他 cmets。

[编辑]

这里是一些示例数据:

 > str(myDF[,c(2,9:10)])
 data.frame':   123 obs. of  3 variables:
 $ animal: chr  "Cats" "Cats" "Turtles" "Cats" ...
 $ q8    : int  3 5 5 3 4 4 2 5 3 5 ...
 $ q9.1  : int  4 5 5 4 3 4 2 4 2 4 ...

所有观测值的值都保持在 1 到 5 之间。它们实际上代表了诸如“非常同意”、“同意”、“既不同意也不反对”等答案。

或者,如果您更喜欢这个而不是另一个:

> myDF[,c(2,9:10)]
     animal q8 q9.1
1      Cats  3    4
2      Cats  5    5
3   Turtles  5    5
4      Cats  3    4
5   Turtles  4    3
6   Turtles  4    4
7   Turtles  2    2
8      Cats  5    4
9      Cats  3    2
10  Turtles  5    4
11  Turtles  4    3
12  Turtles  3    3
13     Dogs  3    3
14     Cats  3    3
15     Dogs  1    1
16     Dogs  1    3

【问题讨论】:

  • 我不清楚到底发生了什么。请通过添加一些示例数据使您的代码reproducible,以便我们可以实际运行和测试代码。此外,您似乎可以通过首先尝试绘制一个图来轻松解决问题。这是特定于plot_likertggarrange 的吗?您的每次尝试都会给出完全相同的错误信息吗?
  • 感谢您的快速回答。所以首先:只制作一个情节没有帮助,如果我使用 ggplot() 制作情节,我会遇到同样的问题。变量
  • 我在原帖中添加了一些数据;)
  • 主要我只是想找到一种按列名自动保存图的方法,以便区分每个调查问题。我也想过在图中写下他们的列名,但 1. 它没有做到这一点,2. 我以后无论如何都必须手动删除它。

标签: r ggplot2 sjplot ggsave


【解决方案1】:

文件名的问题是由于您使用了Q,它是文件名定义中的一个数据框,所以它会导致一些非常混乱的方式取决于您的系统如何处理文件名。

# This command result in a few long character depend on number of columns in Q.
# 4 columns w+ill result 4 long character and ggsvave will return the error
# Error: `device` must be NULL, a string or a function.
ggsave(filename=paste(Q,".png",sep=""), plot=theplot, device = "png")
  
# Again not sure what ID is here but if it was a dataframe you got
# same error with previous one.
ggsave(filename=paste("animal_plot", ID, ".jpeg"), plot=plots[[x]])

# This one it doesn't specific a file name but a directory
# ggsave will return an error:
# Error: Unknown graphics device ''
# If you specify device = "png" - error will be:
# Error in grid.newpage() : could not open file '/home/sinh' 
ggsave(path = "/myDirectory",
       device = "png", filename = "animal_plot", plot = theplot)

# Why there is a param "/myDirectory" here? and you should specify the extention
# in the file name. So the correct param is:
# filename = "/myDirectory/hello.png"
save_plot(filename = "hello", plot = theplot, 
          "/myDirectory",
          device = "png")

这是一个应该可以正常工作但您需要手动输入文件名:

character_variable <- "my_character_variable_here_"
index_number <- 20
# If you specify sep = "" then just need to use paste0
file_name <- paste0(character_variable, index_number)
ggsave(filename=paste(file_name, ".jpeg"), plot=plots[[x]], device = "png")

这是我基于你的函数的重写函数。您可以尝试一下并稍微调整一下

# df is your survey data.frame
# q_column_name is the name of questionare column that you want to graph.
# the final output file will use q_column_name as file name.
plotting_fun3 <- function(df, q_column_name){
  
  require(foreach)
  require(dplyr)
  require(tidyr)
  
  graph_data <- df %>% select(one_of("animal", q_column_name))
  
  plot1 <- plot_likert(
    t(graph_data),
    title = "Total population",
    legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
    grid.range = c(1.6, 1.1),
    expand.grid = FALSE,
    axis.labels = c(" "),
    values = "sum.outside",
    show.prc.sign = TRUE,
    catcount = 4,
    cat.neutral = 3,
  )
  
  animal_plots <- foreach(current_animal = c("Dog", "Cats", "Turtle")) %do% {
    plot_likert(
      t(graph_data %>% filter(animal == current_animal)),
      title = "Female",
      legend.labels = c("strongly disagree","disagree", "neither nor", "agree", "strongly agree"),
      grid.range = c(1.6, 1.1),
      expand.grid = FALSE,
      axis.labels = c(" "),
      values = "sum.outside",
      show.prc.sign = TRUE,
      catcount = 4,
      cat.neutral = 3
    )
  }
  
  theplot <- ggarrange(plot1, animal_plots[[1]],
                       animal_plots[[2]], animal_plots[[3]], 
                       labels = NULL,
                       common.legend = TRUE,
                       legend = "bottom",
                       ncol = 1, nrow = 4)
  
  ggsave(filename=paste(q_column_name, ".png",sep=""), plot=theplot, device = "png")
  
  return(theplot)
}

这里是如何使用该功能

# Assume that your survey dataframe variable is myDF
my_new_plot <- plotting_fun3(df = myDF, q_column_name = "q8")

[更新] - 增加了解决图表问题的功能。

【讨论】:

  • 嗨!感谢你的付出!。由于我对您使用的某些功能不是很了解,我应该如何输入功能输入?我试过 plotting_fun3(df[,9], q_column_name = "q8") 但它没有用,我做错了什么?你会如何建议我在 lapply 中使用它?我应该制作一个列名向量以便 lapply 使用所有正确的名称吗?假设我想要 df[,9:11] 和 col_names 的图是 c("q8","q9.1","q9.2") 你认为你的函数可以这样工作吗?当我有两个需要循环的输入时,我以前从未使用过 lapply
  • 谢谢@SinhNguyen!我现在使用了您创建两个未知数的函数的想法(将文件名作为自己的变量),但使用了我的旧函数。它确实适用于奇异图,但我无法使用两个输入使其与 lapply() 一起使用。但是我找到了一个不同的解决方案。我将旧函数与 lapply 一起使用,然后我从临时文件中访问绘图,对它们进行排序并根据列名向量命名它们,如下所示: plot_names
【解决方案2】:

对于在不太复杂的设置中遇到类似问题的任何人:仔细检查您是否将有效的路径/文件名字符串传递给ggsave()

就我而言,我在使用str_split() 和路径连接进行字符串处理时犯了一个错误。因此,ggsave() 没有给出有效的单字符串路径,提示 Error: 'device' must be NULL, a string or a function. 该错误与我的“设备”无关,但我根本没有传递正确的字符串。一旦我修复了路径,问题就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多