How to fill area between curves with Plots.jl?
Asked Answered
N

4

10

Suppose I have a curve y, and two other curves u and l in the form of vectors. How to plot:

plot(y, lab="estimate")
plot!(y-l, lab="lower bound")
plot!(y+u, lab="upper bound")

That is, an asymmetric confidence interval? I know how to plot the symmetric case with the option ribbon as explained here.

Nagari answered 19/1, 2018 at 4:14 Comment(0)
M
20

The current answers are NOT correct. Here are two ways that are correct (as of v1.10.1 of Plots.jl):

Method 1: Using fillrange

plot(x, l, fillrange = u, fillalpha = 0.35, c = 1, label = "Confidence band")

Method 2: Using ribbon

plot(x, (l .+ u) ./ 2, ribbon = (l .- u) ./ 2, fillalpha = 0.35, c = 1, label = "Confidence band")

(Here, l and u denote the the "lower" and "upper" y values, respectively, and x denotes their common x values.) The key difference between these two methods is that fillrange shades the region between l and u, while the ribbon argument is a radius, i.e. half the width of the ribbon (or in other words, the vertical deviation from the midpoints).

Example using fillrange:

x = collect(range(0, 2, length= 100))
y1 = exp.(x)
y2 = exp.(1.3 .* x)

plot(x, y1, fillrange = y2, fillalpha = 0.35, c = 1, label = "Confidence band", legend = :topleft)

Let's scatter y1 and y2 on top of the plot, just to make sure we're filling in the right region.

plot!(x,y1, line = :scatter, msw = 0, ms = 2.5, label = "Lower bound")
plot!(x,y2, line = :scatter, msw = 0, ms = 2.5, label = "Upper bound")

Result:

enter image description here

Example using ribbon:

mid = (y1 .+ y2) ./ 2   #the midpoints (usually representing mean values)
w = (y2 .- y1) ./ 2     #the vertical deviation around the means

plot(x, mid, ribbon = w , fillalpha = 0.35, c = 1, lw = 2, legend = :topleft, label = "Mean")
plot!(x,y1, line = :scatter, msw = 0, ms = 2.5, label = "Lower bound")
plot!(x,y2, line = :scatter, msw = 0, ms = 2.5, label = "Upper bound")

(Here, x, y1, and y2 are the same as before.)

Result:

enter image description here

Notice that the labels for ribbon and fillrange are different in the legends: the former labels the midpoints/means, while the latter labels the shaded region itself.

Some additional comments:

  1. The OP's answer of plot(y, ribbon=(l,u), lab="estimate") is not correct (at least for Plots v1.10.1.). I realize this thread is over 3 years old, so perhaps it worked in the earlier version of Plots.jl that the OP was using at the time)

  2. Similar to one of the answers given,

plot(x, [mid mid], fillrange=[mid .- w, mid .+ w], fillalpha=0.35, c = [1 4], label = ["Band 1" "Band 2"], legend = :topleft, dpi = 80)

will work, but this actually creates TWO ribbons (and hence, two icons in the legend) which may or may not be what the OP was looking for. To illustrate the point:

enter image description here

Marchesa answered 21/2, 2021 at 18:9 Comment(0)
N
6

It turns out that the option ribbon accepts both lower and upper bounds:

plot(y, ribbon=(l,u), lab="estimate")

Notice that by passing l and u in the ribbon option, the filled area will correspond to the region between y-l and y+u. In other words, l and u should be the "deviations" from the mean curve y.

Nagari answered 21/1, 2018 at 3:32 Comment(2)
Note that you need at least Plots v0.27.1 for this to workRosmunda
If your errors are symmetrical you don't need a Tuple, justplot(vals, ribbon=errs) worksSclerenchyma
R
5

Something like this? (seen here).

plot([y y], fillrange=[y.-l y.+u], fillalpha=0.3, c=:orange)
plot!(y)
Rajiv answered 19/1, 2018 at 12:8 Comment(1)
Thank you @Alexander. I have tried it with both GR and PyPlot as backend, but the filled area also has a line besides the filled region.Nagari
F
0

The fillrange solution in @leonidas 's answer might bring an additional boundary line (at least in Plots v1.35). To remove such a line, a workaround is to specify linealpha = 0, that is,

plot(x, l, fillrange = u, fillalpha = 0.35, c = 1, label = "Confidence band", linealpha = 0)
Fromm answered 20/11, 2022 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.