Reputation: 401
I'm currently working with gganimate, and I can't find a way to properly order the bars of a barplot. I want to represent a mean by country, with an animation by year. I think I found how to do (see below), but I can't find how to order (and reorder) the country every year. I give an example below.
I tried with fct_reorder(), but I can't even get one year with the right order.
I'd like to see my bars switching order with the years.
d <- tibble(country = as.factor(sample(c("France", "Germany", "UK"), 100, replace = TRUE)),
year = sample(c(2000, 2002, 2004, 2006), 100, replace = TRUE),
revenu = rnorm(100, mean = 1500, sd= 400))
d %>% group_by(country, year) %>%
summarise(avg_revenu = mean(revenu, na.rm = TRUE)) %>%
ggplot(aes(fct_reorder(country, avg_revenu), avg_revenu)) +
geom_bar(stat = "identity") +
coord_flip() +
transition_states(year, transition_length = 1, state_length = 1) +
ggtitle("{closest_state}")
I found this page : How does gganimate order an ordered bar time-series? but I admit I don't fully understand the process, and my "mean" issue mess with my head...
Can anyone help me with this? Thanks!
Upvotes: 1
Views: 282
Reputation: 401
Since I got my own answer, I post it here, just in case it can help someone else.
1) Ranking : the idea is to compute an "average revenu" by country and year, and then to compute the order of country by avg_revenu each year.
2) Graph : The trick is to not use a real barplot, but a geom_tile instead.
#example constitution
d <- tibble(
country = as.factor(sample(
c("France", "Germany", "UK"), 100, replace = TRUE
)),
year = sample(c(2000, 2002, 2004, 2006), 100, replace = TRUE),
revenu = rnorm(100, mean = 1500, sd = 400)
)
#ranking
d2 <- d %>% group_by(country, year) %>% summarise(avg_revenu = mean(revenu, na.rm = TRUE)) %>% arrange(year, avg_revenu) %>% group_by(year) %>% mutate(order = min_rank(avg_revenu) * 1.0) %>% ungroup()
#animation object
anim <- d2 %>%
ggplot(aes(order, group = country)) +
geom_tile(aes(
y = avg_revenu / 2,
height = avg_revenu,
width = 0.9
), fill = "grey50") +
theme(axis.text.y = element_blank(), axis.title.y = element_blank()) +
scale_y_continuous(name = "Average revenu", breaks = c(0,500,1000,1500), limits = c(-500,NA)) +
transition_states(year, transition_length = 1, state_length = 3) +
geom_text(aes(y = 0, label = country), hjust = "right") +
coord_flip(clip = "off") +
ggtitle("{closest_state}")
#animation
animate(anim, nframes = 100)
Upvotes: 2