Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何使用动画ggplot2 plot管理并行处理?_R_Animation_Ggplot2_Parallel Processing_Snowfall - Fatal编程技术网

R 如何使用动画ggplot2 plot管理并行处理?

R 如何使用动画ggplot2 plot管理并行处理?,r,animation,ggplot2,parallel-processing,snowfall,R,Animation,Ggplot2,Parallel Processing,Snowfall,我正试图用ggplot2和magick构建一个动画条形图,它在“每天”的基础上不断增长。不幸的是,我的数据集中有成千上万的条目(几年来每天的日期和不同的类别),这使得处理速度非常慢。因此,我使用snow包来加快处理时间。 但是,在集群中拆分数据并调用ggplot()时,我遇到了麻烦 magick需要为动画分割每个日期的数据,snow需要为并行处理分割每个集群的数据。因此,我得到了一个列表列表,当调用clusterApply()中的ggplot()时会出现问题。列表的结构当然取决于我拆分数据的顺序

我正试图用
ggplot2
magick
构建一个动画条形图,它在“每天”的基础上不断增长。不幸的是,我的数据集中有成千上万的条目(几年来每天的日期和不同的类别),这使得处理速度非常慢。因此,我使用
snow
包来加快处理时间。 但是,在集群中拆分数据并调用
ggplot()
时,我遇到了麻烦

magick
需要为动画分割每个日期的数据,
snow
需要为并行处理分割每个集群的数据。因此,我得到了一个列表列表,当调用
clusterApply()
中的
ggplot()
时会出现问题。列表的结构当然取决于我拆分数据的顺序(请参见示例代码中的版本1和版本2),但还没有哪个版本能够成功。 我假设使用
data$date
时无法访问列表元素,因为现在列表中有更多级别

所以,我的问题是:通过这种方式使用并行处理,是否可以通过
ggplot2
构建动画图形

下面是将我的问题可视化的示例代码(我尽可能多地构造它):

########################################################################
#设置
########################################################################
图书馆(平行)
图书馆(雪)
图书馆(GG2)
图书馆(magick)
#创建一年的一些样本数据
#4类;每个类别每天都有一个特定的值
种子(1)
因此,我的解决方案是:

  • ncores
    期间中拆分日期

  • 获取每个时段的绘图,并将其保存为GIF格式

  • 读回所有GIF并合并它们


########################################################################
#设置
########################################################################
#创建一年的一些样本数据
#4类;每个类别每天都有一个特定的值
种子(1)
x%
变异(日期=as.character(日期))%>%
组别(类别)%>%
变异(总和=总和(值))
我会的

library(tidyverse)
library(gganimate)
x %>% 
  as.tibble() %>% 
  arrange(date) %>%  
  group_by(category) %>% 
  mutate(Sum=cumsum(value)) %>% 
  ggplot(aes(category, Sum, fill = category)) +
  geom_col(position = 'identity') + 
  ggtitle("{frame_time}") +
  transition_time(date) +
  ease_aes('linear') 
anim_save("GIF.gif")  


如果数据太多,我建议将转换时间增加到几个月而不是几天

动画是如何工作的?你能给它一张地图的清单吗?是的。从上面的代码调用
out
时,您会得到一个绘图列表<代码>>类(输出)[1]“列表”
那么为什么要使用
打印
?这里有什么问题?你是对的,
print()
不是必需的。不过,这并不能解决我的问题。为了提高性能,我需要使用并行处理来处理我的绘图。我更新了代码并包含了一个使用
snowfall
的版本,该版本似乎有效,但没有生成绘图。另请参见。也感谢您对我的旧问题的回答!与Parralel版本相比,我必须测试它的速度,但它可能要快得多。
########################################################################
# snowfall version
########################################################################
library(parallel)
library(snowfall)
library(ggplot2)
library(magick)

