jjmerelo
jjmerelo

Reputation: 23517

Discrete values and geom_ribbon and geom_lines + problems with "discrete" scale

I have got a file like this one:

Month,Open,Closed
2017-08,53,38
2017-09,102,85
2017-10,58,38
2017-11,51,42
2017-12,32,24
2018-01,24,30
2018-02,56,46
2018-03,82,74
2018-04,95,89
2018-05,16,86

I want to plot both lines, and also shade the difference between them. So this works:

ggplot()  +geom_line(data=issues.m,aes(x=Month,y=Open,group=1))
 +geom_line(data=issues.m,aes(x=Month,y=Closed,group=1)) 
 +geom_ribbon(data=issues.m, aes(x=Month,ymin=Closed,ymax=Open,color=Open-Closed))
 +theme_tufte() 
 +theme(axis.text.x = element_text(angle = 90, hjust = 1))

producing thisFirst attempt

First problem here is that I would like the whole area between the two lines shaded if possible, not a single line. How can I do that?

But I would also like to color the two lines. If I add a color to one of them:

ggplot() 
 +geom_line(data=issues.m,aes(x=Month,y=Open,group=1,color='open')) 
 +geom_line(data=issues.m,aes(x=Month,y=Closed,group=1)) 
 +geom_ribbon(data=issues.m, aes(x=Month,ymin=Closed,ymax=Open,color=Open-Closed))
 +theme_tufte() 
 +theme(axis.text.x = element_text(angle = 90, hjust = 1))

I get the error:

Error: Continuous value supplied to discrete scale

So, can what I want to do be done at all? Would it be possible to change the colour palette of the ribbon too?

Upvotes: 0

Views: 1524

Answers (1)

camille
camille

Reputation: 16842

Your error was because you were mapping Open - Closed onto the color, which will be a continuous variable, i.e. the difference between those two values for each month. But you also assigned "open" to color inside the aes in one of your geom_lines. That means you're trying to assign both continuous values and discrete values to the same scale, and that's not going to work.

If all you need to do is get 2 colors, one for each line, you can do this one of two ways, the second of which fits more into the ggplot/tidyverse way of doing things.

First off I turned your dates into date objects to clean up the x-axis and avoid rotating the labels—feel free to experiment with the date breaks that work well in scale_x_date.

The less "tidy" way is to just make two geom_lines, one for Open and one for Closed, and assign a color to each.

library(tidyverse)


df_dated <- df %>%
  mutate(month2 = sprintf("%s-01", Month) %>% lubridate::ymd())

ggplot(df_dated, aes(x = month2)) +
  geom_ribbon(aes(ymin = Open, ymax = Closed), fill = "lightblue2") +
  geom_line(aes(y = Open), color = "green3") +
  geom_line(aes(y = Closed), color = "red") +
  ggthemes::theme_tufte()

But the more idiomatically "tidy" way is to make a long-shaped version of the data so you can map a variable—in this case whether an observation is the opening or closing value—onto an aesthetic such as color. This also gives you a legend—if you don't want it, you can get rid of it in the theme. This lets you set a scale for the colors, instead of hard-coding into each geom_line.

df_date_long <- df_dated %>%
  gather(key, value, -month2, -Month)

ggplot(df_dated, aes(x = month2)) +
  geom_ribbon(aes(ymin = Open, ymax = Closed), fill = "lightblue2") +
  geom_line(aes(y = value, color = key), data = df_date_long) +
  scale_color_manual(values = c(Open = "green3", Closed = "red")) +
  ggthemes::theme_tufte()

Upvotes: 1

Related Questions