3
votes

I was originally going to use a ribbon for this function, but ribbon was giving me an "Aesthetics can not vary within a ribbon" error. I tried a geom_smooth, geom_ribbon, and geom_line, and none of them worked for what I needed. The picture posted below is what I need, except that I would like those square joints between where the line changes colors to be either vertical and flush or round.

I looked at these posts already:

Shade Fill or Cover Area Density Under Curve

R ggplot Issue When Using Group Interaction

I've also tried using groups in a couple different ways. I should mention that I'm extremely new to ggplot2 and R in general, so any help or possible avenues would be appreciated. I've been using these resources, which you might find useful for this problem or for your own:

R For Data Science

GGPlot2: Elegant Graphics For Data Analysis

GGPlot2 Documentation

R Cookbook

Code:

library(ggplot2)

pdf("ggplot_learning.pdf")

data <- data.frame(
  xvals = c(0:5),
  yvals = c(4, 5, 4.5, 5.5, 5, 6),
  lower = c(3.9, 4.9, 4.4, 5.4, 4.9, 5.9),
  upper = c(4.1, 5.1, 4.6, 5.6, 5.1, 6.1)
)


plot <- ggplot(data, aes(xvals, yvals, ymax = 8, xmax = 8)) + 
  geom_line(aes(color = yvals, alpha = .3), lwd = 10) + 
  geom_line(aes(color = yvals)) + 
  theme(legend.position = "none")

print(plot)

What I have so far:

Graph With Rough Idea of What I Need

2
So you want to fill the area under the curve with five different colors, right?Roman
Originally, it would've been a ribbon that surrounded the line. The ymin and ymax of the ribbon are going to be std deviations (I'm actually not sure if std deviations is the right word, perhaps variation?), so it should be centered around the line. The colors should vary based on the y-values, so if there were more than 5 y-values there would be more than 5 colors. Here though it would be 5 :-)Alex Eastman
No, I didn't find that in my searches, thanks!Alex Eastman

2 Answers

4
votes

I'm not sure but maybe this:

data2 <- rbind(data, data[-1,]) 
data2 <- data2[order(data2$xvals),]
data2$n <- factor(head(rep(1:6, each=2),-1))

ggplot(data2, aes(xvals, yvals,color=n, fill=n, group=n)) + 
  geom_line() + 
  geom_ribbon(aes(ymin=lower, ymax=upper), alpha = 0.5)

enter image description here

Since you need groups for the geom_ribbon function, you need to specify each section. Thus, from 0 to 1, from 1 to 2 ... Therfore, I rbind the data twice, sort according to x and add a grouping factor n.

1
votes

Here's something that looks a little better with geom_path, but it seems to ignore the linejoin = argument when the colors change:

ggplot(data, aes(x = xvals, y = yvals)) + 
  geom_path(aes(color = yvals, alpha = .3), lwd = 10,
            lineend="round",linejoin="miter") + 
  geom_line(aes(color = yvals)) + 
  theme(legend.position = "none")

enter image description here