图例仅在用熊猫绘图时显示一个标签

Art*_*örk 22 python plot matplotlib pandas

我有两个Pandas DataFrames,我希望在单个图中绘制.我正在使用IPython笔记本.

我希望图例显示两个DataFrame的标签,但到目前为止我只能显示后者.此外,任何关于如何以更合理的方式编写代码的建议将不胜感激.我是这一切的新手,并不真正理解面向对象的绘图.

%pylab inline
import pandas as pd

#creating data

prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')
var=pd.DataFrame(randn(len(prng)),index=prng,columns=['total'])
shares=pd.DataFrame(randn(len(prng)),index=index,columns=['average'])

#plotting

ax=var.total.plot(label='Variance')
ax=shares.average.plot(secondary_y=True,label='Average Age')
ax.left_ax.set_ylabel('Variance of log wages')
ax.right_ax.set_ylabel('Average age')
plt.legend(loc='upper center')
plt.title('Wage Variance and Mean Age')
plt.show()
Run Code Online (Sandbox Code Playgroud)

传奇缺少其中一个标签

Rut*_*ies 38

这确实有点令人困惑.我认为这归结为Matplotlib如何处理次轴.熊猫可能会调用ax.twinx()某个在第一个轴上叠加辅助轴的地方,但这实际上是一个单独的轴.因此,还有单独的线条和标签以及单独的图例.调用plt.legend()仅适用于其中一个轴(活动轴),在您的示例中是第二个轴.

幸运的是,Pandas会存储两个轴,因此您可以从两个轴中获取所有线对象并自行将它们传递给.legend()命令.给出您的示例数据:

您可以完全按照您的方式进行绘图:

ax = var.total.plot(label='Variance')
ax = shares.average.plot(secondary_y=True, label='Average Age')

ax.set_ylabel('Variance of log wages')
ax.right_ax.set_ylabel('Average age')
Run Code Online (Sandbox Code Playgroud)

两个轴对象都可以使用ax(左斧头)ax.right_ax,因此您可以从中获取线对象.Matplotlib .get_lines()返回一个列表,以便您可以通过简单的添加来合并它们.

lines = ax.get_lines() + ax.right_ax.get_lines()
Run Code Online (Sandbox Code Playgroud)

行对象具有label属性,可用于读取标签并将其传递给.legend()命令.

ax.legend(lines, [l.get_label() for l in lines], loc='upper center')
Run Code Online (Sandbox Code Playgroud)

其余的策划:

ax.set_title('Wage Variance and Mean Age')
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

编辑:

如果你更严格地分离Pandas(数据)和Matplotlib(绘图)部分可能会更少混淆,所以避免使用Pandas内置绘图(无论如何只包装Matplotlib):

fig, ax = plt.subplots()

ax.plot(var.index.to_datetime(), var.total, 'b', label='Variance')
ax.set_ylabel('Variance of log wages')

ax2 = ax.twinx()
ax2.plot(shares.index.to_datetime(), shares.average, 'g' , label='Average Age')
ax2.set_ylabel('Average age')

lines = ax.get_lines() + ax2.get_lines()
ax.legend(lines, [line.get_label() for line in lines], loc='upper center')

ax.set_title('Wage Variance and Mean Age')
plt.show()
Run Code Online (Sandbox Code Playgroud)


lua*_*art 5

当绘制多个系列时,默认情况下不显示图例。
显示自定义图例的简单方法就是使用最后绘制的系列/数据帧中的轴(我来自IPython Notebook的代码):

%matplotlib inline  # Embed the plot
import matplotlib.pyplot as plt

...
rates[rates.MovieID <= 25].groupby('MovieID').Rating.count().plot()  # blue
(rates[rates.MovieID <= 25].groupby('MovieID').Rating.median() * 1000).plot()  # green
(rates[rates.MovieID <= 25][rates.RateDelta <= 10].groupby('MovieID').Rating.count() * 2000).plot()  # red
ax = (rates[rates.MovieID <= 25][rates.RateDelta <= 10].groupby('MovieID').Rating.median() * 1000).plot()  # cyan

ax.legend(['Popularity', 'RateMedian', 'FirstPpl', 'FirstRM'])
Run Code Online (Sandbox Code Playgroud)

具有自定义图例的情节

  • 不适用于辅助轴,这是这个问题的具体一部分 (7认同)