I am using ggplot2 to plot a time-series graph showing cumulative rainfall for both the current year and the historical values. I am also adding a couple of vertical lines in the graph indicating phonological stages of my interest. Therefore, I need two legends: one for rainfall and one for phenology.
Here is what I have so far:
library(ggplot2)
# Set random seed
set.seed(83)
# generate data frames
df1 <- data.frame(jday=1:365,
value=runif(n=365, min=3, max=10)-3,
type="current")
df1$csum <- cumsum(df1$value)
df2 <- data.frame(jday=1:365,
value=runif(n=365, min=0, max=10),
type="historical")
df2$csum <- cumsum(df2$value)
# plot data
ggplot() +
geom_line(df1, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), y=csum, fill=type), colour="steelblue3") +
geom_ribbon(df2, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), ymin=0, ymax=csum, fill=type), alpha=0.5) +
geom_vline(aes(xintercept=as.Date(150, origin=as.Date("2020-01-01")), colour="Planting"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(180, origin=as.Date("2020-01-01")), colour="Germination"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(210, origin=as.Date("2020-01-01")), colour="Flowering"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(240, origin=as.Date("2020-01-01")), colour="Grain filling"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(270, origin=as.Date("2020-01-01")), colour="Maturity"), linetype="longdash") +
theme_bw(base_size=18) +
scale_x_date(date_breaks="15 days", date_labels="%d/%b/%y") +
labs(y="Cumulative rainfall (mm)", x= "Date") +
theme(axis.text.x=element_text(angle=45, hjust=1)) +
scale_color_manual(name="Phenological stages",
breaks=c("Planting","Germination","Flowering","Grain filling","Maturity"),
values = c("Planting" = "#24CF09",
"Germination" = "#49A012",
"Flowering" = "#5B8817",
"Grain filling" = "#805920",
"Maturity" = "#A52A2A")) +
theme(legend.position="bottom",
legend.title=element_text(size=18),
legend.text = element_text(size=18)) +
guides(colour=guide_legend(nrow=1, byrow=FALSE,
title.position="top", title.hjust=0.5)) +
guides(fill=guide_legend(nrow=1, byrow=FALSE,
title.position="top", title.hjust=0.5)) +
scale_fill_manual(name="Rainfall",
values=c("current"="steelblue3", "historical"="skyblue1"),
labels=c("current"="Current year", "historical"="Historical"),
breaks=c("current","historical"))

The plot itself yields what I wanted, but there is a little detail that I really need to change. In the legend named Rainfall, I need to replace the Current year symbol from a "fill" to a "line", in order to match the geom_line that is being used in the plot.
However, I can't seem to find an easy (i.e. documented) way to do that. Any hints on how to get there? I appreciate it.
Here's a couple of approaches with ggnewscale::new_scale_color:
library(ggnewscale)
ggplot() +
geom_ribbon(df2, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), ymin=0, ymax=csum, fill=type), alpha=0.5) +
geom_vline(aes(xintercept=as.Date(274, origin=as.Date("2020-01-01")), colour="Planting"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(309, origin=as.Date("2020-01-01")), colour="Flowering"), linetype="longdash") +
theme_bw(base_size=18) +
scale_x_date(date_breaks="15 days", date_labels="%d/%b/%y") +
labs(y="Cumulative rainfall (mm)", x= "Date") +
theme(axis.text.x=element_text(angle=45, hjust=1)) +
scale_color_manual(name="Phenological stages",
breaks=c("Planting","Flowering"),
values = c("Planting" = "#24CF09",
"Flowering" = "#805920"),
guide=guide_legend(nrow=1, byrow=FALSE,
override.aes = list(fill = "black"),
title.position="top", title.hjust=0.5)) +
new_scale_color() +
geom_line(df1, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), y=csum, colour="current")) +
scale_color_manual(name = "Rainfall",
values=c("current"="steelblue3", "historical" = "skyblue1"),
labels = c("current"="Current year","historical"="Historical"),
drop = FALSE,
guide=guide_legend(nrow=1, byrow=FALSE,
override.aes = list(fill = "black"),
title.position="top", title.hjust=1.4)) +
scale_fill_manual(name = "", values=c("current"="steelblue3", "historical" = "skyblue1"),
labels = c("current"="Current year","historical"="Historical"),
drop = FALSE,
guide = guide_legend(nrow=1, byrow=FALSE,
title.position="top", title.hjust=0.5)) +
theme(legend.position="bottom",
legend.title=element_text(size=18),
legend.text = element_text(size=18))

