Cannot create a BarChartRace with ggplot - r

I have a dataframe that has daily data about Covid19 (such as: total_cases,total_deaths) in European countries (there are 49 countries in total). You can see a preview here and you can have the whole dataframe here. I want to create a Bar Chart Race for the variable total_cases for all the European countries with ggplot. So, I followed the steps from this link or (this video) and I wrote the below code:
library(ggplot2)
g1 = ggplot(data = data.europe,
aes(x = as.Date(date),y = total_cases,group = location,
color = location)) + geom_line(size = 0.5) +
labs(y = "Total Cases", x = "Date") +
theme(legend.position = "bottom",legend.box = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 10))
Then I wrote the below code in order to create the dynamic plot
g1_star = ggplot(data = data.europe,
aes(x = as.Date(date),y = total_cases,group = location,
color = location)) + geom_line(aes(group = as.Date(date)),linetype=1) +
labs(y= "Total Cases", x = "Date") +
theme(legend.position = "bottom",legend.box = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 10)) +
transition_reveal(as.Date(date))
#We wil create the an animation
library(gifski)
library(gganimate)
animate(g1_star,height= 538,width = 866)
data_star = data.europe %>% group_by(as.Date(date))
However when I wrote these lines:
g1_star_anim = ggplot(data_star,aes(x = as.Date(date),
y = total_cases,
group = location,
fill = location,
color = location)) +
geom_tile(aes(height = total_cases,width = 0.9), alpha = 0.8,color = NA) +
geom_text(aes(y = 0, label = paste(location, " ")), vjust = 0.2, hjust = 1) +
scale_y_continuous(labels = scales::comma) + theme(axis.line=element_blank())
anim1 = g1_star_anim + transition_states(as.Date(date), transition_length = 4,
state_length = 1) +
view_follow(fixed_x = TRUE) +
labs(title = 'Total_cases per year')
The result is:
which isn't expected.
What should I change? Or which code should I write? Can anyone help me because I have been searching for a very long time?
Thanks in advance!

I found that this code shows the top 10 countries based on their total_cases
library(gganimate)
library(hrbrthemes)
library(tidyverse)
data.europe.not.na.star = data.europe.not.na %>%
group_by(as.Date(date)) %>%
arrange(-total_cases) %>%
mutate(rank = row_number()) %>%
filter(rank<=10)
col = c("cadetblue1","aquamarine","chocolate1","gray13","blue3","darkgoldenrod2",
"darkolivegreen1","darkorchid1","lightcoral","deeppink","greenyellow","mediumvioletred",
"midnightblue","olivedrab1","mediumaquamarine","red","seagreen1")
p = data.europe.not.na.star %>%
ggplot(aes(x = -rank,y = total_cases, group = location)) +
geom_tile(aes(y = total_cases / 2, height = total_cases,fill = location),width = 0.9) +
geom_text(aes(label = location), hjust = "right", colour = "gold",fontface = "bold",
nudge_y = -100000) +
geom_text(aes(label = scales::comma(total_cases)), hjust = "left",nudge_y = 100000,
colour = "grey30") +
coord_flip(clip="off") +
scale_fill_manual(name = 'location', values = col) +
scale_x_discrete("") +
scale_y_continuous("",labels=scales::comma) +
hrbrthemes::theme_ipsum(plot_title_size = 32, subtitle_size = 24,caption_size = 20,
base_size = 20) +
theme(panel.grid.major.y=element_blank(),
panel.grid.minor.x=element_blank(),
plot.margin = margin(1,1,1,2,"cm"),
axis.text.y=element_blank()) +
# gganimate code to transition by year:
transition_time(as.Date(date)) +
ease_aes('cubic-in-out') +
labs(title='Bar Char Race of Total Cases in Europe(Top 10)',
subtitle='Total Cases in {round(frame_time,0)}')
animate(p, nframes = 750, fps = 25, end_pause = 50, width = 1200, height = 900)
The result is here

Related

where to pass argument to radiate margin labels of a polar heatmap

This question builds on from here:
Drawing a polar heatmap
> dput(names.d)
c("0050773", "0050774", "0050775", "0050776", "0050777", "0050778",
"0050779", "0050780", "0050781", "0050782", "0050783", "0050784",
"0050785", "0050786", "0050787", "0050788", "0050789", "0050790",
"0050808", "0050809", "0050810", "0050811", "0050812", "0050813",
"0050814", "0050818", "0050819", "0050820", "0050821", "0050822"
)
Based on this, I have come up with the following code:
set.seed(20220913)
arr <- matrix(runif(15*30), nrow = 30)
dff <- as.data.frame(arr)
names(dff) <- paste(sample(letters, replace = F), sample(letters, replace = F), sep = " ")[1:15]
library(tidyverse)
dff %>%
mutate(Site = seq(nrow(.))) %>%
pivot_longer(-Site, names_to = 'Species', values_to = 'Abundance') %>%
mutate(yval = match(Species, colnames(dff))) %>%
ggplot(aes(Site, yval, fill = Abundance)) +
geom_tile(color = "black") +
geom_text(aes(label = colnames(dff)), hjust = 1.1, size = 3,
data = data.frame(Site = 31.5, yval = 1:15, Abundance = 1)) +
coord_polar() +
scale_y_continuous(limits = c(-5, 15.5)) +
scale_x_continuous(limits = c(0.5, 31.5), breaks = 1:30, labels = names.d,
name = 'Breeding site') +
scale_fill_gradientn(colors = colorRampPalette(RColorBrewer::brewer.pal(name = "YlOrRd", n = 9))(25), values = 0:1, labels = scales::percent)+
theme_void(base_size = 16) +
theme(axis.text.x = element_text(size = 12),
axis.title.x = element_text())
which gives me the following figure:
Which is great, but I would like the labels on the rim of the figure to radiate out (or be tangent, for that matter). So, I wrote the angles as:
ang <- 1:30/31.5*360
However, I can not see where to pass this argument. Looking around, it would normally be in the aes function, but there the labels are for the y-axis in the figure (before being changed to the polar coordinates), and what I am wanting rotated should be in the x-axis. So, how do I do this? Thanks for any suggestions!
You can add this in the axis.text.x = element_text() :
ang <- 90 - (1:30/31.5*360)
dff %>%
mutate(Site = seq(nrow(.))) %>%
pivot_longer(-Site, names_to = 'Species', values_to = 'Abundance') %>%
mutate(yval = match(Species, colnames(dff))) %>%
ggplot(aes(Site, yval, fill = Abundance)) +
geom_tile(color = "black") +
geom_text(aes(label = colnames(dff)), hjust = 1.1, size = 3,
data = data.frame(Site = 31.5, yval = 1:15, Abundance = 1)) +
coord_polar() +
scale_y_continuous(limits = c(-5, 15.5)) +
scale_x_continuous(limits = c(0.5, 31.5), breaks = 1:30, labels = names.d,
name = 'Breeding site') +
scale_fill_gradientn(colors = colorRampPalette(RColorBrewer::brewer.pal(name = "YlOrRd", n = 9))(25), values = 0:1, labels = scales::percent)+
theme_void(base_size = 16) +
theme(axis.text.x = element_text(size = 12, angle = ang),
axis.title.x = element_text())

R ggplot vs barplot 2

I am trying to replicate the stacked bar chart built via ggplot() into a chart that uses barplot(). My code is below. My problem is that barplot() produces not a stacked chart. What do I do in a wrong way here? Thanks!
Data is accessible at the following link.
# link to the data: https://drive.google.com/file/d/16FQ7APc0r1IYS_geMdeBRoMiUMaF01t3/view?usp=sharing
df <- read.csv("US Sectoral Balances 3.csv")
# ggplot()
df %>%
# Plotting the data via ggplot2()
ggplot(aes(x = TimePeriod, y = DataValue_per_GDP, color = Sectors, fill = Sectors)) +
geom_col(aes(fill = Sectors), position = "stack", width = 1) +
scale_y_continuous(labels = percent,
sec.axis = sec_axis(~., name = "", labels = percent)) +
scale_x_discrete(name=NULL, breaks = brks) +
scale_fill_manual(values=c("#FF3399", "#3399FF", "#66CC99","#0022CC","#11AA00")) +
scale_color_manual(values=c("#FF3399", "#3399FF", "#66CC99","#0022CC","#11AA00")) +
guides(fill = guide_legend(title.theme =
element_text(size = 9, face = "bold",
colour = "black", angle = 0))) +
labs(x ="", y = "(% of GDP)",
subtitle = "Three-sector breakdown",
title = paste0("U.S. Sectoral Balances",
" through ", year(max(df$date))," ",quarters(max(df$date))),
caption = paste0("\nNote: data is from the BEA's Table 5.1. Saving and Investment by Sector.",
"\n\nSource: BEA.")) +
theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 10),
plot.caption = element_text(hjust = 0, size = 8))
# barplot()
l <- min(
length(df[substr(df$Sectors,1,1)=="A",]$DataValue_per_GDP),
length(df[substr(df$Sectors,1,1)=="B",]$DataValue_per_GDP),
length(df[substr(df$Sectors,1,1)=="C",]$DataValue_per_GDP)
)
bar_data <- matrix(data = rbind(df[substr(df$Sectors,1,1)=="A",]$DataValue_per_GDP*100,
df[substr(df$Sectors,1,1)=="B",]$DataValue_per_GDP*100,
df[substr(df$Sectors,1,1)=="C",]$DataValue_per_GDP*100),
nrow = 3, ncol = l)
colnames(bar_data) <- df[substr(df$Sectors,1,1)=="A",]$TimePeriod[1:l]
rownames(bar_data) <- c("A. General government","B. Private","C. External")
barplot(bar_data, col=c("red","blue","green"), beside = FALSE)
barplot(bar_data, col=c("red","blue","green"), beside = TRUE)

label end of lines outside of plot area

I am trying to replicate this figure from the Financial Times.
Here is a gist with the data. I'm struggling to label the end of the lines because I run out of room in the plot. I found a few ways to expand the limits of the plot area, but this is not ideal because the gridlines extend as well.
library(tidyverse)
library(ggrepel)
covid %>%
ggplot(aes(x = date, y = deaths_roll7_100k, color = Province_State)) +
geom_line() +
scale_y_continuous(breaks = seq(0, 2.4, .2)) +
scale_x_date(breaks = seq.Date(from=as.Date('2020-09-01'),
to=as.Date('2021-07-12'),
by="month"),
labels = function(x) if_else(month(x) == 9 | month(x) == 1,
paste(month(x, label = TRUE),
"\n", year(x)),
paste(month(x, label = TRUE))),
limits = as.Date(c("2020-09-01", "2021-11-01"))) +
geom_text_repel(aes(label = label),
segment.alpha = 0,
hjust = 0,
direction="y",
na.rm = TRUE,
xlim = as.Date(c("2021-08-01", "2021-11-01")))
An alternative to ggrepel is to use geom_text and turn "clipping" off (similar to this question/answer), e.g.
covid %>%
ggplot(aes(x = date, y = deaths_roll7_100k, color = Province_State)) +
geom_line() +
scale_y_continuous(breaks = seq(0, 2.4, .2)) +
scale_x_date(breaks = seq.Date(from=as.Date('2020-09-01'),
to=as.Date('2021-07-12'),
by="month"),
date_labels = "%b\n%Y",
limits = as.Date(c("2020-09-01", "2021-07-01"))) +
geom_text(data = . %>% filter(date == max(date)),
aes(color = Province_State, x = as.Date(Inf),
y = deaths_roll7_100k),
hjust = 0, size = 4, vjust = 0.7,
label = c("Arizona\n", "North Carolina")) +
coord_cartesian(expand = FALSE, clip = "off")
--
With some more tweaks and the Financial-Times/ftplottools R theme you can get the plot looking pretty similar to the Financial Times figure, e.g.
library(tidyverse)
#remotes::install_github("Financial-Times/ftplottools")
library(ftplottools)
library(extrafont)
#font_import()
#fonts()
covid %>%
ggplot() +
geom_line(aes(x = date, y = deaths_roll7_100k,
group = Province_State, color = Province_State)) +
geom_text(data = . %>% filter(date == max(date)),
aes(color = Province_State, x = as.Date(Inf),
y = deaths_roll7_100k),
hjust = 0, size = 4, vjust = 0.7,
label = c("Arizona\n", "North Carolina")) +
coord_cartesian(expand = FALSE, clip = "off") +
ft_theme(base_family = "Arimo for Powerline") +
theme(plot.margin = unit(c(1,6,1,1), "lines"),
legend.position = "none",
plot.background = element_rect(fill = "#FFF1E6"),
axis.title = element_blank(),
panel.grid.major.x = element_line(colour = "gray75"),
plot.caption = element_text(size = 8, color = "gray50")) +
scale_color_manual(values = c("#E85D8C", "#0D5696")) +
scale_x_date(breaks = seq.Date(from = as.Date('2020-09-01'),
to = as.Date('2021-07-01'),
by = "1 month"),
limits = as.Date(c("2020-09-01", "2021-07-01")),
date_labels = "%b\n%Y") +
scale_y_continuous(breaks = seq(from = 0, to = 2.4, by = 0.2)) +
labs(title = "New deaths attributed to Covid-19 in North Carolina and Arizona",
subtitle = "Seven-day rolling average of new deaths (per 100k)\n",
caption = "Source: Analysis of data from John Hopkins SSE\nUpdated: 12th July 2021 | CCBY4.0")

How to combine different layers in r ggplot with 2 different datasets - one for map & other for geom_area?

I have created a plot with geom_area(), geom_line() in it. Now I would like to add a country map background in the plot and for same I am trying to use: map_data() & geom_ploygon() but it's giving error, probably because one's xaxis is on date scale & other's is longitude.
Error:
Error: Invalid input: date_trans works with objects of class Date only
Here is my code & plot without map:
library(tidyverse)
library(glue)
library(scales)
library(tidytext)
data:
file_url <- "https://raw.githubusercontent.com/johnsnow09/covid19-df_stack-code/main/ts_all_long3.csv"
ts_all_long <- read.csv(url(file_url))
Step 1:
confirm_col = "#32a4ba"
death_col = "#f08080"
Country_selected = c("India")
scaleFactor = max(ts_all_long %>%
filter(Country.Region %in% Country_selected) %>%
pull(Confirmed_daily)) /
max(ts_all_long %>%
filter(Country.Region %in% Country_selected) %>%
pull(Death_daily))
ts_all_long %>%
filter(Country.Region %in% c("India") ) %>%
ggplot(aes(x = date)) +
geom_area(aes(y = Confirmed_daily), fill = confirm_col, alpha = .7) +
geom_line(aes(y = Death_daily * scaleFactor), col = death_col,
size = 0.8, alpha = 0.8) +
scale_y_continuous(name = "Daily Cases", sec.axis = sec_axis(~./scaleFactor, name = "Daily Deaths"),
labels = scales::comma_format()) +
scale_x_date(date_breaks = "1 month", date_labels = "%b") +
geom_hline(yintercept = c(25000,95000), lty = 2, col = "grey50") +
geom_vline(xintercept = c(ymd("2020-07-08"),ymd("2020-09-10"),
ymd("2021-03-15"),ymd("2021-04-03")),
lty = 2, col = "grey50") +
annotate("text", x = ymd("2020-08-10"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2months+") +
annotate("text", x = ymd("2021-03-18"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2weeks+") +
geom_text(
label=glue("1st wave"), angle = 90, x=ymd("2020-07-30"), y= 75000,
size = 4, color = confirm_col
) +
geom_text(
label=glue("2nd wave"), angle = 90, x=ymd("2021-03-18"), y= 75000,
size = 4, color = confirm_col
) +
theme_excel_new() +
theme(
axis.title.y.left=element_text(color=confirm_col),
axis.text.y.left=element_text(color=confirm_col),
axis.title.y.right=element_text(color=death_col),
axis.text.y.right=element_text(color=death_col),
plot.title = element_markdown(face = "plain", family = "serif", size = 14),
panel.grid.major = element_blank()
) +
labs(title = glue("<i>{Country_selected}</i>: Daily Cases to jump to 1 lac in 1st & 2nd wave, as of: {max(ts_all_long$date)}"),
# subtitle = "Cases to jump from 25,000 to 95,000 in first & second wave",
caption = "Data source: covid19.analytics
Created by: ViSa")
Step 2: Code & image for map:
ggplot() +
geom_polygon(data = map_data("world", region = "India"),
aes(x = long, y = lat, group = group),
fill="lightgray", colour = "white")
Step 3: When I try to combine code for above 2 steps I get an error:
confirm_col = "#32a4ba"
death_col = "#f08080"
Country_selected = c("India")
scaleFactor = max(ts_all_long %>%
filter(Country.Region %in% Country_selected) %>%
pull(Confirmed_daily)) /
max(ts_all_long %>%
filter(Country.Region %in% Country_selected) %>%
pull(Death_daily))
ts_all_long %>%
filter(Country.Region %in% c("India") ) %>%
ggplot() +
# added country map here from step2
geom_polygon(data = map_data("world", region = "India"),
aes(x = long, y = lat, group = group),
fill="lightgray", colour = "white") +
# usual plot of step1
geom_area(aes(x = date, y = Confirmed_daily), fill = confirm_col, alpha = .7) +
geom_line(aes(x = date, y = Death_daily * scaleFactor), col = death_col,
size = 0.8, alpha = 0.8) +
scale_y_continuous(name = "Daily Cases", sec.axis = sec_axis(~./scaleFactor, name = "Daily Deaths"),
labels = scales::comma_format()) +
scale_x_date(date_breaks = "1 month", date_labels = "%b") +
geom_hline(yintercept = c(25000,95000), lty = 2, col = "grey50") +
geom_vline(xintercept = c(ymd("2020-07-08"),ymd("2020-09-10"),
ymd("2021-03-15"),ymd("2021-04-03")),
lty = 2, col = "grey50") +
annotate("text", x = ymd("2020-08-10"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2months+") +
annotate("text", x = ymd("2021-03-18"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2weeks+") +
geom_text(
label=glue("1st wave"), angle = 90, x=ymd("2020-07-30"), y= 75000,
size = 4, color = confirm_col
) +
geom_text(
label=glue("2nd wave"), angle = 90, x=ymd("2021-03-18"), y= 75000,
size = 4, color = confirm_col
) +
theme_excel_new() +
theme(
axis.title.y.left=element_text(color=confirm_col),
axis.text.y.left=element_text(color=confirm_col),
axis.title.y.right=element_text(color=death_col),
axis.text.y.right=element_text(color=death_col),
plot.title = element_markdown(face = "plain", family = "serif", size = 14),
panel.grid.major = element_blank()
) +
labs(title = glue("<i>{Country_selected}</i>: Daily Cases to jump to 1 lac in 1st & 2nd wave, as of: {max(ts_all_long$date)}"),
# subtitle = "Cases to jump from 25,000 to 95,000 in first & second wave",
caption = "Data source: covid19.analytics
Created by: ViSa")
I would suggest to add the map as a background image to your plot which could be done via e.g. the ggimage package like so:
library(ggimage)
map <- ggplot() +
geom_polygon(data = map_data("world", region = "India"),
aes(x = long, y = lat, group = group),
fill="lightgray", colour = "white") +
theme_void()
ggsave("map.png")
#> Saving 7 x 5 in image
ggbackground(p, "map.png")
p:
d <- ts_all_long %>%
filter(Country.Region %in% c("India")) %>%
mutate(date = as.Date(date))
p <- ggplot(d, aes(x = date)) +
geom_area(aes(y = Confirmed_daily), fill = confirm_col, alpha = .7) +
geom_line(aes(y = Death_daily * scaleFactor), col = death_col,
size = 0.8, alpha = 0.8) +
scale_y_continuous(name = "Daily Cases", sec.axis = sec_axis(~./scaleFactor, name = "Daily Deaths"),
labels = scales::comma_format()) +
scale_x_date(date_breaks = "1 month", date_labels = "%b") +
geom_hline(yintercept = c(25000,95000), lty = 2, col = "grey50") +
geom_vline(xintercept = c(ymd("2020-07-08"),ymd("2020-09-10"),
ymd("2021-03-15"),ymd("2021-04-03")),
lty = 2, col = "grey50") +
annotate("text", x = ymd("2020-08-10"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2months+") +
annotate("text", x = ymd("2021-03-18"), y = 96000, col = death_col, size = 3,
label = "25k to 95k in \n~2weeks+") +
geom_text(
label=glue("1st wave"), angle = 90, x=ymd("2020-07-30"), y= 75000,
size = 4, color = confirm_col
) +
geom_text(
label=glue("2nd wave"), angle = 90, x=ymd("2021-03-18"), y= 75000,
size = 4, color = confirm_col
) +
theme_excel_new() +
theme(
axis.title.y.left=element_text(color=confirm_col),
axis.text.y.left=element_text(color=confirm_col),
axis.title.y.right=element_text(color=death_col),
axis.text.y.right=element_text(color=death_col),
plot.title = element_markdown(face = "plain", family = "serif", size = 14),
panel.grid.major = element_blank()
) +
labs(title = glue("<i>{Country_selected}</i>: Daily Cases to jump to 1 lac in 1st & 2nd wave, as of: {max(ts_all_long$date)}"),
# subtitle = "Cases to jump from 25,000 to 95,000 in first & second wave",
caption = "Data source: covid19.analytics
Created by: ViSa")

gganimate horizontal column chart won't transition bars smoothly

I am creating a bar chart race animation using geom_colh from the ggstance package. Right now, the animation is very choppy and doesn't appear to be one continuous animation, instead just one image after another. Below is what the current animation looks like:
Instead, I want the bars to "glide" from one position to another when they pass each other. Below is the reprex of the code I currently have:
library(tidyverse)
library(dplyr)
library(ggplot2)
library(gganimate)
library(ggstance)
library(zoo)
library(gifski)
library(shadowtext)
stats <- read_csv(url("https://raw.githubusercontent.com/samhoppen/Fantasy-Evaluator/main/Data/Animation%20Test%20Data.csv")) %>%
mutate(unique_id = paste0(player_name, recent_team))
all_weeks <- read_csv(url("https://raw.githubusercontent.com/samhoppen/Fantasy-Evaluator/main/Data/Animation%20Weeks%20Data.csv"))
NFL_pri <- stats$team_color
names(NFL_pri) <- stats$unique_id
NFL_sec <- stats$team_color2
names(NFL_sec) <- stats$unique_id
rb_ani <- ggplot(data = stats, aes(group = player_name)) +
geom_colh(aes(x = tot_fpts, y = rank, color = unique_id, fill = unique_id), position = 'identity',
size = 2, width = 0.8) +
scale_x_continuous(expand = expansion(mult = c(0, 0.05))) +
scale_y_reverse(expand = expansion(mult = c(0.01, 0.01)))+
geom_shadowtext(aes(x = name_loc, y = rank, label = player_name, color = unique_id),
bg.color = 'white', size = 5.5, na.rm = T, bg.r = 0.075, show.legend = FALSE) +
scale_color_manual(values = NFL_sec)+
scale_fill_manual(values = NFL_pri)+
labs(title = "Highest-scoring Fantasy Running Backs of the Past Decade",
subtitle = paste0("{all_weeks$week_name[as.numeric(previous_state)]}"),
caption = "Figure: #SamHoppen | Data: #nflfastR",
y = "",
x = "Total Fantasy Points")+
theme(legend.position = "none",
plot.title = element_text(size = 24, face = "bold", margin = margin(0,0,10,0)),
plot.subtitle = element_text(size = 12, margin = margin(0,0,10,0)),
plot.caption = element_text(size = 12)) +
transition_states(states = week_order, transition_length = 2, state_length = 1, wrap = F) +
view_follow(fixed_y = TRUE) +
enter_fly(y_loc = -21) +
exit_fly(y_loc = -21) +
ease_aes('linear')
anim <- animate(rb_ani, nframes = 100, fps = 5,renderer = gifski_renderer(), height = 900, width = 1600)
I've tried changing the transition length/state length, removing the theme items, removing the colors, removing the stat = 'identity' argument, changing the group variable, and the number of frames/fps. I'm at a loss of what to try next. Any suggestions would be great!
Part of the challenge here is very choppy rankings week to week. To make the animation smooth, you'll need to either make the animation pretty long, or select a subset of weeks to calculate rankings on. Here I've limited to just week 30-39, and added more frames.
I also did some more data cleaning to give all the players a rank in each week even if they aren't included in stats that week.
animate(
stats %>%
# Some week_name missing from stats, will use week_order to get from all_weeks
select(-week_name) %>%
left_join(all_weeks %>% select(week_order, week_name), by = "week_order") %>%
# add every week for each player, and fill in any missing tot_fpts or team_colors
select(week_order, week_name, player_name, tot_fpts,
unique_id, team_color, team_color2) %>%
complete(week_order, player_name) %>%
fill(tot_fpts, .direction = "down") %>%
fill(unique_id, team_color, team_color2, .direction = "downup") %>%
# only keep players who had >0 max_tot_fpts and weeks 30-39
group_by(player_name) %>%
mutate(max_tot_fpts = max(tot_fpts)) %>%
filter(max_tot_fpts > 0, week_order >= 30, week_order < 40) %>%
# smooth out tot_fpts
mutate(tot_fpts_smooth = spline(x = week_order, y = tot_fpts, xout = week_order)$y) %>%
# Calc rank for every week, only keep top 20
group_by(week_order) %>%
arrange(-tot_fpts_smooth, player_name) %>%
mutate(rank = row_number()) %>%
ungroup() %>%
filter(rank <= 20) %>%
ggplot(aes(group = player_name, y = rank)) +
geom_tile(aes(x = tot_fpts/2, height = 0.9, width = tot_fpts,
color = unique_id, fill = unique_id)) +
geom_shadowtext(aes(x = tot_fpts, y = rank, label = player_name, color = unique_id),
bg.color = 'white', size = 3.5, na.rm = T, bg.r = 0.075,
show.legend = FALSE, hjust = 1.1) +
# geom_text(aes(x = tot_fpts, label = paste(player_name, " ")), vjust = 0.2, hjust = 1) +
scale_y_reverse(breaks = 1:20, minor_breaks = NULL) +
scale_color_manual(values = NFL_sec)+
scale_fill_manual(values = NFL_pri)+
labs(title = "Highest-scoring Fantasy Running Backs of the Past Decade",
subtitle = paste0("{all_weeks$week_name[as.numeric(previous_state)]}"),
caption = "Figure: #SamHoppen | Data: #nflfastR",
y = "",
x = "Total Fantasy Points")+
theme_minimal() +
theme(legend.position = "none",
plot.title = element_text(size = 14, face = "bold", margin = margin(0,0,10,0)),
plot.subtitle = element_text(size = 12, margin = margin(0,0,10,0)),
plot.caption = element_text(size = 12)) +
transition_states(week_order, state_length = 0) +
view_follow(fixed_y = TRUE) +
enter_fly(y_loc = -21) +
exit_fly(y_loc = -21) +
ease_aes('linear'),
fps = 20, duration = 4, width = 400, height = 300)

Resources