这确实有点令人费解。我认为这可以归结为 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')
两个轴对象都可用ax
(左轴)和ax.right_ax
,这样你就可以从中抓取线条对象。 Matplotlib 的.get_lines()
返回一个列表,以便您可以通过简单的添加来合并它们。
lines = ax.get_lines() + ax.right_ax.get_lines()
线对象有一个 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()
edit:
如果您更严格地将 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()