ggplot() +
geom_ribbon(df2, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), ymin=0, ymax=csum, fill=type), alpha=0.5) +
geom_vline(aes(xintercept=as.Date(274, origin=as.Date("2020-01-01")), colour="Planting"), linetype="longdash") +
geom_vline(aes(xintercept=as.Date(309, origin=as.Date("2020-01-01")), colour="Flowering"), linetype="longdash") +
theme_bw(base_size=18) +
scale_x_date(date_breaks="15 days", date_labels="%d/%b/%y") +
labs(y="Cumulative rainfall (mm)", x= "Date") +
theme(axis.text.x=element_text(angle=45, hjust=1)) +
scale_color_manual(name="Phenological stages",
breaks=c("Planting","Flowering"),
values = c("Planting" = "#24CF09",
"Flowering" = "#805920"),
guide=guide_legend(nrow=1, byrow=FALSE,
override.aes = list(fill = "black"),
title.position="top", title.hjust=0.5)) +
new_scale_color() +
geom_line(df1, mapping=aes(x=as.Date(jday, origin=as.Date("2020-01-01")), y=csum, colour="current")) +
scale_color_manual(name = "Rainfall",
values=c("current"="steelblue3", "historical" = "skyblue1"),
labels = c("current"="Current year","historical"="Historical"),
drop = FALSE,
guide=guide_legend(nrow=1, byrow=FALSE,
override.aes = list(fill = "black"),
title.position="bottom", title.hjust=0.4)) +
scale_fill_manual(name = "Rainfall", values=c("current"="steelblue3", "historical" = "skyblue1"),
labels = c("current"="Current year","historical"="Historical"),
drop = FALSE,
guide = guide_legend(nrow=1, byrow=FALSE,
title.position="bottom", title.hjust=0.65)) +
theme(legend.position="bottom",
legend.title=element_text(size=18),
legend.text = element_text(size=18))

A second approach to get the desired result would be to make use of a custom key_glyph which uses the default rect glyph for the fill legend in case of the historical data and and a line or path glyph for the current data.
My custom glyph function is simply a wrapper which depending on the type or actually the fill color (see the note) calls ggplot2::draw_key_rect or ggplot2::draw_key_path.
Note 1 To the best of my knowledge it's not possible to condition on type. Instead we have to condition on the assigned fill color, i.e. we have to do if (data$fill == "skyblue1") to check for type == "historical".
Note 2 As draw_key_path needs a color instead of a fill we have to manually adjust the values for color aesthetic. This could be achieved in two ways.
guides(..., override.aes = ...)My edited code makes use of the second approach. Additionally I set the alpha=1 for the line and adjusted the size.
library(ggplot2)
# Custom key glyph
draw_key_cust <- function(data, params, size) {
if (data$fill == "skyblue1") {
draw_key_rect(data, params, size)
} else {
# Hard code the values or make use of guides(..., override.aes(...)) (see below)
# data$colour <- data$fill
# data$alpha <- 1
draw_key_path(data, params, size)
}
}
# plot data
ggplot() +
geom_line(df1, mapping = aes(x = as.Date(jday, origin = as.Date("2020-01-01")), y = csum, fill = "current"), colour = "steelblue3", key_glyph = "cust") +
geom_ribbon(df2, mapping = aes(x = as.Date(jday, origin = as.Date("2020-01-01")), ymin = 0, ymax = csum, fill = "historical"), alpha = 0.5, key_glyph = "cust") +
geom_vline(aes(xintercept = as.Date(150, origin = as.Date("2020-01-01")), colour = "Planting"), linetype = "longdash") +
geom_vline(aes(xintercept = as.Date(180, origin = as.Date("2020-01-01")), colour = "Germination"), linetype = "longdash") +
# geom_vline(aes(xintercept=as.Date(210, origin=as.Date("2020-01-01")), colour="Flowering"), linetype="longdash") +
# geom_vline(aes(xintercept=as.Date(240, origin=as.Date("2020-01-01")), colour="Grain filling"), linetype="longdash") +
# geom_vline(aes(xintercept=as.Date(270, origin=as.Date("2020-01-01")), colour="Maturity"), linetype="longdash") +
theme_bw(base_size = 18) +
scale_x_date(date_breaks = "15 days", date_labels = "%d/%b/%y") +
labs(y = "Cumulative rainfall (mm)", x = "Date") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_color_manual(
name = "Phenological stages",
breaks = c("Planting", "Germination", "Flowering", "Grain filling", "Maturity"),
values = c(
"Planting" = "#24CF09",
"Germination" = "#49A012",
"Flowering" = "#5B8817",
"Grain filling" = "#805920",
"Maturity" = "#A52A2A"
)
) +
theme(
legend.position = "bottom",
# legend.title=element_text(size=18),
# legend.text = element_text(size=18)
) +
guides(colour = guide_legend(
nrow = 1, byrow = FALSE,
title.position = "top", title.hjust = 0.5
)) +
guides(fill = guide_legend(
nrow = 1, byrow = FALSE,
title.position = "top", title.hjust = 0.5,
# Use override.aes to set the aes prams for the glyph
override.aes = list(color = c("steelblue3", NA), size = c(2, .5), alpha = c(1, .5))
)) +
scale_fill_manual(
name = "Rainfall",
values = c("current" = "steelblue3", "historical" = "skyblue1"),
labels = c("current" = "Current year", "historical" = "Historical"),
breaks = c("current", "historical")
)
#> Warning: Ignoring unknown aesthetics: fill

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With