python 使用matplotlib从绘图、条形图和其他图形中获取标签的一致方式

fjaof16o  于 2023-01-08  发布在  Python
关注(0)|答案(1)|浏览(128)

使用线图,我可以获得如下所示的所有标签并构建图例:

p1 = ax1.plot(x, 'P1', data=df)
p2 = ax1.plot(x, 'P2', data=df)
p3 = ax1.plot(x, 'P3', data=df)
p4 = ax1.plot(x, 'P4', data=df)

p = p1+p2+p3+p4
labs = [l.get_label() for l in p]
ax1.legend(p, labs, loc=0, frameon=False)

当我有条形图时,这不再起作用。例如:

b1 = ax1.bar(x-2*w, 'B1', data=df, width=w, label="TP")
b2 = ax1.bar(x-w, 'B2', data=df, width=w, label="FN")
b3 = ax1.bar(x, 'B3', data=df, width=w, label="FP")
b4 = ax2.bar(x+w, 'B4', data=df, width=w, label="AP")
b5 = ax2.bar(x+2*w, 'B5', data=df, width=w, label="AR")

b1.get_label()返回与__str__方法类似的字符串:

'0    87
Name: TP, dtype: object'

为什么.get_label()的行为不同?

guicsvcw

guicsvcw1#

ax1.plot(...)返回Line2D元素的tuple。通常这是一个只有一个元素的元组,但是当在同一个调用中绘制多条线时,它可能会更长(lines = ax1.plot(x1,y1,'r',x2,y2,'b')将返回2个Line2D元素)。
当你执行p1+p2+p3+p4时,你会添加这些元组,创建一个包含4个元素的元组。另一方面,ax.bar返回一个Bar容器。这些不能通过+连接。你需要创建一个元组(b1,b2,b3,b4,b5)或者一个列表[b1,b2,b3,b4,b5]
你经常会看到p1, = ax1.plot(...)中使用了一个神秘的逗号,这样一来,元组的第一个元素就被赋给了p1
还需要注意的是,你不需要提取标签,如果你调用ax1.legend(handles=p),matplotlib会自动提取并使用这些标签。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

x = np.arange(20)
df = pd.DataFrame({f'P{i}': np.random.randn(20).cumsum() for i in range(1, 5)})
fig, ax1 = plt.subplots()
p1 = ax1.plot(x, 'P1', data=df)
p2 = ax1.plot(x, 'P2', data=df)
p3 = ax1.plot(x, 'P3', data=df)
p4 = ax1.plot(x, 'P4', data=df)

p = p1 + p2 + p3 + p4
ax1.legend(handles=p, loc='best', frameon=False)
plt.show()

同样的代码也可以写成如下形式,这样可以更容易地合并不同函数的句柄:

p1, = ax1.plot(x, 'P1', data=df)
p2, = ax1.plot(x, 'P2', data=df)
p3, = ax1.plot(x, 'P3', data=df)
p4, = ax1.plot(x, 'P4', data=df)

p = [p1, p2, p3, p4]
ax1.legend(handles=p, frameon=False)
plt.show()

这与处理条形图的方式类似:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

x = np.arange(5)
df = pd.DataFrame({f'B{i}': np.random.rand(5).cumsum() for i in range(1, 6)})
fig, ax1 = plt.subplots()
w = 0.19
b1 = ax1.bar(x - 2 * w, 'B1', data=df, width=w, label="TP")
b2 = ax1.bar(x - w, 'B2', data=df, width=w, label="FN")
b3 = ax1.bar(x, 'B3', data=df, width=w, label="FP")
b4 = ax1.bar(x + w, 'B4', data=df, width=w, label="AP")
b5 = ax1.bar(x + 2 * w, 'B5', data=df, width=w, label="AR")

ax1.legend(handles=[b1, b2, b3, b4, b5], frameon=False)
plt.show()

当然,在这些情况下,图例也可以自动创建。然而,如果您需要微调图例,或者您想将两个句柄合并为一个,显式地使用这些句柄可能会很有趣。

相关问题