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

3

虽然我可以在图表上同时显示多条线和多个柱形,但是我无法在同一个PeriodIndex上使用线条和柱状图。

以下是伪代码...

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

非常感谢您的帮助...


我喜欢Stack Overflow - 一个严肃的问题:我想在同一张图表上画一条线和一个柱状图,但是我看不出我的代码哪里有问题(柱状图没有被添加)。因为这个问题我还收到了一个踩?同时,我需要更改标题,以便问题不再反映我的信息需求。上面的代码对于多条线图和多个柱状图都可以正常工作 - 我的问题是其中一个。 - Mark Graph
我不知道为什么你会被踩,但我注意到你依赖标题来描述你发布的内容有什么问题。我认为在实际问题中使用比“这是代码,请修复”更具描述性的文本会更好/更清晰。 - Ajean
我欣赏这个由社会不适应者和小暴君居住的世界。已经添加了问题以使其更清晰。 - Mark Graph
1个回答

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

最困难的问题是如何对齐x轴刻度。在这里,我们定义了一个对齐函数,它将ax2.get_xlim()[0]ax1中的x1对齐,并将ax2.get_xlim()[1]ax1中的x2对齐:
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)

这是完整的代码:
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)

输出结果如下图所示:

enter image description here


谢谢 - 您的回答对我帮助很大 - 我现在明白了问题所在。 - Mark Graph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接