Reputation: 59
I want to display both an annual value (school hours) and its cumulative (total school hours) in the same graph. This works, so now I want to tidy-up the legend a little bit. I want to drop the three groups associated with the cumulative values and only report a custom label for each state I use. Thus, the legend should only read "NW, G8", "NW, G9", and "CA", next to the colour they are associated with.
I have found other solutions to this problem which no longer seem to work with the current ggplot version (at least I believe this to be a version-issue, maybe I made another mistake):
https://community.rstudio.com/t/how-keep-aesthetic-mapping-but-remove-a-specific-item-from-legend-with-ggplot/52818/3 -> trying to replicate the solution with the provided code results in a gray barplot "c" and not a blue bar plot for me.
Remove legend entries for some factors levels -> again, similar solution, but if I update my scale_color_manual to the following alternative, I again have gray lines for my cumulative values
scale_color_manual(breaks = c("hours_nw_G8", "hours_nw_G9", "hours_ca"),
values = c("#073B4C", "#118AB2", "#FFD166", "#073B4C", "#118AB2", "#FFD166")) +
Code:
require(tidyverse)
## school hours: comparison of US state (CA) and DE State (NW)
df_hours <- data.frame(year=c(1:13),
hours_nw_G8=c(21.5,22.5,25.5,26.5,31.5,31.5,32.5,32.5,33.5,34,34,34,NA),
hours_nw_G9=c(21.5,22.5,25.5,26.5,28,29,30,30,31,31,31.5,29.5,29.5),
hours_ca=c(840,840,840,900,900,900,900,900,1080,1080,1080,1080,NA)
)
df_hours$hours_nw_G8 <- df_hours$hours_nw_G8 * 38 * 0.75 # scaling by #weeks and accounting for German school hour
df_hours$hours_nw_G9 <- df_hours$hours_nw_G9 * 38 * 0.75
# cumulate
df_hours$c_hours_nw_G8 <- cumsum(df_hours$hours_nw_G8) / 8 # cummulate and divide by scaling factor
df_hours$c_hours_nw_G9 <- cumsum(df_hours$hours_nw_G9) / 8
df_hours$c_hours_ca <- cumsum(df_hours$hours_ca) / 8
# reshape & dummy for cumulative
df_hours <- gather(df_hours, state, hours, hours_nw_G8:c_hours_ca, factor_key=TRUE)
df_hours$cu <- c(rep("annual",13*3),rep("cumulative",13*3))
# Figure
ggplot(df_hours, aes(x=year)) +
geom_line(aes(y=hours, color=state, linetype=cu), linewidth = 1) +
scale_y_continuous(limits = c(0,1500), expand = c(0,0),
breaks = c(0,250,500,750,1000,1250,1500),
name="Hours (annual)",
sec.axis = sec_axis(~ .*8, name = "Hours (cummulative)",
breaks = c(0,2000,4000,6000,8000,10000,12000))
) +
scale_x_continuous(limits = c(0.5,13.5), expand = c(0,0), breaks = c(1:13)) +
labs(x="School Year", y="Hours") +
theme_tufte() +
scale_color_manual(values = c("#073B4C", "#118AB2", "#FFD166", "#073B4C", "#118AB2", "#FFD166")) +
theme(axis.line = element_line(linewidth = 0.75), text = element_text(size = 10, color = "black"),
legend.position = c(.3, .9), legend.title = element_blank()) +
guides(linetype = F)
Upvotes: 1
Views: 54
Reputation: 78927
One solution could be using some stringr
function to modify the strings:
library(ggthemes)
library(tidyverse)
df_hours %>%
mutate(state_label = str_remove(state, "c_hours_|hours_"),
state_label = str_to_upper(state_label),
state_label = str_replace(state_label, "_", ", ")) %>%
ggplot(aes(x=year)) +
geom_line(aes(y=hours, color=state_label, linetype=cu), linewidth = 1) +
scale_y_continuous(limits = c(0,1500), expand = c(0,0),
breaks = c(0,250,500,750,1000,1250,1500),
name="Hours (annual)",
sec.axis = sec_axis(~ .*8, name = "Hours (cummulative)",
breaks = c(0,2000,4000,6000,8000,10000,12000))
) +
scale_x_continuous(limits = c(0.5,13.5), expand = c(0,0), breaks = c(1:13)) +
labs(x="School Year", y="Hours") +
theme_tufte() +
scale_color_manual(values = c("#073B4C", "#118AB2", "#FFD166", "#073B4C", "#118AB2", "#FFD166")) +
theme(axis.line = element_line(0.75), text = element_text(size = 10, color = "black"),
legend.position = c(.3, .9), legend.title = element_blank()) +
guides(linetype = F)
Upvotes: 1