如何在散点图中创建 plt.fill_between 的置信区间

How to create a confidence interval with plt.fill_between inside a scatter plot

我创建了一个散点图,它使用来自两个来源的数据:x = []y = []。在第二步中,我使用以下代码为上面的两个数据列表添加了线性回归线:

(m, b) = np.polyfit(x, y, 1)
Y_Polyval = np.polyval([m, b], x)
plt.plot(x, Y_Polyval, linewidth=3, c="black")

其结果是标准散点图,如下所示。

现在我想使用 plt.fill_between 向黑色回归线添加 95% 的置信区间。我知道这方面有很多话题,我通读了很多,但我无法解决问题,即根据我的特定代码和回归线调整代码。

添加

CI = 1.96 * np.std(y) / np.mean(y)
plt.fill_between(y, (y-CI), (y+CI), color='blue', alpha=0.1)

我的代码会产生以下输出。

plt.fill_between 的蓝色置信区间绘制在图像左侧的某处,但不在回归线周围。我想要实现的是置信区间围绕黑色回归线绘制。完整代码如下:

import numpy as np
import matplotlib.pyplot as plt


# Scatter plot
x = [0.472202, 0.685151, 0.287613, 0.546364, 0.518002, 0.675128, 0.462418, 0.61817, 0.692822, 0.23433,
     0.194009, 0.720232, 0.597321, 0.625955, 0.660571, 0.737754, 0.436876, 0.689937, 0.483067, 0.646723,
     0.699367, 0.384102, 0.561493]

y = [0.131113, 0.123865, 0.150355, 0.138914, 0.140417, 0.119358, 0.130019, 0.129782, 0.113508, 0.13434,
     0.15162, 0.125768, 0.128473, 0.128056, 0.114403, 0.142878, 0.139192, 0.118033, 0.132616, 0.133043,
     0.133973, 0.146611, 0.129792]

(m, b) = np.polyfit(x, y, 1)
Y_Polyval = np.polyval([m, b], x)
plt.plot(x, Y_Polyval, linewidth=3, c="black")

CI = 1.96 * np.std(y) / np.mean(y)
plt.fill_between(y, (y-CI), (y+CI), color='blue', alpha=0.1)

plt.scatter(x, y, s=250, linewidths=2, zorder=2)

plt.show()

您应该绘制预测值 Y_Polyval 而不是真实值 y 并对 (x, y) 值进行排序以填充区域:

plt.fill_between(x, (Y_Polyval-CI), (Y_Polyval+CI), color='blue', alpha=0.1)

完整示例

import numpy as np
import matplotlib.pyplot as plt


# Scatter plot
x = [0.472202, 0.685151, 0.287613, 0.546364, 0.518002, 0.675128, 0.462418, 0.61817, 0.692822, 0.23433,
     0.194009, 0.720232, 0.597321, 0.625955, 0.660571, 0.737754, 0.436876, 0.689937, 0.483067, 0.646723,
     0.699367, 0.384102, 0.561493]

y = [0.131113, 0.123865, 0.150355, 0.138914, 0.140417, 0.119358, 0.130019, 0.129782, 0.113508, 0.13434,
     0.15162, 0.125768, 0.128473, 0.128056, 0.114403, 0.142878, 0.139192, 0.118033, 0.132616, 0.133043,
     0.133973, 0.146611, 0.129792]

# Sort coordinate values
coords = [(a, b) for a, b in zip(x, y)]
coords = sorted(coords, key=lambda x: x[1], reverse=True)
x, y = zip(*coords)

(m, b) = np.polyfit(x, y, 1)
Y_Polyval = np.polyval([m, b], x)
plt.plot(x, Y_Polyval, linewidth=3, c="black")
plt.scatter(x, y, s=250, linewidths=2, zorder=2)
plt.fill_between(x, (Y_Polyval-CI), (Y_Polyval+CI), color='blue', alpha=0.1)