假设我有25行,例如:
x = np.linspace(0, 30, 60)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape)
y1 = y+ np.random.normal(0, 0.1, size=y.shape)
y2= y+ np.random.normal(0, 0.1, size=y.shape)
plt.plot(x, y, 'k-')
plt.plot(x, y1, 'k-')
plt.plot(x, y2,'k-')
.
.
.
现在,我想绘制一个这样的情节:。如何自动制作这些误差线,并仅给阴影线提供一串线,这些线都具有相同的整体形状,但会有细微的变化。
答案 0 :(得分:1)
我不太清楚代码示例中的错误变量如何与 y 变量的变化相关。所以在这里我举了一个例子,说明如何根据 25 个 y 变量的随机变化计算和绘制误差带,我使用这些相同的变化在带顶部创建 y 误差线。相同的逻辑适用于 x 轴上的变化/误差。
让我们先创建一些随机数据,看看由 25 条相似线组成的线图是什么样的:
import numpy as np # v 1.19.2
import matplotlib.pyplot as plt # v 3.3.2
rng = np.random.default_rng(seed=1)
x = np.linspace(0, 5*np.pi, 50)
y = np.sin(x)
# error = np.random.normal(0.1, 0.02, size=x.shape) # I leave this out
nb_yfuncs = 25
ynoise = rng.normal(1, 0.1, size=(nb_yfuncs, y.size))
yfuncs = nb_yfuncs*[y] + ynoise
fig, ax = plt.subplots(figsize=(10,4))
for yfunc in yfuncs:
plt.plot(x, yfunc, 'k-')
plt.show()
我使用 yfuncs
的平均值作为基线变量。我为每个 x 提取 yfuncs
的最小值和最大值来计算误差带。我计算覆盖与误差带相同范围的误差线。因此,误差相对于平均值是不对称的,这就是为什么它们在绘图函数中作为二维数组输入的原因。误差带用 fill_between
绘制,误差线用 errorbar
绘制。代码如下所示:
ymean = yfuncs.mean(axis=0)
ymin = yfuncs.min(axis=0)
ymax = yfuncs.max(axis=0)
yerror = np.stack((ymean-ymin, ymax-ymean))
fig, ax = plt.subplots(figsize=(10,4))
plt.fill_between(x, ymin, ymax, alpha=0.2, label='error band')
plt.errorbar(x, ymean, yerror, color='tab:blue', ecolor='tab:blue',
capsize=3, linewidth=1, label='mean with error bars')
plt.legend()
plt.show()