Matplotlib编辑图例标签

5
如果我使用plt.legend([一些标签])修改绘图的标签,然后调用ax.get_legend_handles_labels(),我会得到旧的标签。
这里是一个简单的例子:
In [1]: import matplotlib.pyplot as plt

In [2]: plt.plot([1,2,3], label='A')
Out[2]: [<matplotlib.lines.Line2D at 0x7f60749be310>]

In [3]: plt.plot([2,3,4], label='B')
Out[3]: [<matplotlib.lines.Line2D at 0x7f60749f1850>]

In [4]: ax = plt.gca()

In [5]: l = ax.get_legend_handles_labels()

In [6]: l
Out[6]:
([<matplotlib.lines.Line2D at 0x7f60749be310>,
  <matplotlib.lines.Line2D at 0x7f60749f1850>],
 [u'A', u'B'])

In [7]: plt.legend(['C', 'D'])  ### This correctly modifies the legend to show 'C' and 'D', but then ...
Out[7]: <matplotlib.legend.Legend at 0x7f6081dce190>

In [10]: l = ax.get_legend_handles_labels()

In [11]: l
Out[11]:
([<matplotlib.lines.Line2D at 0x7f60749be310>,
  <matplotlib.lines.Line2D at 0x7f60749f1850>],
 [u'A', u'B'])

此时我不知道如何获取已显示标签的列表,即['C', 'D']。我错过了什么?我应该使用哪种其他方法?
为了提供更多背景信息,我正在尝试绘制一个pandas数据帧,修改图例以添加一些信息,然后在同一坐标轴上绘制另一个数据帧,并重复相同的过程与标签。为了做到这一点,第二次我需要修改图例中部分标签并保留其余部分不变。
1个回答

5
按照 plt.legend 函数文档中的建议操作,即可达到您想要的效果。

Signature: plt.legend(*args, **kwargs) Docstring: Places a legend on the axes.

To make a legend for lines which already exist on the axes (via plot for instance), simply call this function with an iterable of strings, one for each legend item. For example::

ax.plot([1, 2, 3])
ax.legend(['A simple line'])

However, in order to keep the "label" and the legend element instance together, it is preferable to specify the label either at artist creation, or by calling the :meth:~matplotlib.artist.Artist.set_label method on the artist::

line, = ax.plot([1, 2, 3], label='Inline label')
# Overwrite the label by calling the method.
line.set_label('Label via method')
ax.legend()
import matplotlib.pyplot as plt

line1, = plt.plot([1,2,3], label='A')
line2, = plt.plot([2,3,4], label='B')

ax = plt.gca()
l = ax.get_legend_handles_labels()
print(l)

line1.set_label("C")
line2.set_label("D")
ax.legend()

l = ax.get_legend_handles_labels()
print(l)
plt.show()

>>([<matplotlib.lines.Line2D object at 0x000000000A399EB8>, <matplotlib.lines.Line2D object at 0x0000000008A67710>], ['A', 'B'])
>>([<matplotlib.lines.Line2D object at 0x000000000A399EB8>, <matplotlib.lines.Line2D object at 0x0000000008A67710>], ['C', 'D'])

1
谢谢,你的回答很有效,但我必须说plt.legend的默认行为相当令人困惑。这个命令为什么会让你有可能在不传播更改到底层对象的情况下改变图例?在我最后提出的用例中,你提出的解决方案使得代码非常复杂。我等了一会儿才接受,看看是否有其他选择,现在我接受它。 - l736x
他们可能有一个原因解释为什么它会表现出这样的行为,可能只是“遗留”的原因^^你需要问开发人员才能得到明确的答案。 - M4rtini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接