如何在一个图中对齐线条和条形图的x轴?

时间:2018-07-08 12:20:53

标签: python pandas matplotlib

我正在Jupyter中使用Pandas来尝试绘制一个图中一个字段(条形图)的计数和另一个字段(折线图)的平均值。我的数据在一个数据框中,如果我直接绘制数据框,则显示“确定”。但是,我希望线图在共享x轴的同时具有secondary_y轴,所以我使用以下代码:

mobs_by_cr = data_frame.groupby("cr").agg({'hp': np.mean, 'cr': np.size})
ax = mobs_by_cr["cr"].plot(kind="bar", colormap='Paired')
mobs_by_cr["hp"].plot(kind="line", ax=ax, secondary_y=True)

如果我自己绘制这些列中的任何一列,则它与x轴正确对齐。但是,当我尝试通过传递ax=ax使它们在同一图形上时,它们就没有对齐。

mis-aligned plot

查看数据,折线图中的底线应该在x轴上为 18 ,而不是在 15

                hp    cr
cr                      
0.000     3.848485  33.0
0.125     8.166667  24.0
0.250    14.522727  44.0
0.500    20.025000  40.0
1.000    28.710526  38.0
2.000    43.126984  63.0
3.000    59.205882  34.0
4.000    74.650000  20.0
5.000    96.114286  35.0
6.000   105.823529  17.0
7.000   111.090909  11.0
8.000   114.285714  14.0
9.000   149.700000  10.0
10.000  154.750000   8.0
11.000  178.700000  10.0
12.000  128.000000   5.0
13.000  173.333333   9.0
14.000  185.200000   5.0
15.000  175.166667   6.0
16.000  213.400000   5.0
17.000  252.428571   7.0
18.000   80.000000   1.0
19.000  262.000000   1.0
20.000  310.000000   3.0
21.000  273.750000   4.0
22.000  414.500000   2.0
23.000  438.250000   4.0
24.000  546.000000   2.0
30.000  676.000000   1.0

数据:'cr,hp,cr\n0.0,3.8484848484848486,33.0\n0.125,8.166666666666666,24.0\n0.25,14.522727272727273,44.0\n0.5,20.025,40.0\n1.0,28.710526315789473,38.0\n2.0,43.12698412698413,63.0\n3.0,59.205882352941174,34.0\n4.0,74.65,20.0\n5.0,96.11428571428571,35.0\n6.0,105.82352941176471,17.0\n7.0,111.0909090909091,11.0\n8.0,114.28571428571429,14.0\n9.0,149.7,10.0\n10.0,154.75,8.0\n11.0,178.7,10.0\n12.0,128.0,5.0\n13.0,173.33333333333334,9.0\n14.0,185.2,5.0\n15.0,175.16666666666666,6.0\n16.0,213.4,5.0\n17.0,252.42857142857142,7.0\n18.0,80.0,1.0\n19.0,262.0,1.0\n20.0,310.0,3.0\n21.0,273.75,4.0\n22.0,414.5,2.0\n23.0,438.25,4.0\n24.0,546.0,2.0\n30.0,676.0,1.0\n'

2 个答案:

答案 0 :(得分:1)

熊猫条形图是分类图。这意味着这些值实际上是针对它们的整数索引绘制的,与x值将以数字形式显示的内容无关。从上面的评论来看,这就是您想要的。

线图不是绝对的。它将针对数字索引值进行绘制。将两种图表放在同一张图中将失败。另外,没有“分类线图”可用。

但是,当然,您也可以通过针对其整数索引绘制值来绘制直线。

假设您具有以下数据框

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"x" : [1, 2.75, 100], "y1" : [1,2,3], "y2" : [300,100,275]})
df.set_index("x", inplace=True)
print(df) 

#         y1   y2
# x              
# 1.00     1  300
# 2.75     2  100
# 100.00   3  275

您可以像在问题中那样绘制y1的条形图,但是对于折线图,首先使x成为一个适当的列,而不是针对{{1} }值,将其针对新建立的整数索引进行绘制。

y2

enter image description here

答案 1 :(得分:0)

以下内容似乎可行,尽管它需要深入研究matplotlib才能在折线图上强制对齐。

mobs_by_cr = data_frame.groupby("cr").agg({'hp': np.mean, 'cr': np.size})
mobs_by_cr.rename(columns={"cr":"count"}, inplace=True)
fig, ax = plt.subplots()
mobs_by_cr["count"].plot(kind="bar", ax=ax, colormap='Paired')
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(), mobs_by_cr["hp"])

结果:

enter image description here