如何在matplotlib中一次分配多个标签?

时间:2012-07-14 06:38:14

标签: matplotlib label legend

我有以下数据集:

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4],
      [5, 6, 7, 8, 9],
      [9, 8, 7, 6, 5] ]

现在我用它绘图:

import matplotlib.pyplot as plt
plt.plot(x, y)

但是,我想用这个命令标记3个y数据集,这会在调用.legend()时引发错误:

lineObjects = plt.plot(x, y, label=['foo', 'bar', 'baz'])
plt.legend()

File "./plot_nmos.py", line 33, in <module>
  plt.legend()
...
AttributeError: 'list' object has no attribute 'startswith'

当我检查lineObjects

>>> lineObjects[0].get_label()
['foo', 'bar', 'baz']
>>> lineObjects[1].get_label()
['foo', 'bar', 'baz']
>>> lineObjects[2].get_label()
['foo', 'bar', 'baz']

问题

是否有一种优雅的方法可以使用.plot()方法分配多个标签?

9 个答案:

答案 0 :(得分:43)

您可以遍历线对象列表,因此可以单独指定标签。内置python iter函数的示例:

lineObjects = plt.plot(x, y)
plt.legend(iter(lineObjects), ('foo', 'bar', 'baz'))`
更新到matplotlib 1.1.1后,

编辑,它看起来像plt.plot(x, y),其中y作为列表​​列表(由问题作者提供),没有'再工作了。在将y作为numpy.array传递(假设(numpy)[http://numpy.scipy.org/]之前已导入)时,仍然可以考虑在y数组上不迭代的一步绘图。

在这种情况下,使用plt.plot(x, y)(如果2D y数组中的数据按列[轴1]排列)或plt.plot(x, y.transpose())(如果2D y数组中的数据排列为行) [轴0])

编辑2:正如@pelson指出的那样(请参阅下面的评论),iter函数是不必要的,简单plt.legend(lineObjects, ('foo', 'bar', 'baz'))完美无缺

答案 1 :(得分:35)

不可能直接相互绘制这两个数组(至少版本为1.1.1),因此必须在y数组上循环。我的建议是同时循环标签:

import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [9, 8, 7, 6, 5] ]
labels = ['foo', 'bar', 'baz']

for y_arr, label in zip(y, labels):
    plt.plot(x, y_arr, label=label)

plt.legend()
plt.show()

编辑:@gcalmettes指出,作为numpy数组,可以同时绘制所有行(通过转置它们)。见@gcalmettes答案&amp;评论细节。

答案 2 :(得分:28)

我遇到了同样的问题,现在我发现了一个最简单的解决方案!希望对你来说还不算太晚。没有迭代器,只需将结果分配给结构......

from numpy import *
from matplotlib.pyplot import *
from numpy.random import *

a = rand(4,4)
a
>>> array([[ 0.33562406,  0.96967617,  0.69730654,  0.46542408],
   [ 0.85707323,  0.37398595,  0.82455736,  0.72127002],
   [ 0.19530943,  0.4376796 ,  0.62653007,  0.77490795],
   [ 0.97362944,  0.42720348,  0.45379479,  0.75714877]])

[b,c,d,e] = plot(a)
legend([b,c,d,e], ["b","c","d","e"], loc=1)
show()

看起来像这样: enter image description here

答案 3 :(得分:4)

您可以在绘制曲线时给出标签

import pylab as plt

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [9, 8, 7, 6, 5] ]
labels=['foo', 'bar', 'baz']
colors=['r','g','b']

# loop over data, labels and colors
for i in range(len(y)):
    plt.plot(x,y[i],'o-',color=colors[i],label=labels[i])

plt.legend()
plt.show()

enter image description here

答案 4 :(得分:2)

目前最好的解决方案是:

var ans = from i in src
          group i by i.Item into ig
          let PurchaseQty = ig.Where(i => i.Type == "Purchase").Sum(i => i.Qty)
          let SalesQty = ig.Where(i => i.Type == "Sales").Sum(i => i.Qty)
          let ReturnQty = ig.Where(i => i.Type == "Return").Sum(i => i.Qty)
          select new {
              Item = ig.Key,
              Qty = PurchaseQty - SalesQty - ReturnQty
          };

答案 5 :(得分:1)

如果numpy矩阵图为每列分配多个图例

我想基于绘制具有两列的矩阵来回答这个问题。

假设你有一个2列矩阵Ret

然后可以使用此代码一次分配多个标签

import pandas as pd, numpy as np, matplotlib.pyplot as plt
pd.DataFrame(Ret).plot()

plt.xlabel('time')
plt.ylabel('Return')
plt.legend(['Bond Ret','Equity Ret'], loc=0)
plt.show()

我希望这会有所帮助

答案 6 :(得分:0)

我使用以下内容显示了数据框的标签,而不使用数据框图:

lines_ = plot(df)
legend(lines_, df.columns) # df.columns is a list of labels

答案 7 :(得分:0)

如果使用的是DataFrame,还可以遍历要绘制的数据的列:

# Plot figure
fig, ax = plt.subplots(figsize=(5,5))
# Data
data = data
# Plot
for i in data.columns:
    _ = ax.plot(data[i], label=i)
    _ = ax.legend() 
plt.show()

答案 8 :(得分:0)

当我在数组的列中有一组x值和多个y值时,通常会出现此问题。我真的不想在一个循环中绘制数据,对ax.legend / plt.legend的多次调用也不是一个好选择,因为我想绘制其他东西,通常以同样令人讨厌的格式绘制。

不幸的是,plt.setp在这里没有帮助。在较新版本的matplotlib中,它只是将整个列表/元组转换为字符串,然后将整个内容作为标签分配给所有行。

因此,我制作了一个实用程序函数来将对ax.plot / plt.plot的调用包装在以下位置:

def set_labels(artists, labels):
    for artist, label in zip(artists, labels):
        artist.set_label(label)

您可以这样称呼它

x = np.arange(5)
y = np.random.ranint(10, size=(5, 3))

fig, ax = plt.subplots()
set_labels(ax.plot(x, y), 'ABC')

通过这种方式,您可以将所有正常的演出者参数指定为plot,而无需查看代码中的循环。一种替代方法是将整个plot调用放到一个实用工具中,该实用工具仅打开标签的包装,但是这将需要大量重复才能弄清楚如何解析多个数据集(可能具有不同的列数)并分布在多个参数中,关键字还是其他关键字。