Skip to content

Commit 5efba98

Browse files
authored
Merge pull request #34 from epiforecasts/26-focus-25A-emergence
Issue 26: add a plot focused on 25A emergence
2 parents 2595580 + fc82dbc commit 5efba98

10 files changed

+364
-0
lines changed

R/fig_zoom_clade_mult_nowcasts.R

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
#' Get a plot of nowcasts for multiple nowcast dates vs observations
2+
#'
3+
#' @param model_preds_mult_nowcasts Model predicted observations for multiple
4+
#' nowcasts
5+
#' @param final_eval_data Final sequence counts by clade and location
6+
#' @param clade_to_zoom Character string indicating the clade to zoom
7+
#' @param horizon_to_plot Range of integers to filter to for the plot
8+
#'
9+
#' @returns ggplot object
10+
get_plot_model_preds_mult <- function(model_preds_mult_nowcasts,
11+
final_eval_data,
12+
clade_to_zoom = "25A",
13+
horizon_to_plot = c(-6, 0)) {
14+
df_filt <- model_preds_mult_nowcasts |>
15+
filter(clade == clade_to_zoom) |>
16+
mutate(horizon = as.integer(target_date - nowcast_date)) |>
17+
filter(horizon <= max(horizon_to_plot), horizon >= min(horizon_to_plot))
18+
19+
weekly_obs_data <- daily_to_weekly(final_eval_data) |>
20+
filter(location %in% unique(df_filt$location))
21+
total_seq <- weekly_obs_data |>
22+
group_by(date, location) |>
23+
summarise(n_seq = sum(sequences))
24+
weekly_obs <- left_join(weekly_obs_data, total_seq) |>
25+
filter(clades_modeled == clade_to_zoom)
26+
27+
plot_comps <- plot_components()
28+
29+
p <- ggplot(df_filt) +
30+
geom_line(aes(
31+
x = target_date, y = q_0.5, color = model_id,
32+
group = nowcast_date
33+
)) +
34+
geom_ribbon(
35+
aes(
36+
x = target_date,
37+
ymin = q_0.25,
38+
ymax = q_0.75, fill = model_id,
39+
group = nowcast_date
40+
),
41+
alpha = 0.2
42+
) +
43+
geom_ribbon(
44+
aes(
45+
x = target_date,
46+
ymin = q_0.025,
47+
ymax = q_0.975, fill = model_id,
48+
group = nowcast_date
49+
),
50+
alpha = 0.1
51+
) +
52+
geom_point(
53+
data = weekly_obs,
54+
aes(x = date, y = sequences / n_seq),
55+
color = "#CAB2D6"
56+
) +
57+
geom_line(
58+
data = weekly_obs,
59+
aes(x = date, y = sequences / n_seq),
60+
color = "#CAB2D6"
61+
) +
62+
facet_grid(vars(model_id), vars(location)) +
63+
get_plot_theme(dates = TRUE) +
64+
scale_color_manual(
65+
name = "Model",
66+
values = plot_comps$model_colors
67+
) +
68+
scale_fill_manual(
69+
name = "Model",
70+
values = plot_comps$model_colors
71+
) +
72+
xlab("") +
73+
ylab("Model predictions across nowcast dates") +
74+
guides(
75+
color = "none",
76+
fill = "none"
77+
) +
78+
scale_x_date(
79+
limits = c(min(df_filt$target_date), max(df_filt$target_date)),
80+
date_breaks = "1 week",
81+
date_labels = "%d %b %Y"
82+
) +
83+
ggtitle("25A emergence")
84+
85+
return(p)
86+
}
87+
88+
#' Get a plot of scores by nowcast date for locations and models
89+
#'
90+
#' @param scores Data.frame of scores
91+
#' @param locs Vector of character strings of locations
92+
#' @param nowcast_dates Set of nowcast dates to summarise over
93+
#' @param date_range Range of dates to plot
94+
#' @param horizon_to_plot horizon days to plot
95+
#'
96+
#' @returns ggplot
97+
get_plot_scores_by_date <- function(scores,
98+
locs,
99+
nowcast_dates,
100+
date_range,
101+
horizon_to_plot = c(-6, 0)) {
102+
scores_avg <- scores |>
103+
filter(
104+
location %in% locs,
105+
nowcast_date %in% nowcast_dates,
106+
!is.na(energy_score)
107+
) |>
108+
group_by(model, location) |>
109+
summarise(energy_score = mean(energy_score, na.rm = TRUE))
110+
111+
scores_df <- scores |>
112+
mutate(horizon = as.numeric(target_date - nowcast_date)) |>
113+
filter(
114+
location %in% locs,
115+
nowcast_date %in% nowcast_dates,
116+
!is.na(energy_score),
117+
horizon <= max(horizon_to_plot),
118+
horizon >= min(horizon_to_plot)
119+
) |>
120+
group_by(nowcast_date, location, model) |>
121+
summarise(energy_score = mean(energy_score, na.rm = TRUE))
122+
123+
plot_comps <- plot_components()
124+
p <- ggplot(scores_df) +
125+
geom_point(aes(
126+
x = nowcast_date, y = energy_score,
127+
color = model
128+
)) +
129+
geom_line(aes(
130+
x = nowcast_date, y = energy_score,
131+
color = model
132+
)) +
133+
geom_hline(
134+
data = scores_avg,
135+
aes(yintercept = energy_score, color = model),
136+
linetype = "dashed"
137+
) +
138+
facet_wrap(~location) +
139+
get_plot_theme(dates = TRUE) +
140+
scale_color_manual(
141+
name = "Model",
142+
values = plot_comps$model_colors
143+
) +
144+
xlab("") +
145+
ylab("Average energy score") +
146+
scale_x_date(
147+
limits = date_range,
148+
date_breaks = "1 week",
149+
date_labels = "%d %b %Y"
150+
)
151+
return(p)
152+
}
153+
154+
#' Multiplot panel looking at 25A emergence across nowcast dates
155+
#'
156+
#' @param grid A
157+
#' @param underlay B
158+
#' @param plot_name name of plot
159+
#' @param output_fp filepath directory
160+
#'
161+
#' @returns patchwork
162+
get_fig_zoom_25A <- function(grid,
163+
underlay,
164+
plot_name,
165+
output_fp = file.path(
166+
"output", "figs",
167+
"zoom_25A", "final"
168+
)) {
169+
fig_layout <- "
170+
AAA
171+
AAA
172+
AAA
173+
BBB
174+
"
175+
176+
fig_zoom <- grid +
177+
underlay +
178+
plot_layout(
179+
design = fig_layout,
180+
axes = "collect",
181+
guides = "collect"
182+
) +
183+
plot_annotation(
184+
tag_levels = "A",
185+
tag_suffix = "",
186+
tag_sep = "",
187+
theme = theme(
188+
legend.position = "top",
189+
legend.title = element_text(hjust = 0.5),
190+
legend.justification = "center",
191+
plot.tag = element_text(size = 20)
192+
)
193+
)
194+
195+
dir_create(output_fp, recurse = TRUE)
196+
ggsave(file.path(output_fp, glue::glue("{plot_name}.png")),
197+
plot = fig_zoom,
198+
width = 8,
199+
height = 11
200+
)
201+
return(fig_zoom)
202+
}