# creating some sample data for one year
# 4 categories; each category has a specific value per day
set.seed(1)
x <- data.frame(
  rep(as.Date((Sys.Date()-364):Sys.Date(), origin="1970-01-01"),4),
  c(rep("cat01",length.out=365),
    rep("cat02",length.out=365),
    rep("cat03",length.out=365),
    rep("cat04",length.out=365)),
  sample(0:50,365*4, replace=TRUE)
)
colnames(x) <- c("date", "category", "value")
x$category <- factor(x$category)

# creating a cumulative measure making the graphs appear "growing"
x$cumsum <- NA
for(i in levels(x$category)){
  x$cumsum[x$category == i] <- cumsum(x$value[x$category == i])
}
x <- x[order(x$date),]

# number of cores
cores <- detectCores()

# clustering
sfInit(parallel = TRUE, cpus = cores, type = "SOCK")

# splitting data for plotting
datalist <- split(x, x$date)

# making everything accessible in the cluster
sfExportAll()
sfLibrary(ggplot2)
sfLibrary(magick)

# opening magick-device
img <- image_graph(1000, 700, res = 96)

# plotting
out <- sfLapply(datalist, function(data){
  plot <- ggplot(data)+
    geom_bar(aes(category, cumsum), stat = "identity")+
    # holding breaks and limits constant per plot
    scale_y_continuous(expand = c(0,0), 
                       breaks = seq(0,max(x$cumsum)+500,500), 
                       limits = c(0,max(x$cumsum)+500))+
    ggtitle(data$date)
plot
})
dev.off()

# animation
animation <- image_animate(img, fps = 5)
animation
img <- image_graph(1000, 700, res = 96)
out
dev.off()
animation <- image_animate(img, fps = 5)
animation
########################################################################
# setup
########################################################################

# creating some sample data for one year
# 4 categories; each category has a specific value per day
set.seed(1)
x <- data.frame(
  rep(as.Date((Sys.Date()-364):Sys.Date(), origin="1970-01-01"),4),
  c(rep("cat01",length.out=365),
    rep("cat02",length.out=365),
    rep("cat03",length.out=365),
    rep("cat04",length.out=365)),
  sample(0:50,365*4, replace=TRUE)
)
colnames(x) <- c("date", "category", "value")

# creating a cumulative measure making the graphs appear "growing"
library(dplyr)
x <- x %>%
  as_tibble() %>%
  arrange(date) %>%
  mutate(date = as.character(date)) %>%
  group_by(category) %>%
  mutate(cumsum = cumsum(value))

y_max <- max(x$cumsum) + 500

library(doParallel)

all_dates <- unique(x$date)
ncores <- detectCores() - 1
ind_cluster <- sort(rep_len(1:ncores, length(all_dates)))
date_cluster <- split(all_dates, ind_cluster)
registerDoParallel(cl <- makeCluster(ncores))

tmp <- tempfile()

files <- foreach(ic = 1:ncores, .packages = c("tidyverse", "magick")) %dopar% {

  img <- image_graph(1000, 700, res = 96)

  x %>%
    filter(date %in% date_cluster[[ic]]) %>%
    group_by(date) %>%
    do(
      plot = ggplot(.) +
        geom_col(aes(category, cumsum)) +
        scale_y_continuous(expand = c(0, 0), 
                           breaks = seq(0, y_max, 500), 
                           limits = c(0, y_max))
    ) %>%
  pmap(function(date, plot) {
    print(plot + ggtitle(date))
    NULL
  })

  dev.off()

  image_write(image_animate(img, fps = 5), paste0(tmp, ic, ".gif"))
}
stopCluster(cl)

test <- do.call(c, lapply(files, magick::image_read))
test
library(tidyverse)
library(gganimate)
x %>% 
  as.tibble() %>% 
  arrange(date) %>%  
  group_by(category) %>% 
  mutate(Sum=cumsum(value)) %>% 
  ggplot(aes(category, Sum, fill = category)) +
  geom_col(position = 'identity') + 
  ggtitle("{frame_time}") +
  transition_time(date) +
  ease_aes('linear') 
anim_save("GIF.gif")