问题
I have a dataframe like this :
> head(df_graph)
treatment year mean se
1: AC 2005 0.3626147 0.03005057
2: AC 2006 0.3925465 0.02370335
3: AC 2007 0.3217444 0.02279881
4: AC 2008 0.3895656 0.05985077
5: AC 2009 0.3820191 0.01481586
6: AC 2010 0.3732695 0.03544626
...
And a (long) ggplot script :
df_graph %>%
# way to make 2 lines becoming 4 in a smooth way
filter(treatment %in% c("Ambient", "Elevated")) %>%
mutate(treatment = ifelse(treatment == "Ambient", "AA", "EE")) %>%
bind_rows(df_graph) %>%
mutate(treatment_group = ifelse(treatment %in% c("Ambient", "AC", "AF", "AA"),"treatment1","treatment2"),
line_type = ifelse(treatment %in% c("AA", "EE", "AF", "EF"),"type1","type2")) %>%
# plot
ggplot(aes(x = year, y = mean,group = interaction(treatment_group, line_type),color = treatment_group)) +
geom_line(aes(x = year, y = mean, linetype = line_type),size = 1.5, lineend = "round") +
geom_point(size=5)+
geom_errorbar(aes(ymin = mean-se, ymax = mean+se),width = 0.2, size = 1.5)+
# scaling visual
scale_color_manual(values=c('blue1','red3'))+
scale_linetype_manual(values = c('dashed', 'solid'))+
scale_x_continuous(breaks = c(1999:2010), limits = c(1998.5, 2010.5),labels = 1999:2010)+
# axes and legend
labs(title ="", x="year", y = expression(paste("result")))+
theme_classic() + theme(text = element_text(size=20))
I made it this way so that 2 treatments can become 4 after 2004. My problem concerns my legend. By running this script, I get a 'two parts' legend with 1) the color (treatment_group) and the 2) the line type (line_type).
What I need is a legend with only the 4 treatments displayed after 2004.
What I get:
What I would like to get (ideally):
I realize my dataframe is not the best format, but to get a smooth transition from 2004 to 2005, that's the only way I found. Hence a good solution would be changing the ggplot script, not the shape of the dataframe.
I've seen this : Controlling line color and line type in ggplot legend
But it will also add the 'ambient' and 'elevated' treatment, and so duplicate the straight lines in the legend. Thank you for your help.
回答1:
Here is one approach for you. I created a sample data given your data above was not enough to reproduce your graphic. I'd like to give credit to the SO users who posted answers in this question. The key trick in this post was to assign identical groups to shape and line type. Similarly, I needed to do the same for color and linetype in your case. In addition to that there was one more thing do to. I manually assigned specific colors and line types. Here, there are four levels (i.e., treatment1.AC, treatment1.AE, treatment2.EC, treatment2.EF) in the end. But I used interaction()
and created eight levels. Hence, I needed to specify eight colors and line types. When I assigned a name to the legend, I realized that I need to have an identical name in both scale_color_manual()
and scale_linetype_manual()
.
library(ggplot2)
set.seed(111)
mydf <- data.frame(year = rep(1999:2010, time = 4),
treatment.type = rep(c("AC", "AF", "EC", "EF"), each = 12),
treatment = rep(c("treatment1", "treatment2"), each = 24),
mean = c(runif(min = 0.3, max = 0.55, 12),
rep(NA, 5), runif(min = 0.3, max = 0.55, 7),
runif(min = 0.3, max = 0.55, 12),
rep(NA, 5), runif(min = 0.3, max = 0.55, 7)),
se = c(runif(min = 0.01, max = 0.03, 12),
rep(NA, 5), runif(min = 0.01, max = 0.03, 7),
runif(min = 0.01, max = 0.03, 12),
rep(NA, 5), runif(min = 0.01, max = 0.03, 7)),
stringsAsFactors = FALSE)
ggplot(data = mydf, aes(x = year, y = mean,
color = interaction(treatment, treatment.type),
linetype = interaction(treatment, treatment.type))) +
geom_point(show.legend = FALSE) +
geom_line() +
geom_errorbar(aes(ymin = mean-se, ymax = mean+se),width = 0.1, size = 0.5) +
scale_color_manual(name = "Treatment conditions", values = rep(c("blue", "blue", "red", "red"), times = 2)) +
scale_linetype_manual(name = "Treatment conditions", values = rep(c(1,2), times = 4))
来源:https://stackoverflow.com/questions/48450762/combining-linetype-and-color-in-ggplot2-legend