pandas 使用 DataFrame.Plot 在同一图上绘制多个图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24227650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 22:09:54  来源:igfitidea点击:

Multiple plots on same figure with DataFrame.Plot

pythonmatplotlibpandas

提问by Mark Graph

While I can get multiple lines on a chart and multiple bars on a chart - I cannot get a line and bar on the same chart using the same PeriodIndex.

虽然我可以在图表上获得多条线并在图表上获得多条柱线 - 但我无法使用相同的 PeriodIndex 在同一图表上获得线段和柱线。

Faux code follows ...

伪代码如下...

# play data
n = 100
x = pd.period_range('2001-01-01', periods=n, freq='M')
y1 = (Series(np.random.randn(n)).diff() + 5).tolist()
y2 = (Series(np.random.randn(n)).diff()).tolist()
df = pd.DataFrame({'bar':y2, 'line':y1}, index=x)

# let's plot
plt.figure()
ax = df['bar'].plot(kind='bar', label='bar')
df['line'].plot(kind='line', ax=ax, label='line')
plt.savefig('fred.png', dpi=200)
plt.close()

Any help will be greatly appreciated ...

任何帮助将不胜感激 ...

回答by HYRY

The problem is: bar plots don't use index values as x axis, but use range(0, n). You can use twiny()to create a second axes that share yaxis with the bar axes, and draw line curve in this second axes.

问题是:条形图不使用索引值作为 x 轴,而是使用range(0, n). 您可以使用twiny()创建与条形轴共享 yaxis 的第二个轴,并在第二个轴上绘制线曲线。

The most difficult thing is how to align x-axis ticks. Here we define the align function, which will align ax2.get_xlim()[0]with x1in ax1and ax2.get_xlim()[1]with x2in ax1:

最困难的是如何对齐 x 轴刻度。这里我们定义对齐功能,将调整ax2.get_xlim()[0]x1ax1ax2.get_xlim()[1]x2ax1

def align_xaxis(ax2, ax1, x1, x2):
    "maps xlim of ax2 to x1 and x2 in ax1"
    (x1, _), (x2, _) = ax2.transData.inverted().transform(ax1.transData.transform([[x1, 0], [x2, 0]]))
    xs, xe = ax2.get_xlim()
    k, b = np.polyfit([x1, x2], [xs, xe], 1)
    ax2.set_xlim(xs*k+b, xe*k+b)

Here is the full code:

这是完整的代码:

from matplotlib import pyplot as plt
import pandas as pd
from pandas import Series
import numpy as np
n = 50
x = pd.period_range('2001-01-01', periods=n, freq='M')
y1 = (Series(np.random.randn(n)) + 5).tolist()
y2 = (Series(np.random.randn(n))).tolist()
df = pd.DataFrame({'bar':y2, 'line':y1}, index=x)

# let's plot
plt.figure(figsize=(20, 4))
ax1 = df['bar'].plot(kind='bar', label='bar')
ax2 = ax1.twiny()
df['line'].plot(kind='line', label='line', ax=ax2)
ax2.grid(color="red", axis="x")

def align_xaxis(ax2, ax1, x1, x2):
    "maps xlim of ax2 to x1 and x2 in ax1"
    (x1, _), (x2, _) = ax2.transData.inverted().transform(ax1.transData.transform([[x1, 0], [x2, 0]]))
    xs, xe = ax2.get_xlim()
    k, b = np.polyfit([x1, x2], [xs, xe], 1)
    ax2.set_xlim(xs*k+b, xe*k+b)

align_xaxis(ax2, ax1, 0, n-1)

and the output:

和输出:

enter image description here

在此处输入图片说明