[英]Matplotlib, horizontal bar chart (barh) is upside-down
TL'DR , the vertical bar charts are shown in a conventional way -- things line up from left to right. TL'DR ,垂直条形图以传统方式显示 - 事物从左到右排列。 However, when it is converted to horizontal bar chart (from
bar
to barh
), everything is upside-down. 但是,当它被转换为水平条形图(从
bar
到barh
)时,一切都是颠倒的。 Ie, 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. 即,对于分组条形图,不仅分组条的顺序是错误的,每个组的顺序也是错误的。
For eg, 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/的图表
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-chart and the result looks like this: https://plot.ly/7/~xpt/ 作为最简单的演示,我从这个图https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chart改变了
kind='bar',
到kind='barh',
结果看起来像这个: https : //plot.ly/7/~xpt/
Ie, 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. 编辑: @Ajean,它实际上不仅是分组栏的顺序错误,每个组的顺序也是错误的。 The graph from Simple customization of matplotlib/pandas bar chart (labels, ticks, etc.) shows it clearly:
简单定制matplotlib / pandas条形图(标签,刻度等)的图表清楚地显示:
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. 如果您搜索“Excel颠倒”,您会发现人们在Excel中的所有地方都在抱怨这一点。 The Microsoft Excel has a fix for it, do Matplotlib/Panda/Searborn/Ploty/etc has a fix for it?
Microsoft Excel有一个修复它,Matplotlib / Panda / Searborn / Ploty /等有没有修复它?
I believe the joint wrong order of groups and subgroups boils down to a single feature: that the y
axis increases upwards, as in a usual plot. 我认为群组和子群的联合错误顺序归结为一个特征:
y
轴向上增加,就像在通常的情节中一样。 Try reversing the y
axis of your axes as in this pandas-less example: 尝试反转轴的
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()
I believe the simplest solution for this problem is to reverse the pandas dataframe before plotting. 我相信这个问题的最简单的解决方案是在绘图之前反转pandas数据帧。 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.
至少用户应该能够传递一个像reverse_order = True等参数。
I will consider this to be a bug, ie, the y position of the bars are not assigned correctly. 我会认为这是一个错误,即没有正确分配条形的y位置。 The patch is however relatively simple:
然而,补丁相对简单:
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)
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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.