使用 pandas 绘图时,图例仅显示一个标签 [英] Legend only shows one label when plotting with pandas

查看:48
本文介绍了使用 pandas 绘图时,图例仅显示一个标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个 Pandas DataFrame,我希望将它们绘制成单个图形.我正在使用 IPython 笔记本.

I have two Pandas DataFrames that I'm hoping to plot in single figure. I'm using IPython notebook.

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

I would like the legend to show the label for both of the DataFrames, but so far I've been able to get only the latter one to show. Also any suggestions as to how to go about writing the code in a more sensible way would be appreciated. I'm new to all this and don't really understand object oriented plotting.

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

推荐答案

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

This is indeed a bit confusing. I think it boils down to how Matplotlib handles the secondary axes. Pandas probably calls ax.twinx() somewhere which superimposes a secondary axes on the first one, but this is actually a separate axes. Therefore also with separate lines & labels and a separate legend. Calling plt.legend() only applies to one of the axes (the active one) which in your example is the second axes.

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

Pandas fortunately does store both axes, so you can grab all line objects from both of them and pass them to the .legend() command yourself. Given your example data:

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

You can plot exactly as you did:

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

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

Both axes objects are available with ax (left axe) and ax.right_ax, so you can grab the line objects from them. Matplotlib's .get_lines() return a list so you can merge them by simple addition.

lines = ax.get_lines() + ax.right_ax.get_lines()

线条对象有一个标签属性,可用于读取标签并将其传递给 .legend() 命令.

The line objects have a label property which can be used to read and pass the label to the .legend() command.

ax.legend(lines, [l.get_label() for l in lines], loc='upper center')

其余的绘图:

ax.set_title('Wage Variance and Mean Age')
plt.show()

如果您更严格地将 Pandas(数据)和 Matplotlib(绘图)部分分开,可能会减少混淆,因此请避免使用 Pandas 内置绘图(无论如何它只包装 Matplotlib):

It might be less confusing if you separate the Pandas (data) and the Matplotlib (plotting) parts more strictly, so avoid using the Pandas build-in plotting (which only wraps Matplotlib anyway):

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

这篇关于使用 pandas 绘图时,图例仅显示一个标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