0

I have looked at this articles: Legend formatting for ggplot with geom_col and geom_line and: Controlling legend appearance in ggplot2 with override.aes

I have a plot with a geom_col layer and 4 geom_line layers. I would like to be able to show a legend with no title using the colors that I chose when generating each layer in Plot 1. Alternatively, if I could change the colors and legend title in Plot 2 that might work. I would also like to change the Y-axis scale since the production data will never drop below 20 acre-feet but when I use scale_y_continuous with geom_col the bars do not appear.

Data

structure(list(Month_Day = structure(c(18628, 18629, 18630, 18631, 
18632, 18633, 18634, 18635, 18636, 18637), class = "Date"), `2021` = c(37.57464179, 
35.95859072, 39.14746726, 37.9630674, 40.55096688, 42.53487456, 
41.66243889, 40.18150773, 37.90217088, 38.30979013), Mean = c(36.9619627272733, 
36.2260000000002, 36.4146654545455, 36.3741972727362, 36.9979654545361, 
36.5846318181822, 35.7040999999992, 36.3543818181826, 36.3387527272723, 
36.5865854545457), Median = c(36.44704, 35.9190000000022, 35.56288, 
36.19223, 35.82997, 36.21986, 35.69489, 35.07475, 36.29047, 36.18302
), Maximum = c(40.2170000000067, 42.43354, 41.04897, 39.2959999999978, 
42.3659999999978, 40.524, 41.24238, 41.48184, 38.49166, 39.26223
), Minimum = c(34.1998, 31.78064, 33.38932, 34.74012, 33.96955, 
31.54425, 31.48285, 33.49063, 35.02563, 34.7831)), row.names = c(NA, 
10L), class = "data.frame")

Plot 1

library(ggplot2)
library(scales)

p_2021 <- ggplot(dfinal21, aes(x = Month_Day)) +
geom_col(aes(y = `2021`), size = 1, color = "darkblue", fill = "white") +
geom_line(aes(y = `Median`), size = 1.0, color="red") +
geom_line(aes(y = `Mean`), size = 1.0, color="yellow") +
geom_line(aes(y = `Maximum`), size = 1.0, color="darkgreen") +
geom_line(aes(y = `Minimum`), size = 1.0, color = "darkviolet") +
scale_x_date(breaks = "1 month", minor_breaks = "1 day", labels=date_format("%b")) +
labs(x = "Month", y = "acre-feet", title = "Treatment Plant Production 2021")

Generates this plot:

Treatment Plant Production without legend

Plot 2

library(ggplot2)
library(scales)
p_2021 <- ggplot(dfinal21) +
geom_col(aes(x = Month_Day, y = `2021`, color = "2021")) +
geom_line(aes(x = Month_Day, y = `Median`, color = "Median")) +
geom_line(aes(x = Month_Day, y = `Mean`, color= "Mean")) +
geom_line(aes(x = Month_Day, y = `Maximum`, color= "Maximum")) +
geom_line(aes(x = Month_Day, y = `Minimum`, color= "Minimum")) +
scale_x_date(breaks = "1 month", minor_breaks = "1 day", labels=date_format("%b")) +
labs(x = "Month", y = "acre-feet", title = "Treatment Plant Production 2021") +
theme(legend.background = element_rect(fill = "white"))

Generates this plot:

Treatment Production 2021 with legend and GGPLOT2 colors, legend title

John Orr
  • 23
  • 7

2 Answers2

0

It turns out that I did not have my data in the format that ggplot2 likes (Tidy data). An acquaintance helped me out. Here's the new code:

dfinal21a <- dfinal21 %>%
  mutate(y2021 = `2021`) %>% #rename column
  select(-(`2021`)) %>% # remove old col name
  pivot_longer(cols = Mean:y2021, names_to = "measure", values_to = "data") #tidy the data

p_2021 <- ggplot() +
  geom_col(data = filter(dfinal21a, measure == "y2021"),
           aes(y = data, x = Month_Day),
           color = "darkblue", fill = "white") +
  geom_line(data = filter(dfinal21a, measure != "y2021"),
            aes(y = data, x = Month_Day, color = measure)) +
  scale_color_manual(values = c("red", "yellow", "darkgreen", "darkviolet")) +
  coord_cartesian(ylim = c(20,120)) + #changed range to include maximums 
  theme(legend.title = element_blank()) + 
  scale_color_discrete(name = "Year") +
  scale_x_date(breaks = "1 month", minor_breaks = "1 day", labels=date_format("%b")) +
  labs(x = "Month", y = "acre-feet", title = "Treatment Plant Production 2021")
John Orr
  • 23
  • 7
0

Here is a solution! If this is what you are looking for let me know. I then can explain the code:

enter image description here

The code:

library(tidyverse)
library(scales)

# data manipulation
dfinal21_long <- dfinal21 %>% 
  pivot_longer(
    cols = c(`2021`, Mean, Median, Maximum, Minimum),
    names_to = "names", 
    values_to = "values"
  ) %>% 
  mutate(color = case_when(names=="Mean" ~ "red",
                           names=="Median" ~ "yellow",
                           names=="Maximum" ~ "darkgreen",
                           names=="Minimum" ~ "darkviolet")) %>% 
  arrange(names)

# function for custom transformation of y axis
shift_trans = function(d = 0) {
  scales::trans_new("shift", transform = function(x) x - d, inverse = function(x) x + d)
}

# plot

ggplot()  + 
  geom_col(data= dfinal21_long[1:10,],mapping = aes(x=Month_Day,y=values), size = 1, color = "darkblue", fill = "white" ) +
  geom_line(data= dfinal21_long[11:50,],mapping=aes(x=Month_Day,y=values, color=color), size = 1.0) +
  scale_x_date(breaks = "1 month", minor_breaks = "1 day", labels=date_format("%b")) +
  labs(x = "Month", y = "acre-feet", title = "Treatment Plant Production 2021") + 
  scale_y_continuous(trans = shift_trans(20))+
  scale_color_manual(labels = c("Maximum","Mean","Median","Minimum"), values = c("red","yellow","darkgreen","darkviolet")) +
  theme_minimal() +
  theme(legend.position="bottom") +
  theme(legend.title=element_blank())
TarJae
  • 72,363
  • 6
  • 19
  • 66
  • TarJae, your solution didn't work for me. The geom_line does not generate. Here's the error: "Error: Can't subset columns that don't exist. x Locations 11, 12, 13, 14, 15, etc. don't exist.ℹ There are only 4 columns." Sorry it took me so long to try your code. I had a solution (see below) and have not gotten back to the project. – John Orr Jun 15 '21 at 18:38
  • That's strange. I used your posted data and again got the posted plot. `dfinal21 <- structure(list(Month_Day = structure(c(18628,.............`. And take care of the comma in `[11:50,]` – TarJae Jun 15 '21 at 18:47
  • I only see one geom_line line in your code above. – John Orr Jun 29 '21 at 20:17