2
votes

I have a plot I'm trying to make using geom_ribbon where two categories may have a higher value than the other and the two may 'switch places' multiple times in the plot.

See example 1 : enter image description here

You can see there that the ribbon is perfectly within the bounds of the two lines throughout. However, when I change the fill aesthetic to be dependent on which category has the higher value, the ribbon 'jumps' between the two points when that color is needed.

See example 2 : enter image description here

This is how I would expect two separate ribbons to react, as I expect it will want to fill in holes between where that ribbon has data for, but I would have expected one ribbon with different categorical fills to just, well, color in the ribbon that exists without a fill aesthetic.

I'd like to know how to split the fill properly, without each part of the ribbon 'reaching' across. There won't necessarily be the same number of changes, and the positions of the changes could be variable, so coding a new ribbon for each change would be a pain.

Examples like this only deal with one switch of fill.

min <- c(10,10,20,20,30,30,40,40,50,50,60,60)
t1cumi <- c(3,3,3,4,4,4,4,8,8,9,9,9)
t2cumi <- c(1,1,1,5,5,5,5,5,5,5,5,10)
lead_team <- c("Team1","Team1","Team1","Team2","Team2","Team2","Team2","Team1","Team1","Team1","Team1","Team1")
minimum <- c(1,1,1,4,4,4,4,5,5,5,5,9)
maximum <- c(3,3,3,5,5,5,5,8,8,9,9,10)

newtab3 <- data.frame(min,t1cumi,t2cumi,lead_team,minimum,maximum)
ggplot(newtab3)+
  geom_ribbon(aes(x=min,ymin=minimum,ymax=maximum,fill=lead_team))+
  geom_step(aes(x=min,y=t1cumi),colour="blue")+
  geom_step(aes(x=min,y=t2cumi),colour="red")
1

1 Answers

1
votes

I think geom_rect() is a better match. Something like:

time <- c(10, 20, 30, 40, 50, 60)
team1 <- c(3, 4, 4, 8, 9, 9)
team2 <- c(1, 5, 5, 5, 5, 10)

df <- data.frame(time, team1, team2) %>% 
  mutate(lead_team = ifelse(team1 > team2, "Team1", "Team2"))


ggplot(df) + 
  geom_rect(aes(xmin = time, xmax = lead(time), ymin = team1, ymax = team2, 
    fill = lead_team), alpha = .6) + 
  geom_step(aes(x = time, y = team1), color = "red", lwd = 1.5) + 
  geom_step(aes(x = time, y = team2), color = "blue", lwd = 1.5) + 
  scale_fill_manual(values = c("red", "blue")) + ylab("Score")

enter image description here

Note that lead(time) is a dplyr verb that takes the next time value; it has nothing to do with lead_team. Also, I think your blue and red lines are switched. If I understand what you're trying to do, the lead team color should always be on top.