_targets.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ plot_targets <- list(
8383
fig_nowcast_targets,
8484
fig_pred_plus_data_targets,
8585
fig_overall_targets,
86+
fig_zoom_25A_targets,
8687
fig_submission_heatmaps_targets
8788
)
8889

man/get_fig_zoom_25A.Rd

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/get_plot_model_preds_mult.Rd

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/get_plot_scores_by_date.Rd

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

targets/clean_data_targets.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ clean_data_targets <- list(
3131
type = "evaluation"
3232
)
3333
),
34+
tar_target(
35+
name = clean_variant_data_for_eval_mult_nowcasts,
36+
command = get_clean_variant_data(
37+
variant_data_for_eval_mult_nowcasts,
38+
clade_list,
39+
location_data,
40+
nowcast_date_range_to_zoom,
41+
seq_col_name = "oracle_value",
42+
type = "evaluation"
43+
)
44+
),
3445
tar_target(
3546
name = clean_variant_data_eval_all,
3647
command = get_clean_variant_data(

targets/config_targets.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ config_targets <- list(
5555
name = nowcast_date_for_vis,
5656
command = as.character(ymd("2025-02-19"))
5757
),
58+
tar_target(
59+
name = nowcast_date_range_to_zoom,
60+
command = seq(
61+
from = ymd("2025-01-15"),
62+
to = ymd("2025-03-19"),
63+
by = "week"
64+
)
65+
),
5866
tar_target(
5967
name = quantiles_to_vis,
6068
command = c(0.05, 0.25, 0.5, 0.75, 0.975)

targets/fig_zoom_25A_targets.R

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fig_zoom_25A_targets <- list(
2+
tar_target(
3+
name = plot_model_preds_mult_nowcasts,
4+
command = get_plot_model_preds_mult(
5+
model_preds_mult_nowcasts = df_mult_nowcasts,
6+
final_eval_data = clean_variant_data_final_all_states,
7+
clade_to_zoom = "25A"
8+
)
9+
),
10+
tar_target(
11+
name = plot_score_underlay,
12+
command = get_plot_scores_by_date(
13+
scores = su_scores,
14+
locs = states_for_vis,
15+
nowcast_dates = nowcast_date_range_to_zoom,
16+
date_range = c(
17+
min(nowcast_date_range_to_zoom) - days(6),
18+
max(nowcast_date_range_to_zoom)
19+
)
20+
)
21+
),
22+
tar_target(
23+
name = fig_zoom_25A,
24+
command = get_fig_zoom_25A(
25+
plot_model_preds_mult_nowcasts,
26+
plot_score_underlay,
27+
plot_name = "fig_zoom_25A"
28+
)
29+
)
30+
)

targets/load_data_targets.R

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ load_data_targets <- list(
2222
states = states_for_vis
2323
)
2424
),
25+
tar_target(
26+
name = variant_data_for_eval_mult_nowcasts,
27+
command = get_oracle_output(
28+
hub_path = hub_path,
29+
nowcast_dates = nowcast_date_range_to_zoom,
30+
states = states_for_vis
31+
)
32+
),
2533
# Variant data for evaluation (all dates and locations)
2634
tar_target(
2735
name = variant_data_eval_all,
@@ -76,6 +84,15 @@ load_data_targets <- list(
7684
bucket_name = nowcast_bucket_name
7785
)
7886
),
87+
# Model outputs for the selected dates
88+
tar_target(
89+
name = model_outputs_mult_nowcasts,
90+
command = extract_nowcasts(
91+
nowcast_dates = nowcast_date_range_to_zoom,
92+
states = states_for_vis,
93+
bucket_name = nowcast_bucket_name
94+
)
95+
),
7996
# All model outputs for heatmap (all dates and locations)
8097
tar_target(
8198
name = all_model_outputs_for_heatmap,

0 commit comments

Comments
 (0)