Python Matplotlib,水平条形图(barh)是倒置的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34076177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:26:22  来源:igfitidea点击:

Matplotlib, horizontal bar chart (barh) is upside-down

pythonpandasmatplotlibbar-chart

提问by xpt

TL'DR, the vertical bar charts are shown in a conventional way -- things line up from left to right. However, when it is converted to horizontal bar chart (from barto barh), everything is upside-down. I.e., for a grouped bar chart, not only the order of the grouped bar is wrong, the order of the each group is wrong as well.

TL'DR,垂直条形图以传统方式显示 - 从左到右排列。但是,当它转换为水平条形图(从barbarh)时,一切都是颠倒的。即,对于分组条形图,不仅分组条的顺序错误,每个组的顺序也错误。

For e.g., the graph from http://dwheelerau.com/2014/05/28/pandas-data-analysis-new-zealanders-and-their-sheep/

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

enter image description here

在此处输入图片说明

If you look closely, you will find that the the bar and legend are in reverse order -- Beef shows on top in legend but on bottom in the graph.

如果仔细观察,您会发现条形图和图例的顺序相反——牛肉显示在图例的顶部,但在图表的底部。

As the simplest demo, I changed kind='bar',to kind='barh',from this graph https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chartand the result looks like this: https://plot.ly/7/~xpt/

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

I.e., the bars in the horizontal grouped bar chart is ordered upside-down.

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

How to fix it?

如何解决?

EDIT:@Ajean, it is actually not only the order of the grouped bar is wrong, the order of the each group is wrong as well. The graph from Simple customization of matplotlib/pandas bar chart (labels, ticks, etc.)shows it clearly:

编辑:@Ajean,实际上不仅分组条的顺序错误,每个组的顺序也错误。来自matplotlib/pandas 条形图(标签、刻度等)的简单定制的图表清楚地显示了它:

the order of the each group is wrong

每个组的顺序是错误的

We can see that the order is unconventional too, because people would expect the graph to be top-down, with "AAA" at the top, not the bottom.

我们可以看到顺序也是非常规的,因为人们希望图形是自上而下的,“AAA”在顶部,而不是底部。

If you search for "Excel upside-down", you will find people are complaining about this in Excel all over the places. The Microsoft Excel has a fix for it, do Matplotlib/Panda/Searborn/Ploty/etc has a fix for it?

如果你搜索“Excel颠倒”,你会发现到处都有人在Excel中抱怨这个。Microsoft Excel 有修复它,Matplotlib/Panda/Searborn/Ploty/etc 有修复它吗?

采纳答案by Andras Deak

I believe the joint wrong order of groups and subgroups boils down to a single feature: that the yaxis increases upwards, as in a usual plot. Try reversing the yaxis of your axes as in this pandas-less example:

我相信组和子组的联合错误顺序归结为一个特征: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()

Specifically for pandas, pandas.DataFrame.plotand its various plotting submethods return a matplotlib axes object, so you can invert its y axis directly:

专门针对熊猫,pandas.DataFrame.plot其各种绘图子方法返回一个 matplotlib 轴对象,因此您可以直接反转其 y 轴:

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

回答by CT Zhu

I will consider this to be a bug, i.e., the y position of the bars are not assigned correctly. The patch is however relatively simple:

我会认为这是一个错误,即条形的 y 位置未正确分配。然而,补丁相对简单:

This is only one right order of bars, and that is called..., the right order. Anything that is not the right order, is thus a buggy order. :p

这只是一种正确的条形顺序,这就是所谓的...,正确的顺序。因此,任何不正确的顺序都是错误的顺序。: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

在此处输入图片说明

回答by alexsalo

General fix is simple:

一般修复很简单:

handles, labels = axis.get_legend_handles_labels()
# reverse to keep order consistent
axis.legend(reversed(handles), reversed(labels), loc='upper left')

回答by Philipp Schwarz

I believe the simplest solution for this problem is to reverse the pandas dataframe before plotting. For example:

我相信这个问题最简单的解决方案是在绘图之前反转熊猫数据框。例如:

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

In my opinion that is a bug in the pandas barh function. At least users should be able to pass an argument like reverse_order = True etc.

在我看来,这是 pandas barh 函数中的一个错误。至少用户应该能够传递像 reverse_order = True 等参数。