matplotlib 如何一次指定多个图例标签?

cqoc49vn  于 2023-11-22  发布在  其他
关注(0)|答案(9)|浏览(153)

我有以下数据集:

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()方法来分配多个标签?

vfwfrxfs

vfwfrxfs1#

你可以覆盖你的线对象列表,这样标签就被单独分配了。一个内置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)(如果二维y数组中的数据排列为列[轴1])或plt.plot(x, y.transpose())(如果二维y数组中的数据排列为行[轴0])

**编辑2:**正如@pelson所指出的(见下面的评论),iter函数是不必要的,一个简单的plt.legend(lineObjects, ('foo', 'bar', 'baz'))就可以完美地工作。

vhmi4jdf

vhmi4jdf2#

这两个数组不可能直接相互绘制(至少在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回答和评论。

bsxbgnwa

bsxbgnwa3#

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

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

字符串
看起来像这样:x1c 0d1x

qvk1mo1f

qvk1mo1f4#

目前最好的解决方案是:

lineObjects = plt.plot(x, y)  # y describes 3 lines
plt.legend(['foo', 'bar', 'baz'])

字符串

brqmpdu1

brqmpdu15#

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

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

字符串


的数据

dauxcl2d

dauxcl2d6#

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

字符串
我希望这能帮助

q8l4jmvw

q8l4jmvw7#

当我在数组的列中有一组x值和多个y值时,这个问题经常出现。我真的不想在循环中绘制数据,而且多次调用ax.legend/plt.legend也不是一个选择,因为我想绘制其他东西,通常是以同样烦人的格式。
不幸的是,plt.setp在这里没有帮助。在matplotlib的新版本中,它只是将整个列表/元组转换为字符串,并将整个内容作为标签分配给所有行。
因此,我创建了一个实用函数来 Package 对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')


通过这种方式,你可以将所有普通的artist参数指定给plot,而不必在代码中看到循环。另一种方法是将整个plot调用放入一个实用程序中,该实用程序只解包标签,但这需要大量的重复来弄清楚如何解析多个数据集,可能具有不同数量的列,并分布在多个参数,关键字或其他参数中。

uxh89sit

uxh89sit8#

我使用下面的代码来显示一个不使用点阵图的点阵的标签:

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

字符串

flvlnr44

flvlnr449#

如果您使用的是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()

字符串

相关问题