I’m working on a race bar chart using gganimate
where I show the evolution of total goals scored through each month during the season. I managed to get quite close to what I want with this output:
(The layout is awful I know it’s just to meet the requirements of the upload size on stackoverflow).
The last part I’m trying to achieve is that geom_text()
shows the intermediate values during the transitions.
For instance, instead of going from 7 directly to 12, I would like the graph to show 7,8,9,10,11 while the bar is adjusting. I’m not really sure how I can get to that result and I’ve been stuck for quite a while on this.
Here is a sample of my dataframe:
df2<-structure(list(Season = c("2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024",
"2023/2024", "2023/2024", "2023/2024", "2023/2024", "2023/2024"
), DATEMM = structure(c(2023.5, 2023.5, 2023.5, 2023.5, 2023.5,
2023.5, 2023.5, 2023.5, 2023.58333333333, 2023.58333333333, 2023.58333333333,
2023.58333333333, 2023.58333333333, 2023.58333333333, 2023.58333333333,
2023.58333333333, 2023.66666666667, 2023.66666666667, 2023.66666666667,
2023.66666666667, 2023.66666666667, 2023.66666666667, 2023.66666666667,
2023.66666666667, 2023.75, 2023.75, 2023.75, 2023.75, 2023.75,
2023.75, 2023.75, 2023.75, 2023.83333333333, 2023.83333333333,
2023.83333333333, 2023.83333333333, 2023.83333333333, 2023.83333333333,
2023.83333333333, 2023.83333333333, 2023.91666666667, 2023.91666666667,
2023.91666666667, 2023.91666666667, 2023.91666666667, 2023.91666666667,
2023.91666666667, 2023.91666666667), class = "yearmon"), League = c("Super League",
"Jupiler Pro League", "Bundesliga", "Liga", "LigaNOS", "Ligue 1",
"Premier League", "Serie A", "Super League", "Premier League",
"LigaNOS", "Ligue 1", "Liga", "Bundesliga", "Serie A", "Jupiler Pro League",
"Liga", "Premier League", "LigaNOS", "Bundesliga", "Super League",
"Serie A", "Ligue 1", "Jupiler Pro League", "Liga", "Premier League",
"Bundesliga", "LigaNOS", "Serie A", "Super League", "Ligue 1",
"Jupiler Pro League", "Premier League", "Liga", "Bundesliga",
"Serie A", "LigaNOS", "Super League", "Ligue 1", "Jupiler Pro League",
"Premier League", "Liga", "Bundesliga", "Serie A", "LigaNOS",
"Ligue 1", "Super League", "Jupiler Pro League"), goals = c(36,
21, 0, 0, 0, 0, 0, 0, 94, 86, 85, 85, 80, 65, 52, 38, 210, 206,
185, 158, 155, 148, 137, 84, 312, 300, 271, 246, 237, 217, 212,
139, 401, 392, 353, 314, 292, 290, 267, 207, 607, 479, 454, 429,
392, 358, 339, 316), rank = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), image_file = c("~/lglogos/Super League.png",
"~/lglogos/Jupiler Pro League.png", "~/lglogos/Bundesliga.png",
"~/lglogos/Liga.png", "~/lglogos/LigaNOS.png", "~/lglogos/Ligue 1.png",
"~/lglogos/Premier League.png", "~/lglogos/Serie A.png", "~/lglogos/Super League.png",
"~/lglogos/Premier League.png", "~/lglogos/LigaNOS.png", "~/lglogos/Ligue 1.png",
"~/lglogos/Liga.png", "~/lglogos/Bundesliga.png", "~/lglogos/Serie A.png",
"~/lglogos/Jupiler Pro League.png", "~/lglogos/Liga.png", "~/lglogos/Premier League.png",
"~/lglogos/LigaNOS.png", "~/lglogos/Bundesliga.png", "~/lglogos/Super League.png",
"~/lglogos/Serie A.png", "~/lglogos/Ligue 1.png", "~/lglogos/Jupiler Pro League.png",
"~/lglogos/Liga.png", "~/lglogos/Premier League.png", "~/lglogos/Bundesliga.png",
"~/lglogos/LigaNOS.png", "~/lglogos/Serie A.png", "~/lglogos/Super League.png",
"~/lglogos/Ligue 1.png", "~/lglogos/Jupiler Pro League.png",
"~/lglogos/Premier League.png", "~/lglogos/Liga.png", "~/lglogos/Bundesliga.png",
"~/lglogos/Serie A.png", "~/lglogos/LigaNOS.png", "~/lglogos/Super League.png",
"~/lglogos/Ligue 1.png", "~/lglogos/Jupiler Pro League.png",
"~/lglogos/Premier League.png", "~/lglogos/Liga.png", "~/lglogos/Bundesliga.png",
"~/lglogos/Serie A.png", "~/lglogos/LigaNOS.png", "~/lglogos/Ligue 1.png",
"~/lglogos/Super League.png", "~/lglogos/Jupiler Pro League.png"
)), row.names = c(NA, -48L), class = c("tbl_df", "tbl", "data.frame"
))
And here is my code for the graph:
colpal<-c('Ligue 1'="#E5174F",'Premier League' ="#99CBE7", 'Liga' = "#122623", 'Bundesliga' = "#00bbf9ff", 'Serie A' ="#3469A6",
"LigaNOS" = "#5EB1BF","Jupiler Pro League" ="#F6AE2D","Super League" = "#B3001B")
colpal.order<-c('Ligue 1','Premier League', 'Liga', 'Bundesliga', 'Serie A',"LigaNOS","Jupiler Pro League",
"Super League")
gfb<-ggplot(df2, aes(rank,group=League,fill=factor(League,levels = colpal.order),
color = as.factor(League)))+
geom_tile(aes(y=goals/2,x=rank,height=goals,width = 0.5),alpha = 0.8, color = NA) +
ggtext::geom_richtext(
aes(
y = 0,
x = rank,
label = sprintf("<img src='%s' width='70'/>", image_file)),
hjust = 1,
inherit.aes = FALSE,
fill = NA,
color = NA,
label.padding = grid::unit(30, "pt"))+
scale_fill_manual(values = colpal)+
scale_color_manual(values = colpal) +
coord_flip(clip="off",expand=FALSE) +
scale_y_continuous(labels = scales::comma) +
scale_x_reverse()+
geom_text(aes(y=goals, label= ifelse(goals > 0, sprintf("%1.0f", goals), "")),
color="white",fontface = "bold", size = 20,family="Archivo Black",vjust = 0.5, hjust = 1)+
guides(color = guide_none())+
theme_minimal()+
theme( panel.grid = element_blank(),
panel.grid.major.x = element_line( linewidth = .5, color="#122623"),
panel.background = element_rect(colour = NA,fill="transparent"),
legend.position = "none",
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_text(size=20,face = 'bold'),
plot.margin = margin(8, 6, 8, 6, "cm"),
plot.background = element_rect(fill = "#ffffff", color = NA),
plot.title = element_text(size = 28, hjust = 0.5, face = 'bold', color = "#21FA90", vjust = 5,family="Archivo Black"),
plot.subtitle = element_text(size = 17.5, hjust = 0.5, face = "italic", color = "grey", vjust = 5,family="Archivo Black"),
plot.caption = element_text(size = 12.5, color = "grey", vjust = 0,family="Archivo Black"),
)
anim <- gfb +
transition_states(DATEMM, state_length = 0) +
view_follow(
fixed_y = c(0, NA),
fixed_x = TRUE,
)+
enter_grow() +
exit_shrink() +
ease_aes('linear') +
labs( title = "Goal scored this season",
subtitle = 'Month: {closest_state}',
caption = 'Source: Hedgeflare calculation')
anim
animate(anim, fps = 10, duration =07, width = 500, height = 1000, renderer = gifski_renderer("gganim1.gif"))
Thanks a lot for your insight.