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.
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:
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:
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:
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)
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: