【问题标题】:Python Pivot tables custom sort x-axisPython数据透视表自定义排序x轴
【发布时间】:2019-11-15 06:00:40
【问题描述】:

我正在尝试创建一个数据透视表图,其中 x 轴是自定义排序的。 我的代码:

import pandas as pd
data_dict = {
    'x' : [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
    'y' : [9,10,11,12,13,14,15,1,2,3,4,5,6,7,8]
}
res_table = pd.DataFrame(data_dict)

df_pivot = pd.pivot_table(res_table, 
                    index='x', values='y', 
                    aggfunc='sum')

ax = df_pivot.plot(kind='line', marker='*', title='y data')

ax.set(xlabel='x', ylabel='y')
ax.legend(bbox_to_anchor=(1,1), loc="upper left")
ax.figure

这段代码给出了这个情节:

现在我想更改 X 轴,使其从 8 到 15 开始,然后从 1 到 7。这​​样图形就变成了一条直线。

我试过这段代码:(Pandas pivot table Nested Sorting)

order = [8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7]
pd.concat([res_table.loc[res_table['x'] == val, :].set_index(['x']) for val in order])

但这似乎并没有改变什么。

*编辑:当然,我可以添加一个具有正确索引的额外列并使用它绘制图表,但我希望图表显示真实的 x 值。

**编辑:我庆祝得有点早。 我的真实代码有额外的列可以在一张图上绘制多条这些线

data_dict = {
    'x' : [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
    'y' : [9,10,11,12,13,14,15,1,2,3,4,5,6,7,8,29,30,31,32,33,34,35,21,22,23,24,25,26,27,28],
    'z' : [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
}
res_table = pd.DataFrame(data_dict)
df_pivot = pd.pivot_table(res_table, 
                    index='x', values='y', 
                    aggfunc='sum', columns='z')

cut_val = 8
tmp_df = pd.concat((df_pivot.loc[cut_val:], 
                     df_pivot.loc[:cut_val-1])).reset_index()
print(tmp_df)
fig, ax = plt.subplots()

ax.plot(tmp_df.index, tmp_df.y, '-o')
ticks = ax.get_xticks()
ax.set_xticklabels(tmp_df.loc[ticks, 'x'])
ax.figure

代码停在这一行,在 tmp_df.y 上有一个关键错误:

ax.plot(tmp_df.index, tmp_df.y, '-o')

如果没有 columns 参数,代码可以正常工作

在原始代码中,图表如下所示

【问题讨论】:

  • 您是否知道确切的剪切位置,即 8,或者您需要自动检测它?
  • 是的,它知道在哪里切割图形。在这种情况下 8

标签: python-3.x pandas pivot-table


【解决方案1】:

实际上,在这种特殊情况下,我们可以使用sort_valueset_xticklabels

df_pivot = df_pivot.sort_values('y').reset_index()

fig, ax = plt.subplots()

ax.plot(df_pivot.index, df_pivot.y, '-o')
ticks = ax.get_xticks()
ax.set_xticklabels(df_pivot.loc[ticks, 'x'])
plt.show()

输出:

一般来说,您可以使用concat,然后以类似方式使用set_xticklabels

cut_val = 8
tmp_df = pd.concat((df_pivot.loc[cut_val:], 
                     df_pivot.loc[:cut_val-1])).reset_index()

fig, ax = plt.subplots()

ax.plot(tmp_df.index, tmp_df.y, '-o')
ticks = ax.get_xticks()
ax.set_xticklabels(tmp_df.loc[ticks, 'x'])
plt.show()

对于您更新的数据框,tmp_df 实际上还有其他几列,不是y,因为z 中的唯一值:

cut_val = 8
tmp_df = pd.concat((df_pivot.loc[cut_val:], 
                     df_pivot.loc[:cut_val-1])).reset_index()
fig, ax = plt.subplots()

tmp_df[df_pivot.columns].plot(ax=ax, marker='o')
ticks = ax.get_xticks()
ax.set_xticklabels(tmp_df.loc[ticks, 'x'])
plt.show()

输出:

【讨论】:

  • 确实在这种情况下这是可能的,但我的 y 值是测量值,不能保证总是很好地递增。
  • 这似乎确实可以满足我的需要。什么是变量 plt?因为它没有在任何地方定义?已经感谢您的帮助
  • 常用做法:from matplotlib import pyplot as plt。你的ax 实际上是一个plt.Axes 对象。
  • 谢谢。这似乎确实有效。只有他将 x 轴显示为从 0 而不是 8 开始。有没有办法解决这个问题?
  • 我最后忘记了ax.set_xticklabels(tmp_df.loc[ticks, 'x'])。查看更新。
猜你喜欢
  • 1970-01-01
  • 2019-07-01
  • 2019-05-11
  • 1970-01-01
  • 2014-06-18
  • 2012-05-22
  • 2017-02-08
  • 2016-06-10
  • 1970-01-01
相关资源
最近更新 更多