Легенда только с некоторыми рядами данных - ggplot - R - PullRequest
1 голос
/ 29 апреля 2020

У меня есть этот сюжет с барами уклонения для 2 серий: 2019-2018 и линиями для 3 разных серий: 2015-2017 с регистрацией по неделям для каждого года. При работе над легендой мне нужно отображать ключи только для 2018-2019 (столбцы) и 2017 (черная линия). Для других серий я буду работать с текстом аннотации, который отлично работает. Итак, моя проблема заключается в добавлении только одной строки в легенду, когда у меня есть как минимум 2 объекта geom_line (один на 2017 год и второй на 2015-2016 годы) или 3 объекта geom_line, по одному на каждый год формы 2015-2017. Происходит одно из двух: либо легенда для 2019 года не отображается, либо во второй версии кода строка находится внутри клавиш для баров в легенде. См. Ниже мой код:

# This is my simulated data - plot looks horrible but with real data looks way better -please do not judge
data <- data.frame(week=rep(1:52,5),
                   year=rep(2015:2019, each=52),
                   freq=sample(100,260, TRUE))
data$year <- as.character(data$year)
data$freq[data$year=="2019"] <- sample(30,52, TRUE)
data$freq[data$year=="2018"] <- sample(30,52, TRUE)

# Making the bars
ggplot() + 
  geom_bar(data = subset(data, year %in% c("2019", "2018")), aes(x=week, y=freq, fill = year),       
  stat= "identity", position=position_dodge()) + 
   # I need the keys for bars in the legend
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) + 

  # This is the line that I need to be included in legend, for 2017
  geom_line(data = subset(data, year=="2017"), aes(x=week, y=freq), color = "black",           
  show.legend = FALSE ,size = 2) + 

  # Here I have the geom_line for 2015-2016 years
  # Here I have two problems, first, I am missing one series, and second these two
  # should not be included in the legend
  geom_line(data = subset(data, year %in% c("2016", "2015")), aes(x=week, y=freq, color="year"), 
            show.legend = FALSE, alpha = 0.4, size = 1.5) + 

  # adding some other details that are not important actually for my question
  scale_y_continuous(breaks = seq(0, 75,10), labels =seq(0,70,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.text.x  = element_text(colour="black", size = 12, face = "bold"),
        axis.text.y  = element_text(colour="black", size = 12, face = "bold"),
        axis.title.x = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 20, r = 0, b = 20, l = 0)),
        axis.title.y = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 0, r = 20, b = 0, l = 0)),
        plot.title   = element_text(colour="black", size = 22, face = "bold", hjust=0.5),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 18, face = "bold"),
        legend.position = c(0.5, 0.98),
        legend.direction = "horizontal") +
  labs(title = "Title",x = "weeks",y = "number")

Plot using code v1

Второй вариант - построчное использование geom_line для каждой интересующей серии, но все же я делаю Не знаю, как добавить серию 2017 только к легенде. Ниже мой код для этой опции:

# bar plot
ggplot() + 
  geom_bar(data = subset(data, year %in% c("2019", "2018")), aes(x=week, y=freq, fill = year), stat= "identity", position=position_dodge()) + 
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) + 
# Year 2017- I need the key for this one in legend  
  geom_line(data = subset(data, year=="2017"), aes(x=week, y=freq), color = "black", show.legend = TRUE ,size = 2) + 

# Year 2016- I don't need it in legend 
  geom_line(data = subset(data, year=="2016"), aes(x=week, y=freq), color = "green", show.legend = FALSE ,size = 2) +

# Year 2015- I don't need it in legend 
  geom_line(data = subset(data, year=="2015"), aes(x=week, y=freq), color = "red", show.legend = FALSE ,size = 2) +
# additional details not important to the question that I have 
  scale_y_continuous(breaks = seq(0, 110,10), labels =seq(0,110,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.text.x  = element_text(colour="black", size = 12, face = "bold"),
        axis.text.y  = element_text(colour="black", size = 12, face = "bold"),
        axis.title.x = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 20, r = 0, b = 20, l = 0)),
        axis.title.y = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 0, r = 20, b = 0, l = 0)),
        plot.title   = element_text(colour="black", size = 22, face = "bold", hjust=0.5),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 18, face = "bold"),
        legend.position = c(0.5, 0.98),
        legend.direction = "horizontal") +
  labs(title = "Title",x = "weeks",y = "number")

Plot using code V2

Огромное спасибо за помощь!

1 Ответ

0 голосов
/ 29 апреля 2020

Возможным решением будет использование функции new_scale_color из пакета ggnewscale для дифференциации построения линий 2015/2016 с графиком линии 2017.

Вкратце, вы можете построить первые линии на 2015 и 2016 с опцией show.legend = FALSE, установите их цвет с scale_color_manual. затем передайте функцию new_scale_color, построите линию 2017 года и установите соответствующий атрибут для этого цвета.

В целом ваш код может выглядеть примерно так:

library(ggnewscale)
library(ggplot2)

ggplot(data, aes(x = week, y = freq))+
  geom_col(position = position_dodge(), aes(fill = year), color = NA, data = subset(data, year %in% 2018:2019))+
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) +
  geom_line(data = subset(data, year %in% 2015:2016), aes(group = year, color = year), show.legend = FALSE)+
  scale_color_manual(name = "", values = c("2015" = "red","2016" = "green"))+
  new_scale_color()+
  geom_line(data = subset(data, year == 2017), aes(group = year, color = year))+
  scale_color_manual(name = "", values = "black", label = "2017 enrollement")+
  scale_y_continuous(breaks = seq(0, 110,10), labels =seq(0,110,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        axis.text.x = element_text(angle = 60, hjust = 1),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 10, face = "bold"),
        legend.position = "top",
        legend.direction = "horizontal",
        plot.title   = element_text(colour="black", size = 10, face = "bold", hjust=0.5)) +
  labs(title = "Title",x = "weeks",y = "number")

enter image description here

Выглядит ли то, что вы пытаетесь достичь?

...