2

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:

![enter image description here

It works well when the frame has only one level:

enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
RRuiz
  • 2,159
  • 21
  • 32
  • you can reproduce my whole code. I used `mtcars` to create the data. – RRuiz Jan 04 '17 at 08:42
  • Maybe my english is not good, but in my question i ask for a solution of the first plot, not for the second. The second is to show only how it works with one level... I do not know what is your problem with my work. You have not idea of what I am doing with this graphs and data and how they are going to be formated. But of course, you know everuthing – RRuiz Jan 04 '17 at 20:26
  • Sorry @Essberto I actually hadn't understood it right at first - may be because my English isn't perfect neither. I don't pretend to know everything, I'm just trying to guide you getting more people helping you : When I screened your question I thought you had an issue with the second plot that only displays one year, while the first one looks quite nice, and because I couldn't reproduce that seconde one, I just left my first comment. I sincerely apologize if that sounded rude to you. – HubertL Jan 04 '17 at 20:40

1 Answers1

3

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")

enter image description here

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")

enter image description here

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)))

enter image description here

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)))

enter image description here

Community
  • 1
  • 1
eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Thanks! Very nice. And thank you for your recommendation, but I need the animated pie charts for what I want. The only thing I am worried is about the animation package. I would like to do it directly with the gganimate. But thank you for the solution. – RRuiz Jan 04 '17 at 08:22
  • 1
    I agree with _animating a bunch of pie charts just adds insult to injury_ – HubertL Jan 04 '17 at 18:42
  • I think you need to know a little bit more about what i am doing before to write that... But of course, you know everything... – RRuiz Jan 04 '17 at 20:24
  • Sorry @Essberto, I can only guess what you haven't written. And pie charts aren't my piece of cake – HubertL Jan 04 '17 at 20:54