Matplotlib,水平条形图(barh)颠倒

2024-03-28 23:56:33 发布

您现在位置:Python中文网/ 问答频道 /正文

TL'DR,垂直条形图以传统方式显示——东西从左到右排列。然而,当它被转换成水平条形图(从barbarh)时,一切都是颠倒的。一、 例如,对于分组条形图,不仅分组条形图的顺序是错误的,而且每组的顺序也是错误的。

例如,来自http://dwheelerau.com/2014/05/28/pandas-data-analysis-new-zealanders-and-their-sheep/的图

enter image description here

如果你仔细观察,你会发现这个栏和图例的顺序是相反的——牛肉显示在图例的顶部,但在图表的底部。

作为最简单的演示,我将kind='bar',改为kind='barh', 从这个图表 https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chart 结果如下: https://plot.ly/7/~xpt/

即,水平分组条形图中的条形图是颠倒排列的。

怎么解决?

编辑:@ajan,实际上不仅分组条的顺序不对,每组的顺序也不对。来自Simple customization of matplotlib/pandas bar chart (labels, ticks, etc.)的图表清楚地显示了这一点:

the order of the each group is wrong

我们可以看到,这个顺序也很不传统,因为人们会期望图表是自上而下的,顶部是“AAA”,而不是底部。

如果你搜索“Excel颠倒”,你会发现到处都有人在Excel中抱怨。微软的Excel有一个解决方案,Matplotlib/Panda/Searborn/Ploty/etc有一个解决方案吗?


Tags: httpspandasplot顺序错误图表水平ly
3条回答

我认为群和子群的联合错误顺序归结为一个单一的特征:如通常的图所示,y轴向上增加。尝试反转轴的y轴,就像在这个没有熊猫的示例中一样:

import numpy as np
import matplotlib.pyplot as plt

x=range(5)
y=np.random.randn(5)

#plot1: bar
plt.figure()
plt.bar(x,y)

#plot2: barh, wrong order
plt.figure()
plt.barh(x,y)

#plot3: barh with correct order: top-down y axis
plt.figure()
plt.barh(x,y)
plt.gca().invert_yaxis()

特别是对于pandas,pandas.DataFrame.plot及其各种绘图子方法返回matplotlib axes对象,因此可以直接反转其y轴:

ax = df.plot.barh()  # or df.plot(), or similar
ax.invert_yaxis()

我认为解决这个问题最简单的方法是在绘制之前反转pandas数据帧。例如:

df = df.iloc[::-1]
df.plot.barh(stacked=True);

在我看来,这是熊猫巴思功能的一个缺陷。至少用户应该能够传递诸如reverse_order=True等参数

我将认为这是一个错误,即条的y位置分配不正确。不过,修补程序相对简单:

这只是一个正确的顺序,那叫做…,正确的顺序。任何不正确的命令,都是错误的命令。:p页

In [63]:

print df
      Total_beef_cattle  Total_dairy_cattle  Total_sheep  Total_deer  \
1994           0.000000            0.000000     0.000000    0.000000   
2002         -11.025827           34.444950   -20.002034   33.858009   
2003          -8.344764           32.882482   -20.041908   37.229441   
2004         -11.895128           34.207998   -20.609926   42.707754   
2005         -12.366101           32.506699   -19.379727   38.499840   

      Total_pigs  Total_horses  
1994    0.000000      0.000000  
2002  -19.100637     11.811093  
2003  -10.766476     18.504488  
2004   -8.072078     13.376472  
2005  -19.230733   -100.000000  
In [64]:

ax = df.plot(kind='barh', sort_columns=True)

#Get the actual bars
bars = [item for item in ax.get_children() if isinstance(item, matplotlib.patches.Rectangle)]
bars = bars[:df.size]

#Reset the y positions for each bar
bars_y = [plt.getp(item, 'y') for item in bars]
for B, Y in zip(bars, np.flipud(np.array(bars_y).reshape(df.shape[::-1])).ravel()):
    B.set_y(Y)

enter image description here

相关问题 更多 >