如何使用gganimate获取完整而非局部的饼图 [英] How to get complete, rather than partial, pie charts using gganimate

查看:363
本文介绍了如何使用gganimate获取完整而非局部的饼图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 gganimate ggplot 制作动画饼图时遇到问题。



我想每年都有普通的派,但是我的输出是完全不同的。



你可以看到一个使用 mtcars

  library(ggplot2)
library(gganimate)


#有些数据

df< -aggregate(mtcars $ mpg,list(mtcars $ cyl,mtcars $ carb),sum)
colnames (df)<-c(X,Y,Z)

bp < - ggplot(df,aes(x =,y = Z,fill = X, frame = Y))+
geom_bar(width = 1,stat =identity)+ coord_polar(y,start = 0)

gganimate(pie,output.gif )

这是输出:



你对这个问题有了解吗?提前致谢!新年快乐!

解决方案

ggplot代码为 df中的每一行创建一个单独的堆叠条形图。 code>。使用 coord_polar ,这将成为数据框中每行都有楔形的单个饼图。然后,当您使用 gg_animate 时,每个框架仅包含对应于给定等级 Y 的楔子。这就是为什么你每次只得到完整饼图的一部分。



如果您想为每个 Y 级别设置一个完整的饼图,那么一个选项是创建一个单独的每个级别 Y 的饼图,然后将这些饼图组合成一个GIF。以下是一些假数据的示例(我希望)与您的真实数据类似:

 库(动画)

假数据
set.seed(40)
df = data.frame(Year = rep(2010:2015,3),
disease = rep(c( (c(1,1.5,2),函数(i)cumsum(c(1000 * i,sample()), (-200 * i):( 200 * i),5)))))

saveGIF({
for(i in unique(df $ Year)){
p = ggplot(df [df $ Year == i,],aes(x =,y = count,fill = disease,frame = Year))+
geom_bar(width = 1,stat =identity )+
facet_grid(〜Year)+
coord_polar(y,start = 0)
print(p)
}
},movie.name = test1.gif)



以上GIF的饼都大小相同。但你也可以根据 count 的总和,改变 Year 的每个级别的饼的大小从



如果我可以编辑尽管动画很酷(但饼图不太酷,所以也许动画化一大堆饼图只是增加了对伤害的侮辱),但数据可能会更容易理解一个普通的旧静态线条图。例如:

  ggplot(df,aes(x = Year,y = count,color = disease))+ 
geom_line()+ geom_point()+
scale_y_continuous(limits = c(0,max(df $ count)))



或者,也许这样:

  ggplot(df,aes(x = Year,y = count,color = disease))+ 
geom_line()+ geom_point(show.legend = FALSE)+
geom_line(data = df%>%group_by(Year)%>%mutate(count = sum(count)),
aes(x = Year,y = count,color =All ),lwd = 1)+
scale_y_continuous(限制= c(0,df%>%group_by(年)%>%
汇总(count = sum(count))%>%max (。$ count)))+
scale_colour_manual(values = c(black,hcl(seq(15,275,length = 4)[1:3],100,65)))


I have a problem when doing an animated pie chart with gganimate and ggplot.

I want to have normal pies each year, but my output is totally different.

You can see an example of the code using mtcars:

library(ggplot2)
library(gganimate)


#Some Data

df<-aggregate(mtcars$mpg, list(mtcars$cyl,mtcars$carb), sum)
colnames(df)<-c("X","Y","Z")

bp<- ggplot(df, aes(x="", y=Z, fill=X, frame=Y))+
geom_bar(width = 1, stat = "identity") + coord_polar("y", start=0)

gganimate(pie, "output.gif")

An this is the output:

It works well when the frame has only one level:

Do you have an idea about the problem? Thanks in advance! and happy New Year!

解决方案

The ggplot code creates a single stacked bar chart with a section for every row in df. With coord_polar this becomes a single pie chart with a wedge for each row in the data frame. Then when you use gg_animate, each frame includes only the wedges that correspond to a given level of Y. That's why you're getting only a section of the full pie chart each time.

If instead you want a full pie for each level of Y, then one option would be to create a separate pie chart for each level of Y and then combine those pies into a GIF. Here's an example with some fake data that (I hope) is similar to your real data:

library(animation)

# Fake data
set.seed(40)
df = data.frame(Year = rep(2010:2015, 3), 
                disease = rep(c("Cardiovascular","Neoplasms","Others"), each=6),
                count=c(sapply(c(1,1.5,2), function(i) cumsum(c(1000*i, sample((-200*i):(200*i),5))))))

saveGIF({
  for (i in unique(df$Year)) {
    p = ggplot(df[df$Year==i,], aes(x="", y=count, fill=disease, frame=Year))+
      geom_bar(width = 1, stat = "identity") + 
      facet_grid(~Year) +
      coord_polar("y", start=0) 
    print(p)
  }
}, movie.name="test1.gif")

The pies in the GIF above are all the same size. But you can also change the size of the pies based on the sum of count for each level of Year (code adapted from this SO answer):

library(dplyr)

df = df %>% group_by(Year) %>% 
  mutate(cp1 = c(0, head(cumsum(count), -1)),
         cp2 = cumsum(count))

saveGIF({
  for (i in unique(df$Year)) {
    p = ggplot(df %>% filter(Year==i), aes(fill=disease)) +
      geom_rect(aes(xmin=0, xmax=max(cp2), ymin=cp1, ymax=cp2)) + 
      facet_grid(~Year) +
      coord_polar("y", start=0) +
      scale_x_continuous(limits=c(0,max(df$cp2)))
    print(p)
  }
}, movie.name="test2.gif")

If I can editorialize for a moment, although animation is cool (but pie charts are uncool, so maybe animating a bunch of pie charts just adds insult to injury), the data will probably be easier to comprehend with a plain old static line plot. For example:

ggplot(df, aes(x=Year, y=count, colour=disease)) +
  geom_line() + geom_point() +
  scale_y_continuous(limits=c(0, max(df$count)))

Or maybe this:

ggplot(df, aes(x=Year, y=count, colour=disease)) +
  geom_line() + geom_point(show.legend=FALSE) +
  geom_line(data=df %>% group_by(Year) %>% mutate(count=sum(count)), 
            aes(x=Year, y=count, colour="All"), lwd=1) +
  scale_y_continuous(limits=c(0, df %>% group_by(Year) %>% 
                                summarise(count=sum(count)) %>% max(.$count))) +
  scale_colour_manual(values=c("black", hcl(seq(15,275,length=4)[1:3],100,65)))

这篇关于如何使用gganimate获取完整而非局部的饼图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