在Matplotlib中分别对堆积的条形图进行排序

时间:2019-10-13 03:11:53

标签: python pandas matplotlib data-visualization

我正在尝试对堆叠条形图的各个组件进行排序,以提高可读性(在DataFrame本身中),或者在对图表进行绘制之后,又无法弄清楚是否有这样做的好方法。

例如,我有这本球员词典,以及与他们的对手花费的时间-

so_oppo_dict = {
  'Player 1': {'Opponent 1': 2.15, 'Opponent 2': 3.5333, 'Opponent 3': 3.1}, 
  'Player 2': {'Opponent 1': 2.2167, 'Opponent 2': 1.8667, 'Opponent 3': 2.3333}, 
  'Player 3': {'Opponent 1': 1.5333, 'Opponent 2': 4.3833, 'Opponent 3': 4.15}
}

然后我使用下面的代码将其绘制成一个堆积的条形图-

fig, ax = plt.subplots()
ax = plt.subplot(111)
so_oppo_df.T.plot(kind="barh", stacked=True, ax=ax)
fig.tight_layout()
fig.savefig('opponents-stacked.png')

我得到的图形如下所示,并且堆叠条形图的每个组件都以相同顺序排序。我想做的是重新排列小节的组成部分,以按从高到低的顺序排序(因此绿色和橙色的小节会先于蓝色的小节出现)-这样可以吗?

enter image description here

1 个答案:

答案 0 :(得分:0)

基于this phenomenal answer,我能够准确地生成所需的内容。这是我在下面完成的代码片段以及生成的图像(带有更大的字典)。

x = so_oppo_df.index
indexes = np.argsort(so_oppo_df.values).T
widths = np.sort(so_oppo_df.values).T
order = -1
lefts = widths[::order].cumsum(axis=0)
lefts = np.insert(lefts, 0, np.zeros(len(lefts[0])), axis=0)

mpp_colors = dict(zip(so_oppo_df.columns, plt.cm.get_cmap("tab20c").colors))

for k, (idxs, vals) in enumerate(list(zip(indexes, widths))[::order]):
    mps = np.take(np.array(so_oppo_df.columns), idxs)
    ax1.barh(x, width=vals, left=lefts[k], color=[mpp_colors[m] for m in mps])

ax1.legend((np.take(np.array(so_oppo_df.columns), np.argsort(so_oppo_df.values)[0]))[::-1], bbox_to_anchor=(1.05, 1), loc='upper left', ncol=1)
ax1.title.set_text(f"Team Opposition - 5v5 Sorted TOI")

Horizontal Bar Chart (Sorted by Individual Values)