My data:
structure(list(month = c("01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12"), p00pcp = c(0, 0, 0, 0, 0.1,
0, 0, 0, 0, 0, 0, 0), p20pcp = c(7.8, 12.8, 12.9, 18.9, 17.8,
5.7, 0.2, 0.9, 6.6, 14.4, 16.8, 12.3), p40pcp = c(20.3, 26.4,
27, 34.7, 29.9, 19, 3.9, 3.4, 12.7, 33.6, 43.2, 25.4), p50pcp = c(27.5,
32.5, 33.7, 45.6, 35.7, 24.5, 6, 6.1, 17, 48.8, 48.3, 32.9),
p60pcp = c(34.2, 41, 41.6, 52.9, 45.6, 28.9, 9.2, 9.1, 25.6,
58.5, 60.2, 45.5), p80pcp = c(64.4, 63, 58, 69.8, 71, 40.8,
16.5, 15.3, 47.5, 86.9, 79.7, 79.1), p100pcp = c(156.1, 128.7,
140.7, 138.1, 135.3, 91.9, 54.8, 73.8, 169, 192.4, 198.4,
180.5), sumpcp = c(11.7, 1.6, 22, 8.3, 58.6, 42.5, 0, 0,
0, 0, 0.1, NA), diffp50pcp = c("-15.8", "-30.9", "-11.7",
"-37.3", "+22.9", "+18", "-6", "-6.1", "-17", "-48.8", "-48.2",
NA), diffp50pcp_x = c("/2.4", "/20.3", "/1.5", "/5.5", "x1.6",
"x1.7", "-", "-", "-", "-", "/483", NA)), row.names = c(NA,
-12L), class = c("tbl_df", "tbl", "data.frame"))
My code so far:
ref_end_year <- 2010
ref_start_year <- 1981
selected_year <- 2020
ggplot2::ggplot(data = plot_data, aes(x = month)) +
ggh4x::geom_box(aes(ymin = 0, ymax = p00pcp, fill = "P00", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p00pcp, ymax = p20pcp, fill = "P20", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p20pcp, ymax = p40pcp, fill = "P40", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p40pcp, ymax = p60pcp, fill = "P60", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p60pcp, ymax = p80pcp, fill = "P80", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p80pcp, ymax = p100pcp, fill = "P100", width = 0.9), alpha = 0.3) +
ggh4x::geom_box(aes(ymin = p100pcp, ymax = p100pcp + 50, fill = ">P100", width = 0.9), alpha = 0.3) +
ggplot2::geom_segment(aes(x = month, xend = month, y = 0, yend = sumpcp, color = "sumpcp"),
linewidth = 0.75, na.rm = TRUE) +
ggplot2::geom_point(aes(y = sumpcp, color = "sumpcp"), na.rm = TRUE) +
ggplot2::scale_color_manual(values = c("sumpcp" = "black"),
label = paste0("Monthly total precip. (", selected_year, ")"),
guide = guide_legend(order = 1)) +
ggplot2::geom_text(aes(y = sumpcp, label = paste(diffmedian, "*mm~vs.~italic(P)[50]")),
parse = TRUE, vjust = -2.5, na.rm = TRUE) +
ggplot2::geom_text(aes(y = sumpcp, label = diffmedian_x), vjust = -1.5, na.rm = TRUE) +
#ggplot2::scale_alpha_manual(values = rep(0.3, 1)) +
ggplot2::scale_fill_manual(
values = c(">P100" = "#2166ac", "P100" = "#67a9cf", "P80" = "#d1e5f0", "P60" = "#f7f7f7", "P40" = "#fddbc7",
"P20" = "#ef8a62", "P00" = "#b2182b"),
labels = c(">P100" = expr(paste("Extrem. wet month (>", italic(P[100]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P100" = expr(paste("Very wet month (", italic(P[80]), "-", italic(P[100]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P80" = expr(paste("Wet month (", italic(P[60]), "-", italic(P[80]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P60" = expr(paste("Normal month (", italic(P[40]), "-", italic(P[60]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P40" = expr(paste("Dry month (", italic(P[20]), "-", italic(P[40]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P20" = expr(paste("Very dry month (", italic(P[00]), "-", italic(P[20]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")")),
"P00" = expr(paste("Extrem. dry month (<", italic(P[00]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"))),
breaks = c(">P100", "P100", "P80", "P60", "P40", "P20", "P00")) + # to give order
ggplot2::scale_x_discrete(
limits = c("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"),
labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")) +
ggplot2::scale_y_continuous(
labels = function(x) paste0(x, "mm"),
breaks = seq(from = 0, to = max(max(plot_data$p100pcp), max(plot_data$sumpcp, na.rm = TRUE)) + 125, by = 50),
limits = c(0, max(max(plot_data$p100pcp), max(plot_data$sumpcp, na.rm = TRUE)) + 100)) +
ggthemes::theme_hc(base_size = 15) +
ggplot2::labs(
x = "", y = "",
color = NULL, fill = NULL
) +
ggplot2::theme(
plot.title = ggplot2::element_text(hjust = 1, face = "bold", family = "sans", size = 35),
plot.subtitle = ggplot2::element_text(hjust = 1, size = 25),
legend.background = ggplot2::element_blank(),
legend.box.background = ggplot2::element_rect(fill = "white", color = "black", linewidth = 0.75),
legend.position = c(0.125, 0.85),
legend.spacing = ggplot2::unit(0, "cm"),
legend.margin = ggplot2::margin(r = 5, l = 5, b = 5),
legend.title = ggplot2::element_blank()
)
As you can see, alpha is not applied on the legend, only in the main plot. How can I apply same alpha to legend boxes? To be clear: I want same color transparency within the legend boxes and the ones in geom_box
. I've tried including alpha inside aes()
and use scale_alpha_manual()
with no luck. I have also tried + guides(fill = guide_legend(override.aes = list(alpha = 1)))
but with no luck either. What am I missing?
This is a prime example of the mysterious issues one might encounter when working and plotting with untidy data. (;
The issue is a special kind of overplotting which only happens in the legend, i.e. for each of your geom_box
layers a legend key is drawn, i.e. in total for each category 7 legend keys are drawn on top each other, each with an alpha
of .3. But in "sum" it seems as if no alpha
is applied. This is also the reason why overriding alpha
via guides
will have no effect (but perhaps override.aes(alpha = .3 / 7)
gets you close).
Instead, reshape your data to long and create your chart using just one e.g. geom_col
:
library(ggplot2)
library(dplyr, warn=FALSE)
plot_data_long <- plot_data |>
select(month, matches("^>?p")) |>
select(-p50pcp) |>
mutate(
`>p100pcp` = p100pcp + 50,
) |>
tidyr::pivot_longer(
-month
) |>
mutate(
name = toupper(gsub("pcp$", "", name)),
name = factor(name, levels = rev(unique(name)))
) |>
arrange(month) |>
mutate(
value = value - dplyr::lag(value, default = 0),
.by = month
)
ggplot(data = plot_data_long, aes(x = month)) +
geom_col(aes(y = value, fill = name), width = 0.9, alpha = 0.3) +
geom_segment(
data = plot_data,
aes(
x = month, xend = month,
y = 0, yend = sumpcp, color = "sumpcp"
),
linewidth = 0.75, na.rm = TRUE
) +
geom_point(
data = plot_data,
aes(y = sumpcp, color = "sumpcp"), na.rm = TRUE
) +
scale_color_manual(
values = c("sumpcp" = "black"),
label = paste0("Monthly total precip. (", selected_year, ")"),
guide = guide_legend(order = 1)
) +
# geom_text(aes(y = sumpcp, label = paste(diffmedian, "*mm~vs.~italic(P)[50]")),
# parse = TRUE, vjust = -2.5, na.rm = TRUE
# ) +
# geom_text(aes(y = sumpcp, label = diffmedian_x), vjust = -1.5, na.rm = TRUE) +
# scale_alpha_manual(values = rep(0.3, 1)) +
scale_fill_manual(
values = c(
">P100" = "#2166ac", "P100" = "#67a9cf",
"P80" = "#d1e5f0", "P60" = "#f7f7f7",
"P40" = "#fddbc7",
"P20" = "#ef8a62", "P00" = "#b2182b"
),
labels = c(
">P100" = expr(paste(
"Extrem. wet month (>", italic(P[100]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P100" = expr(paste(
"Very wet month (", italic(P[80]), "-", italic(P[100]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P80" = expr(paste(
"Wet month (", italic(P[60]), "-", italic(P[80]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P60" = expr(paste(
"Normal month (", italic(P[40]), "-", italic(P[60]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P40" = expr(paste(
"Dry month (", italic(P[20]), "-", italic(P[40]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P20" = expr(paste(
"Very dry month (", italic(P[00]), "-", italic(P[20]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
)),
"P00" = expr(paste(
"Extrem. dry month (<", italic(P[00]), ") (",
!!ref_start_year, "-", !!ref_end_year, ")"
))
)
) +
scale_x_discrete(
labels = month.abb
) +
scale_y_continuous(
labels = function(x) paste0(x, "mm"),
breaks = seq(from = 0, to = max(
max(plot_data$p100pcp),
max(plot_data$sumpcp, na.rm = TRUE)
) + 125, by = 50),
limits = c(0, max(
max(plot_data$p100pcp),
max(plot_data$sumpcp, na.rm = TRUE)
) + 100)
) +
ggthemes::theme_hc(base_size = 15) +
labs(
x = "", y = "",
color = NULL, fill = NULL
) +
theme(
plot.title = element_text(
hjust = 1, face = "bold", family = "sans", size = 35
),
plot.subtitle = element_text(hjust = 1, size = 25),
legend.background = element_blank(),
legend.box.background = element_rect(
fill = "white", color = "black", linewidth = 0.75
),
legend.position = c(0.125, 0.85),
legend.spacing = unit(0, "cm"),
legend.margin = margin(r = 5, l = 5, b = 5),
legend.title = element_blank()
)