首页 > 解决方案 > 如何从多个 pd.Series 对象中绘制多系列直方图?

问题描述

我想绘制一个看起来像这样的多系列直方图:

多系列直方图

我正在尝试将此添加到现有的 Jupyter 笔记本中,该笔记本已经有代码来建立双图表:

    fig, (ax, ax2) = plt.subplots(2,1)

现有代码使用使用数据对象本身的方法完成绘图的样式。例如,这里有一些在现有子图中绘制折线图的现有代码:

            ax = termstruct[i].T.plot.line(ax=ax, c=linecolor, 
                 dashes=dash, grid=True, linewidth=width, figsize=FIGURE_SIZE)

我在这里要说明的要点是,实现绘图的方式是在 Pandas pd.Series (termstruct) 上使用 .plot.line 方法。这与我在网上找到的使用 pyplot 绘制图表的示例和教程完全不同,但它可以工作,并且它建立了一个我试图在其中工作的框架。

因此,我首先采取了明显的步骤,即通过将子图调用从上面更改为 plt 来为我的直方图添加第三个子图:

    fig, (ax, ax2, ax3) = plt.subplots(3,1)

我的数据位于四个单独的 pd.Series 对象中,其中每个对象代表一个系列,该系列应映射到本文顶部图表示例中的一种颜色。但是,当我尝试遵循相同的通用编码风格,在数据对象上使用方法进行绘图时,我似乎总是以与我想要的相反的 X 轴和 Y 轴结束,如下所示:

我的结局是什么!

生成上图的代码是:

ax3 = NakedPNLperMo.plot.hist(ax=ax3,grid=True, figsize=FIGURE_SIZE)
ax3 = H9PNLperMo.plot.hist(ax=ax3, grid=True, figsize=FIGURE_SIZE)
ax3 = H12PNLperMo.plot.hist(ax=ax3, grid=True, figsize=FIGURE_SIZE)
ax3 = H15PNLperMo.plot.hist(ax=ax3, grid=True, figsize=FIGURE_SIZE)

NakedPNLperMo 和其他 3 个 pd.Series 对象充满了神秘的金融符号,但其内容的简化版本(为了清楚起见)将是:

NakedPNLperMO = pd.Series(data=[1.2,3.4,5.6,7.8,-2.3,-4.6],
                          index=['Month 1','Month 2','Month 3','Month 4',
                                 'Month 5','Month 6'])

我的意图/目标是数据绘制在 Y 轴上,索引值(“第 1 个月”等)就像 x 轴上的列,但无论我尝试什么,我似乎都无法获得该输出.

显然问题是轴被交换了。但是当我去寻找如何解决这个问题时,我在网上找不到任何遵循这种使用数据对象上的方法绘制图表的方法的示例。我在在线教程中发现的所有内容都是使用一堆调用 plt 来设置图表。更重要的是,我看不出有任何方法可以遵循这些示例中的样式,并且仍然将图表绘制为与该程序已经定义的 2 个子图一起的第三个子图。

我的第一个(也是最重要的)问题是我接下来应该尝试什么......弄清楚如何更改 [data-object].plot.xxx 的参数以按照我需要的方式获得轴是否有意义,或者遵循完全不同的风格来调用 plt 来设计和绘制图表会更有意义吗?前者与我所拥有的一致,但我找不到任何使用该编码风格的在线帮助。(我是否应该推断这是一种过时的做事风格?)

如果上述问题的答案是像在线示例似乎都显示的那样采用调用 plt 的方法,我该如何使用将这个图表与现有子图联系起来的 ax3?如果上面的答案是坚持使用 [data-object].plot.xxx 的方法,我在哪里可以找到使用该样式的帮助?我能找到的所有在线示例都遵循不同的编码风格。

当然还有最明显的问题:如何交换轴以使图表看起来正确?:)

谢谢!

标签: pythonpandasmatplotlibchartshistogram

解决方案


我希望这段代码对您有所帮助,我创建了三个系列来向您展示如何做到这一点:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#jupyter notebook only
%matplotlib inline
s1 = pd.Series(data=[1.2,3.4,5.6,7.8,-2.3,-4.6],
                          index=['Month 1','Month 2','Month 3','Month 4',
                                 'Month 5','Month 6'])
s2=pd.Series(data=[5,3.4,7.4,-5.1,-2.3,3],
                          index=['Month 1','Month 2','Month 3','Month 4',
                                 'Month 5','Month 6'])
s3=pd.Series(data=[5,2,-2.4,0,1,3],
                          index=['Month 1','Month 2','Month 3','Month 4',
                                 'Month 5','Month 6'])

df=pd.concat([s1,s2,s3],axis=1)
df.columns=['s1','s2','s3']
print(df)
ax=df.plot(kind='bar',figsize=(10,10),fontsize=15)
#------------------------------------------------#
plt.xticks(rotation=-45)
#grid on
plt.grid()
# set y=0
ax.axhline(0, color='black', lw=1)
#change size of legend
ax.legend(fontsize=20)
#hiding upper and right axis layout
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
#changing the thickness
ax.spines['bottom'].set_linewidth(3)
ax.spines['left'].set_linewidth(3)

输出:

          s1   s2   s3
Month 1  1.2  5.0  5.0
Month 2  3.4  3.4  2.0
Month 3  5.6  7.4 -2.4
Month 4  7.8 -5.1  0.0
Month 5 -2.3 -2.3  1.0
Month 6 -4.6  3.0  3.0

数字

在此处输入图像描述


推荐阅读