Pandas 从数据透视表中绘图

Posted

技术标签:

【中文标题】Pandas 从数据透视表中绘图【英文标题】:Pandas Plotting from Pivot Table 【发布时间】:2016-07-08 01:30:28 【问题描述】:

我基本上是在尝试重现显示不同地点全年平均温度和降水量的气候图。

我通过以下方式从我的 csv 生成了一个数据透视表:

data = pd.read_csv("05_temp_rain_v2.csv")
pivot = data.pivot_table(["rain(mm)","temp(dC)"], ["loc","month"])  

文本形式的样本数据:

loc,lat,long,year,month,rain(mm),temp(dC)
Adria_-_Bellombra,45.011129,12.034126,1994,1,45.6,4.6  
Adria_-_Bellombra,45.011129,12.034126,1994,2,31.4,4  
Adria_-_Bellombra,45.011129,12.034126,1994,3,1.6,10.7  
Adria_-_Bellombra,45.011129,12.034126,1994,4,74.4,11.5  
Adria_-_Bellombra,45.011129,12.034126,1994,5,26,17.2  
Adria_-_Bellombra,45.011129,12.034126,1994,6,108.6,20.6

数据透视表:

由于我正在处理不同的位置,因此我正在迭代它们:

locations=pivot.index.get_level_values(0).unique()

for location in locations:
    split=pivot.xs(location)

    rain=split["rain(mm)"]
    temp=split["temp(dC)"]

    plt.subplots()
    temp.plot(kind="line",color="r",).legend()
    rain.plot(kind="bar").legend()

一个示例绘图输出如下所示:

为什么我的温度值是从 2 月 (2) 月开始绘制的? 我认为这是因为温度值列在第二列中。

从数据透视表中处理和绘制不同数据(两列)的正确方法是什么?

【问题讨论】:

如果您能以 text 形式提供示例数据,对您的帮助会更容易 当然!添加了示例数据。 【参考方案1】:

您可以遍历groupby 操作的结果:

for name, group in data[['loc', 'month', 'rain(mm)', 'temp(dC)']].groupby('loc'):
    group.set_index('month').plot()

【讨论】:

一个更优雅的选择是直接绘制groupby 对象,但我不确定如何使其完全工作:data.groupby('loc').plot()【参考方案2】:

这是因为linebar 的情节没有以同样的方式设置xlim。在条形图的情况下,x 轴被解释为分类数据,而对于折线图,它被解释为连续数据。结果是xlimxticks 在两种情况下的设置不同。

考虑一下:

In [4]: temp.plot(kind="line",color="r",)
Out[4]: <matplotlib.axes._subplots.AxesSubplot at 0x117f555d0>
In [5]: plt.xticks()
Out[5]: (array([ 1.,  2.,  3.,  4.,  5.,  6.]), <a list of 6 Text xticklabel objects>)

其中刻度的位置是一个浮点数组,范围从 1 到 6

In [6]: rain.plot(kind="bar").legend()
Out[6]: <matplotlib.legend.Legend at 0x11c15e950>
In [7]: plt.xticks()
Out[7]: (array([0, 1, 2, 3, 4, 5]), <a list of 6 Text xticklabel objects>)

其中刻度的位置是一个 int 数组,范围从 0 到 5

所以,更换这部分比较容易:

temp.plot(kind="line", color="r",).legend()
rain.plot(kind="bar").legend()

作者:

rain.plot(kind="bar").legend()
plt.plot(range(len(temp)), temp, "r", label=temp.name)
plt.legend()

【讨论】:

++ 很好的解决方案!有没有办法对任何 x 轴(任何类型的数据)执行 range(6) 技巧?我的意思是一个通用的解决方案......也许保存 xticks 或者只是它的长度? @MaxU,谢谢,已修复 你的情节看起来仍然比我的好;)感谢您的澄清!【参考方案3】:

感谢jeanrjc's answer和this thread我想我终于很满意了!

for location in locations:
#print(pivot.xs(location, level=0))

split=pivot.xs(location)
rain=split["rain(mm)"]
temp=split["temp(dC)"]

fig = plt.figure()
ax1 = rain.plot(kind="bar")
ax2 = ax1.twinx()
ax2.plot(ax1.get_xticks(),temp,linestyle='-',color="r")
ax2.set_ylim((-5, 50.))
#ax1.set_ylim((0, 300.))
ax1.set_ylabel('Precipitation (mm)', color='blue')
ax2.set_ylabel('Temperature (°C)', color='red')
ax1.set_xlabel('Months')
plt.title(location)
labels = ['Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dez']
#plt.xticks(range(12),labels,rotation=45)
ax1.set_xticklabels(labels, rotation=45)  

我收到以下输出,这与我的意图非常接近:

【讨论】:

以上是关于Pandas 从数据透视表中绘图的主要内容,如果未能解决你的问题,请参考以下文章

熊猫:从数据透视表中的另一列中减去一列

访问熊猫数据透视表中元素的正确方法

Pandas:编写一个包含所有列的数据透视表以表现出色

从 R 中的数据透视表库呈现的数据透视表中删除小计和总计

如何从数据透视表中删除一行

Pyspark SQL:在数据透视表中保留只有空值的条目