我必须绘制一个包含三条彼此接近的曲线的图形。当我绘制每条曲线中的置信区间时,我得到一个丑陋的图形,其中包含重叠的置信区间。
这是一个例子。
from matplotlib import pyplot as plt
import numpy as np
y1 = [2, 3.9, 5.8, 7.2]
y2 = [2, 3.7, 5.6, 7.1]
y3 = [1.9, 3.6, 5.4, 6.8]
x = [2, 4, 6, 8]
ci1 = 1.96 * np.std(y1)/np.sqrt(len(x))
ci2 = 1.96 * np.std(y2)/np.sqrt(len(x))
ci3 = 1.96 * np.std(y3)/np.sqrt(len(x))
fig, ax = plt.subplots()
ax.plot(x, y1)
ax.fill_between(x, (y1-ci1), (y1+ci1), color='b', alpha=.1)
ax.plot(x, y2)
ax.fill_between(x, (y2-ci2), (y2+ci2), color='b', alpha=.1)
ax.plot(x, y3)
ax.fill_between(x, (y3-ci3), (y3+ci3), color='b', alpha=.1)
plt.show()
您知道有更好的方法来显示带有置信区间的曲线吗?我尝试使用误差线,但它更难看。在图例中或 x 轴或 y 轴的某些位置显示置信区间是一个很好的选择吗?
我不确定您的置信区间沿 x 轴是否恒定。
您的数据中的每个 x 值应该有多个点,然后每个 x 值都有一个置信区间,如下所示:
import numpy as np
x = [2, 4, 6, 8]
num_x = len(x)
num_y = 20
y1 = np.array([2, 3.9, 5.8, 7.2])
y2 = np.array([2, 3.7, 5.6, 7.1])
y3 = np.array([1.9, 3.6, 5.4, 6.8])
# Multiple points for each x values
y1 = np.stack([y1 for _ in range(num_y)], axis=0)
y2 = np.stack([y2 for _ in range(num_y)], axis=0)
y3 = np.stack([y3 for _ in range(num_y)], axis=0)
# Some randomness for CI
y1 = y1 + np.random.randn(*y1.shape)
y2 = y2 + np.random.randn(*y2.shape)
y3 = y3 + np.random.randn(*y3.shape)
对于您的实际问题,也许您可以为每条曲线的每个点绘制单独的框:
from matplotlib import pyplot as plt
fig, ax = plt.subplots()
# Tweaks the position so no overlapping
num_curves = 3
pos1 = np.arange(1, (num_curves + 1) * num_x + 1, num_curves + 1)
pos2 = np.arange(2, (num_curves + 1) * num_x + 2, num_curves + 1)
pos3 = np.arange(3, (num_curves + 1) * num_x + 3, num_curves + 1)
# But then fix the ticks
xticks = [2, 6, 10, 14]
xtickslabels = [1, 2, 3, 4]
bplot1 = ax.boxplot(y1, positions=pos1, patch_artist=True)
bplot2 = ax.boxplot(y2, positions=pos2, patch_artist=True)
bplot3 = ax.boxplot(y3, positions=pos3, patch_artist=True)
ax.set_xticks(xticks)
ax.set_xticklabels(xtickslabels)
bplots = (bplot1, bplot2, bplot3)
colors = ["pink", "lightblue", "lightgreen"]
for bplot, clr in zip(bplots, colors):
for patch in bplot["boxes"]:
patch.set_facecolor(clr)
plt.show()