matplotlib 如何自定义图例的句柄和标签

1mrurvl1  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(151)

我尝试从matplotlib plot自定义ax。这里我使用一个surpyval包来拟合数据,然后绘制它。surpyval包中的plot方法不接受我提供的ax=ax以外的参数。我的问题是我无法匹配句柄和图例,正如你在这个例子中看到的:

import surpyval as surv 
import matplotlib.pyplot as plt 

y_a = np. array([181, 183, 190,190, 195, 195, 198, 198, 198, 201,202, 202, 202, 
       204, 205, 205, 206,206, 206, 206,207, 209 , 213, 214, 218, 219])

y_s = np.array([161, 179, 196,196, 197, 198, 204, 205, 209, 211,215, 218, 227, 
       230, 231, 232, 232 ,236, 237, 237,240, 243, 244, 246, 252, 255])

model_1 = surv.Weibull.fit(y_a)
model_2 = surv.Weibull.fit(y_s)

ax=plt.gca()

model_1.plot(ax=ax)
model_2.plot(ax=ax)

p_a = ['A', 'a_u_CI','a_l_CI', 'a_fit']
p_s= ['S', 's_u_CI','s_l_CI', 's_fit']
p_t = p_a + p_s

ax.legend(labels=p_t[0:5:4])

kfgdxczn

kfgdxczn1#

除了指定标签之外,还需要告诉ax.legend使用哪个“句柄”。
通常使用matplotlib,你可以在绘制它们时标记每一行或每一个集合,但是使用surpyval,这是不可能的。
相反,我们可以从matplotlib Axes示例中找到相关的句柄。
在本例中,假设您想要标记蓝色和橙子圆圈,您需要两个PathCollection示例,它们是使用matplotlib的scatter方法在后台创建的。幸运的是,它们很容易访问,在ax.collections属性中。所以,您只需要将图例行更改为:

ax.legend(handles=ax.collections, labels=p_t[0:5:4])

得到这个图:

作为参考,红色实线和黑色虚线存储在ax.lines中。对于此图,有6个Line2D对象存储在那里,对应于图上的4条红线和2条黑线。
为了回答下面的评论(“* 你知道如何将实线转换为fill_between吗?*”),要在两行之间填充,你可以从两行中获取x和y数据,然后使用matplotlib的fill_between函数。
例如,要在“A”数据的两条红线之间填充,您可以这样做:

l1 = ax.lines[0]
l2 = ax.lines[1]

x1 = l1.get_xdata()
x2 = l2.get_xdata()

y1 = l1.get_ydata()
y2 = l2.get_ydata()

ax.fill_between(x1, y1, y2, zorder=-5, alpha=0.5, color='r')

请注意,您需要将zorder设置为低于分散点的值,否则会隐藏它们。
对于此图中的其他两条线,您可能希望使用ax.lines[3]ax.lines[4]
请注意,这都是用matplotlib v3.6、surpyval v0.10.10、python 3.9测试的。
我发现使用matplotlib的后续版本(v3.7.2,2023年9月)不起作用,因为surpyval试图绘制网格的方式存在一些问题。

相关问题