I have a dataframe the looks as follows:
COUNTRY YEAR y
AT 2019 25
AT 2020 38.0
AT 2021 23.4
BE 2019 11.1
BE 2020 18.6
BE 2021 15.0
DK 2019 31.1
DK 2020 43.6
DK 2021 42.0
I am plotting it using both bars (year = 2021) and dots (year = 2015, 2019). I have some issues in getting the legend properly showing the right symbols. I indeed get the following graph
This is the final version of the code I am using:
countries <- c("AT", "BE", "DK")
years <- c(2019, 2020, 2021)
values <- c(25, 38.0, 23.4, 11.1, 18.6, 15.0, 31.1, 43.6, 42.0)
df <- data.frame(
COUNTRY = rep(countries, each = 3),
YEAR = rep(years, times = 3),
y = values
)
ggplot(df, aes(x = COUNTRY, y = y, group = YEAR, shape = as.factor(YEAR))) +
geom_bar(data = subset(df, YEAR == 2021), aes(fill = "2021"), stat = 'identity', position = 'dodge', alpha = 0.7) +
geom_point(data = subset(df, YEAR == 2020), aes(fill = "2020"), position = position_dodge(width = 0.4), size = 3, shape = 19, color = "red") +
geom_point(data = subset(df, YEAR == 2019), aes(fill = "2019"), position = position_dodge(width = 0.4), size = 3, shape = 4, color = "blue") +
scale_fill_manual(values = c("2021" = "grey", "2020" = "red", "2019" = "blue")) +
labs(x = "Country", y = "y", fill = "") +
theme_minimal() +
theme(legend.position = "right")
I would like the legend to just show a "bar"/filled box for YEAR = 2021, and the two different shapes for the years 2020 and 2019 respectively.
Here is one option to achieve your desired result which properly maps on aesthetics instead of setting colors and shapes as arguments in geom_point
and takes care that all three legends (fill
, color
and shape
) get merged. Finally I use the override.aes
argument of guide_legend
to remove the fill colors for the points in the legend.
library(ggplot2)
ggplot(df, aes(x = COUNTRY, y = y, group = YEAR, shape = factor(YEAR))) +
geom_col(
data = subset(df, YEAR == 2021), aes(fill = factor(YEAR)),
position = "dodge", alpha = 0.7
) +
geom_point(
data = subset(df, YEAR %in% 2019:2020),
aes(color = factor(YEAR)),
position = position_dodge(width = 0.4), size = 3
) +
scale_fill_manual(
values = c("2021" = "grey", "2020" = "red", "2019" = "blue"),
aesthetics = c("color", "fill")
) +
scale_shape_manual(
values = c("2020" = 19, "2019" = 4, "2021" = NA),
) +
labs(x = "Country", y = "y", fill = NULL, color = NULL, shape = NULL) +
theme_minimal() +
theme(legend.position = "right") +
guides(
fill = guide_legend(override.aes = list(fill = c(NA, NA, "grey")))
)