如何使用Seaborn绘制带阴影误差带?

9
我希望创建一个类似以下的图表,其中我可以展示一些数值和标准差。

enter image description here

我有两组由两种不同方法得到的平均值和标准差。我想使用seaborn来完成这个任务,但是由于官方示例中使用了我不熟悉的pandas DataFrame对象,我不确定该如何操作。
例如,考虑以下起始代码:
import seaborn as sns

mean_1 = [10, 20, 30, 25, 32, 43]
std_1 = [2.2, 2.3, 1.2, 2.2, 1.8, 3.5]

mean_2 = [12, 22, 30, 13, 33, 39]
std_2 = [2.4, 1.3, 2.2, 1.2, 1.9, 3.5]

谢谢,

G.


2
你不需要数据框,但你需要原始数据来使用 seaborn。如果你已经计算出了统计量,你需要直接使用 matplotlib 中的 plotfill_between 方法。 - Paul H
谢谢您的回复 :) 您能给我展示一个例子吗? - gab
这个网站和matplotlib.org上有很多使用plotfill_between的示例。 - Paul H
上面显示的例子是由seaborn在文档中提供的,但毫无意义。传递的参数是x值、y值,以及样式和色调的值。那里没有参数用于阴影区域的宽度。要么是发生了我不理解的事情,因为文档中没有解释,要么他们提供的例子是错误的。我已经看过你从中得到上面图表的页面。 - undefined
1个回答

23

以下是使用给定数据创建此图的最简示例。由于向量化和广播,使用numpy简化了代码。

import matplotlib.pyplot as plt
import numpy as np

mean_1 = np.array([10, 20, 30, 25, 32, 43])
std_1 = np.array([2.2, 2.3, 1.2, 2.2, 1.8, 3.5])

mean_2 = np.array([12, 22, 30, 13, 33, 39])
std_2 = np.array([2.4, 1.3, 2.2, 1.2, 1.9, 3.5])

x = np.arange(len(mean_1))
plt.plot(x, mean_1, 'b-', label='mean_1')
plt.fill_between(x, mean_1 - std_1, mean_1 + std_1, color='b', alpha=0.2)
plt.plot(x, mean_2, 'r-', label='mean_2')
plt.fill_between(x, mean_2 - std_2, mean_2 + std_2, color='r', alpha=0.2)
plt.legend()
plt.show()

example plot

另一个例子:

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

sns.set()
N = 100
x = np.arange(N)
mean_1 = 25 + np.random.normal(0.1, 1, N).cumsum()
std_1 = 3 + np.random.normal(0, .08, N).cumsum()

mean_2 = 15 + np.random.normal(0.2, 1, N).cumsum()
std_2 = 4 + np.random.normal(0, .1, N).cumsum()

plt.plot(x, mean_1, 'b-', label='mean_1')
plt.fill_between(x, mean_1 - std_1, mean_1 + std_1, color='b', alpha=0.2)
plt.plot(x, mean_2, 'r--', label='mean_2')
plt.fill_between(x, mean_2 - std_2, mean_2 + std_2, color='r', alpha=0.2)

plt.legend(title='title')
plt.show()

第二个例子

PS:使用matplotlib 3.5或更高版本,线条和填充可以在图例中合并:

line_1, = plt.plot(x, mean_1, 'b-')
fill_1 = plt.fill_between(x, mean_1 - std_1, mean_1 + std_1, color='b', alpha=0.2)
line_2, = plt.plot(x, mean_2, 'r--')
fill_2 = plt.fill_between(x, mean_2 - std_2, mean_2 + std_2, color='r', alpha=0.2)
plt.margins(x=0)

plt.legend([(line_1, fill_1), (line_2, fill_2)], ['Series 1', 'Series 2'], title='title')

图例中的填充和连线结合


图例可能包括“填充”命令相关系列。如果是这种情况,您可以在相应的行后添加参数label='_nolegend_',以便在每个系列中只写入plt.legend(['S1','S2']) - Filipe Pinto
1
@FilipePinto 感谢你的建议。我在帖子中添加了一个示例。 - JohanC

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