如何使用Plots.jl填充两条曲线之间的区域?

10
假设我有一条曲线 y,还有两条向量形式的曲线 ul。如何绘制图表:
plot(y, lab="estimate")
plot!(y-l, lab="lower bound")
plot!(y+u, lab="upper bound")

也就是说,这是一个不对称的置信区间?我知道如何使用选项ribbon绘制对称情况,详情请见此处

4个回答

20

当前的答案并不正确。以下是两种正确的方法(截至Plots.jl v1.10.1):

方法1:使用fillrange

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

方法二:使用 ribbon

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

(在这里,lu分别表示“下限”和“上限”的y值,x表示它们共同的x值。) 这两种方法之间的关键区别在于fillrange填充了lu之间的区域,而ribbon参数是一个半径,即缎带的一半宽度(或者换句话说,中点的垂直偏移量)。

使用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)

让我们在图表上分散y1y2,以确保我们填充了正确的区域。

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")

结果:

enter image description here

使用ribbon的示例: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")

(这里,xy1y2与之前相同。)

结果:

enter image description here

请注意,图例中ribbonfillrange的标签不同:前者标记中点/均值,而后者标记阴影区域本身。

一些附加说明:

  1. OP的答案plot(y, ribbon=(l,u), lab="estimate")是不正确的(至少对于Plots v1.10.1)。我意识到这个主题已经超过3年了,所以也许在OP当时使用的Plots.jl早期版本中它可以工作。

  2. 类似于其中一个给出的答案,

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

这样做虽然可以实现目标,但会创建两个条带(因此在图例中会出现两个图标),这可能并非OP所要求的。举个例子:

在此输入图片描述


6
原文:It turns out that the option ribbon accepts both lower and upper bounds:
翻译:原来选项ribbon接受上下限值:
plot(y, ribbon=(l,u), lab="estimate")

请注意,在ribbon选项中传递lu,填充区域将对应于y-ly+u之间的区域。换句话说,lu应该是与平均曲线y的“偏差”。

1
请注意,您需要至少 Plots v0.27.1 才能运行此程序。 - fredcallaway
如果你的错误是对称的,你不需要一个元组,只需要plot(vals, ribbon=errs)就可以了。 - josePereiro

5
像这样吗?(见这里)。
plot([y y], fillrange=[y.-l y.+u], fillalpha=0.3, c=:orange)
plot!(y)

谢谢@Alexander。我已经尝试了GR和PyPlot作为后端,但是填充区域除了填充区域之外还有一条线。 - juliohm

0

@leonidas的答案中的fillrange解决方案可能会带来额外的边界线(至少在Plots v1.35中)。为了删除这样的线条,一个解决方法是指定linealpha = 0,也就是说,

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接