在 R 中创建 GIF 时出现帧顺序问题(库:“magick”和“purrr”)
Posted
技术标签:
【中文标题】在 R 中创建 GIF 时出现帧顺序问题(库:“magick”和“purrr”)【英文标题】:Problem with order of frames when creating a GIF in R (Libraries: "magick" and "purrr") 【发布时间】:2020-06-04 22:44:17 【问题描述】:我正在R
中创建一个 GIF 图像。首先,我使用循环在我的工作目录中创建并保存所有绘图。接下来,使用库 magick
和 purrr
我调用这些图并加入它们以创建一个 GIF。我的问题如下:
创建 GIF 时,帧的顺序不正确。每个情节的标题中都有数字大小写,因此可以看出它们的顺序不正确。这是我的代码:
# my df (result) is all possible combinations of cumulative frequency for # a 5 likert scale where each row sum is 1 along all its levels.
setwd(\myworkingdirectory...)
library(dplyr)
library(magick)
library(purrr)
values <- seq(0, 1, by=0.1)
values
df <- expand.grid(A1 = values, A2 = values, A3 = values, A4 = values, A5 = values)
df$TestSum <- rowSums(df)
result <- df[df$TestSum == 1, 1:5]
colnames(result) <- c("F1","F2","F3","F4","F5")
rownames(result) <- c(1:nrow(result))
colnames(result) <- c("F1","F2","F3","F4","F5")
> head(result)
F1 F2 F3 F4 F5
1 1.0 0.0 0 0 0
2 0.9 0.1 0 0 0
3 0.8 0.2 0 0 0
4 0.7 0.3 0 0 0
5 0.6 0.4 0 0 0
6 0.5 0.5 0 0 0
#to simplify for the example...
result <- result[seq(1,nrow(result),9),]
Likert_plots <- function(Yr)
png(filename = sprintf("%i%i.png",00,Yr))
barplot(as.matrix(result[Yr,]), ylim = c(0,1), main = paste0("Case ", Yr), ylab = "Cumulative Freq.", xlab = "Levels")
print(paste0("saving plot ", Yr))
dev.off()
for (i in 1:nrow(result))
Likert_plots(i)
list.files(pattern = "*.png", full.names = T) %>%
map(image_read) %>%
image_join() %>%
image_animate(fps=2) %>%
image_write("name.gif")
这些图的名称是正确的,我认为它们不是问题(例如:“01.png”、“02.png”...“0103.png”)我认为问题可能出在函数中调用它们,例如:list.files()
、map()
或 image_join()
。可能,这个可能的“有罪”功能不尊重订购号,而是另一个订单。如果是这样:我可以改变它吗?
感谢您对此提供的任何帮助。这里的GIF看问题。请注意,顺序遵循一些逻辑顺序: [1, 10, 100, 101, 102, 103, 2 , 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 31, 32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 50, 51 ..., 6, 60, 61 ... 7, 70, 71 ... 8, 80, 81 ...等等]
【问题讨论】:
请显示更多步骤。您如何读取文件名、使用哪个函数以及每个步骤的输出是什么?确实问题可能存在 如果您将绘图写入带有数字的文件,您必须确保您有前导零。 001, 002, 003, ... 010, 011, 012, ...., 100, 101, 102。然后它们将被正确排序。查看sprintf
以创建前导零。
代码已更新为我的所有步骤 (@Chelmy88)。此外,我尝试过使用@ricoderks 方法......(可以在上面的代码中看到)。结果是一样的。
@pgcudahy 回答对你有用吗?
刚刚试了一下,效果很好。谢谢大家。
【参考方案1】:
问题在于您的文件名。您看到的“某种逻辑顺序”来自list.files
如何对文件名进行排序。由于它们是字符串而不是数字,因此它们会根据第一个字符进行排序,然后是第二个字符,依此类推。在您的代码中,您有 png(filename = sprintf("%i%i.png",00,Yr))
,我将其简化为 purrr::map_chr(1:105, ~ sprintf("%i%i.png",00,.))
。如果你对输出进行排序(记住是一个字符串,而不是一个整数),你会得到
purrr::map_chr(1:105, ~ sprintf("%i%i.png",00,.)) %>% sort %>% head
#> [1] "01.png" "010.png" "0100.png" "0101.png" "0102.png" "0103.png"
您的 gif 的组装顺序是什么。问题是一个前导零被添加到您的所有数字前面。要获得正确的排序,请使用 stringr
中的 str_pad
添加可变数量的前导零以产生 4 位数字。 (其他选项见here)
purrr::map_chr(1:105, ~ stringr::str_pad(., 4, pad = "0")) %>% paste(".png", sep="") %>% sort %>% head
#> [1] "0001.png" "0002.png" "0003.png" "0004.png" "0005.png" "0006.png"
因此,将您的 png(filename = sprintf("%i%i.png",00,Yr))
更改为 png(filename = paste(stringr::str_pad(Yr, 4, pad = "0"), ".png", sep=""))
有一种方法仍然可以使用sprintf
,但我认为它的可读性要差得多。使用png(filename = sprintf("%04d.png",Yr))
【讨论】:
以上是关于在 R 中创建 GIF 时出现帧顺序问题(库:“magick”和“purrr”)的主要内容,如果未能解决你的问题,请参考以下文章