简体   繁体   English

从plot获取标签的一致方式,bar等图纸与matplotlib

[英]Consistent way of getting labels from plot, bar and other drawings with matplotlib

With line plots, I can get all labels like this and build a legend:使用线图,我可以获得所有这样的标签并构建图例:

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)

When I have bar plots, this does not work anymore.当我有条形图时,这不再有效。 Eg:例如:

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() returns a string similar to a __str__ method: b1.get_label()返回类似于__str__方法的字符串:

'0    87
Name: TP, dtype: object'

Why does .get_label() not behave identically?为什么.get_label()行为不同?

ax1.plot(...) returns a tuple of Line2D elements. ax1.plot(...)返回 Line2D 元素的元组 Usually this is a tuple of just one element, but it can be longer when more lines are plotted in the same call ( lines = ax1.plot(x1,y1,'r',x2,y2,'b') would return 2 Line2D elements).通常这是一个只有一个元素的元组,但是当在同一个调用中绘制更多行时它可能会更长( lines = ax1.plot(x1,y1,'r',x2,y2,'b')将返回 2 Line2D 元素)。

When you do p1+p2+p3+p4 , you append these tuples, creating a tuple of 4 elements.当您执行p1+p2+p3+p4时,您 append 这些元组,创建一个包含 4 个元素的元组。 ax.bar , on the other hand, returns a single Bar container.另一方面, ax.bar返回单个 Bar 容器。 These can't be concatenated via + .这些不能通过+连接。 You need to create a tuple (b1,b2,b3,b4,b5) or a list [b1,b2,b3,b4,b5] .您需要创建一个元组(b1,b2,b3,b4,b5)或一个列表[b1,b2,b3,b4,b5]

You'll often see a mysterious comma used in p1, = ax1.plot(...) .您经常会在p1, = ax1.plot(...)中看到一个神秘的逗号。 That way, the first element of the tuple is assigned to p1 .这样,元组的第一个元素被分配给p1

Also note that you don't need to extract the labels.另请注意,您不需要提取标签。 If you call ax1.legend(handles=p) , matplotlib will extract and use these labels automatically.如果您调用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()

调用句柄

The same can be written as follows, making it easier to combine handles from different functions:同样的可以写成下面这样,这样可以更容易地组合来自不同函数的句柄:

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()

That makes it similar to how you would work with bars:这使得它类似于您使用条形图的方式:

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()

带有手柄图例的条形图

Of course, in these cases, the legend can also be created automatically.当然,在这些情况下,图例也可以自动创建。 However, explicit working with these handles can be interesting if you need f.netuning the legend, or you want to combine two handles into one.但是,如果您需要 f.netuning 图例,或者想要将两个句柄合二为一,那么显式使用这些句柄可能会很有趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM