Home > database >  Add a main legend for colored line types on ggplot2 facet_wrap plot
Add a main legend for colored line types on ggplot2 facet_wrap plot

Time:07-26

How can I add a main common legend to suitable blank area for facet_wrap plot? I need 3 line types with 3 different colors in the legend. (black dotted line: Current Price, green dotted line: lowline, red dotted line: highline)

Reproducible example:

library(quantmod)
library(purrr)
library(tidyverse)
library(stats)

start_date <- as.Date("2018-02-02")
end_date <- as.Date("2018-09-24")

adjustment <- TRUE
symbol <- c("AAPL", "AMZN", "MSFT")


getSymbols(symbol, src = "yahoo",
           from = start_date, to=end_date,
           adjust = adjustment)

DFCONVERT<- function (sym) {
  library(xts)
  newdata<-list()

  newdata[[sym]]<-data.frame(Date=index(eval(as.symbol(sym))), coredata(eval(as.symbol(sym))))
  columnnames<- c("Date", "Open", "High", "Low", "Close", "Volume", "Adjusted")
  newdata[[sym]] <- newdata[[sym]] %>%
    rename_with(~ gsub(paste0(sym, "."), '', .x))
  
  }

symbol <- setNames(symbol, symbol)
newdata<-map_df(symbol, DFCONVERT, .id="symbol")

CurrentPrice=c(54.41500, 95.7505, 114.26)
lowline=c(40, 80, 98)
highline=c(50, 90, 110)

df<-data.frame(symbol, CurrentPrice, lowline, highline)

ggplot(newdata)   
  geom_line(aes(Date,Close))  
  geom_hline(data = df, aes(yintercept = CurrentPrice), linetype = 'dotted', color="black") 
  geom_hline(data = df, aes(yintercept = lowline), linetype = 'dashed', color="green") 
  geom_hline(data = df, aes(yintercept = highline), linetype = 'dashed', color="red") 
  facet_wrap(~symbol, scales = "free_y")  
  theme(axis.text.x=element_text(size=8, angle=90,hjust=0.95,vjust=0.2)) 
  theme(axis.text.y=element_text(size=6))

CodePudding user response:

If you want to have a legend the first step is to map on aesthetics instead of setting your color and linetypes as arguments, i.e. move color=... and linetype=... inside aes(). Second step is to set your desired colors and linetypes via scale_xxx_manual. Note, that to get only one legend we have to use the same name (which I simply set to NULL, i.e. no legend title) and the same labels:

library(ggplot2)

df <- data.frame(symbol, CurrentPrice, lowline, highline)

labels <- c("Current Price", "lowline", "highline")
names(labels) <- c("current", "low", "high")

ggplot(newdata)  
  geom_line(aes(Date, Close))  
  geom_hline(data = df, aes(yintercept = CurrentPrice, linetype = "current", color = "current"))  
  geom_hline(data = df, aes(yintercept = lowline, linetype = "low", color = "low"))  
  geom_hline(data = df, aes(yintercept = highline, linetype = "high", color = "high"))  
  scale_linetype_manual(values = c(current = "dotted", high = "dashed", low = "dashed"), labels = labels, name = NULL)  
  scale_color_manual(values = c(current = "black", high = "red", low = "green"), labels = labels, name = NULL)  
  facet_wrap(~symbol, scales = "free_y")  
  theme(axis.text.x = element_text(size = 8, angle = 90, hjust = 0.95, vjust = 0.2))  
  theme(axis.text.y = element_text(size = 6))

enter image description here

  • Related