ggplot2 geom_ribbon() in R: Filled Area Between Two Lines
The geom_ribbon() function in ggplot2 fills the AREA between two y values (ymin and ymax) at each x. It is the standard tool for confidence bands, prediction intervals, and any "range over time" plot.
ggplot(df, aes(x, ymin = lo, ymax = hi)) + geom_ribbon()
ggplot(df, aes(x, y, ymin = lo, ymax = hi)) + geom_ribbon(alpha = 0.3) + geom_line()
geom_ribbon(fill = "steelblue", alpha = 0.4)
geom_area(...) # different: from 0 baselineNeed explanation? Read on for examples and pitfalls.
What geom_ribbon() does in one sentence
geom_ribbon() draws a filled area at each x bounded by ymin (bottom) and ymax (top). The most common use: confidence bands around a fit line.
Syntax
geom_ribbon(mapping = NULL, data = NULL, alpha = 0.3, ...). Requires aes(ymin, ymax).
geom_ribbon with geom_line for the central trend. The ribbon shows uncertainty; the line shows the estimate.Five common patterns
1. Confidence band
2. Prediction interval
3. Min-max range
4. Multiple ribbons (groups)
5. Combine with stat_smooth
geom_smooth() internally uses geom_ribbon + geom_line to draw the fit line and confidence band. When you need MORE control (custom intervals, prediction bands), build with geom_ribbon + geom_line directly.geom_ribbon() vs geom_area() vs geom_errorbar()
| Function | Bounds | Best for |
|---|---|---|
geom_ribbon() |
ymin to ymax | Confidence bands, ranges |
geom_area() |
0 to y | Filled areas from baseline |
geom_errorbar() |
ymin to ymax (vertical bars) | Per-point uncertainty |
A practical workflow
The "fit + band" pattern is geom_ribbon's signature use.
Manual confidence band from a linear model.
Common pitfalls
Pitfall 1: forgetting alpha. Default fill is solid. Set alpha = 0.3 for translucency so the line and points underneath remain visible.
Pitfall 2: forgetting the line. A ribbon alone is just a shaded area. Add geom_line for the central trend.
geom_ribbon fills BETWEEN ymin and ymax, the line itself is NOT drawn. Always pair with geom_line for the visible trend.Try it yourself
Try it: Plot mtcars wt vs mpg with a fit line and 95% confidence band using lm. Save to ex_plot.
Click to reveal solution
Explanation: ribbon for the band; line for the fit; points for raw data.
Related ggplot2 functions
After mastering geom_ribbon, look at:
geom_area(): from baseline 0geom_smooth(): auto fit + bandgeom_errorbar()/geom_errorbarh(): per-point barsgeom_pointrange(): point with rangestat_summary(): compute summaries on the fly
FAQ
What does geom_ribbon do in ggplot2?
geom_ribbon() fills the area between ymin and ymax at each x. Used for confidence bands, prediction intervals, and ranges over time.
What is the difference between geom_ribbon and geom_area?
geom_ribbon fills between ymin and ymax (two curves). geom_area fills from baseline 0 to y (one curve).
How do I make geom_ribbon translucent?
Set alpha = 0.3 (or smaller). Default is opaque, which obscures lines underneath.
Should I use geom_smooth or geom_ribbon for confidence bands?
geom_smooth for automatic fit + band. geom_ribbon for manual control over the band's data.
Can I use geom_ribbon with multiple groups?
Yes. Pass fill = group in aes; each group gets its own ribbon. Pair with geom_line(color = group) for trends.