Python 使用熊猫打印时,图例仅显示一个标签

Python 使用熊猫打印时,图例仅显示一个标签,python,matplotlib,plot,pandas,Python,Matplotlib,Plot,Pandas,我有两个熊猫数据框,我希望用一个图形绘制。我用的是IPython笔记本 我希望图例显示两个数据帧的标签,但到目前为止,我只能显示后一个。此外,任何关于如何以更合理的方式编写代码的建议都将不胜感激。我对所有这些都是新手,并不真正了解面向对象绘图 %pylab inline import pandas as pd #creating data prng = pd.period_range('1/1/2011', '1/1/2012', freq='M') var=pd.DataFrame(ran

我有两个熊猫数据框,我希望用一个图形绘制。我用的是IPython笔记本

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

%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()
仅适用于一个轴(活动轴),在您的示例中,该轴是第二个轴

熊猫确实存储了这两个轴,因此您可以从这两个轴获取所有线对象,并将它们传递给
.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')
这两个轴对象都可以使用
ax
(左轴)和
ax.right\u ax
,因此您可以从它们中获取线对象。Matplotlib的
.get_lines()
返回一个列表,这样您就可以通过简单的添加来合并它们

lines = ax.get_lines() + ax.right_ax.get_lines()
line对象具有一个label属性,可用于读取标签并将其传递给
.legend()
命令

ax.legend(lines, [l.get_label() for l in lines], loc='upper center')
以及其余的绘图:

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

编辑: 如果您更严格地分离熊猫(数据)和Matplotlib(打印)部分,可能会更容易混淆,因此避免使用熊猫内置打印(无论如何只包装Matplotlib):


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

%matplotlib inline#嵌入绘图
将matplotlib.pyplot作为plt导入
...

rates[rates.MovieID您可以使用
pd.concat
合并两个数据帧,然后使用辅助y轴进行绘图:

import numpy as np  # For generating random data.
import pandas as pd

# Creating data.
np.random.seed(0)
prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')
var = pd.DataFrame(np.random.randn(len(prng)), index=prng, columns=['total'])
shares = pd.DataFrame(np.random.randn(len(prng)), index=prng, columns=['average'])

# Plotting.
ax = (
    pd.concat([var, shares], axis=1)
    .rename(columns={
        'total': 'Variance of Low Wages',
        'average': 'Average Age'
    })
    .plot(
        title='Wage Variance and Mean Age',
        secondary_y='Average Age')
)
ax.set_ylabel('Variance of Low Wages')
ax.right_ax.set_ylabel('Average Age', rotation=-90)

不适用于次轴,而次轴正是此问题的一部分
%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'])
import numpy as np  # For generating random data.
import pandas as pd

# Creating data.
np.random.seed(0)
prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')
var = pd.DataFrame(np.random.randn(len(prng)), index=prng, columns=['total'])
shares = pd.DataFrame(np.random.randn(len(prng)), index=prng, columns=['average'])

# Plotting.
ax = (
    pd.concat([var, shares], axis=1)
    .rename(columns={
        'total': 'Variance of Low Wages',
        'average': 'Average Age'
    })
    .plot(
        title='Wage Variance and Mean Age',
        secondary_y='Average Age')
)
ax.set_ylabel('Variance of Low Wages')
ax.right_ax.set_ylabel('Average Age', rotation=-90)