Matplotlib, horizontal bar chart (barh) is upside-down
TL'DR,垂直条形图以常规方式显示-东西从左到右排列。但是,将其转换为水平条形图(从
例如,该图来自http://dwheelerau.com/2014/05/28/pandas-data-analysis-new-zealanders-and-their-sheep/
如果仔细观察,会发现条和图例的顺序相反-牛肉在图例的顶部显示,但在图形的底部显示。
作为最简单的演示,我将
从这张图
https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chart
结果看起来像这样:
https://plot.ly/7/~xpt/
也就是说,水平分组条形图中的条形颠倒排列。
如何解决?
编辑:@Ajean,实际上不仅是分组条的顺序是错误的,而且每个组的顺序也是错误的。 matplotlib / pandas条形图的简单定制中的图形(标签,刻度等)清楚地显示了它:
我们可以看到顺序也是非常规的,因为人们希望图形是自上而下的," AAA"在顶部,而不是底部。
如果您搜索" Excel上下颠倒",您会发现人们在各地抱怨着Excel。 Microsoft Excel有一个修复程序,Matplotlib / Panda / Searborn / Ploty / etc是否有修复程序?
我相信组和子组的联合错误顺序归结为一个特征:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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() |
专门针对大熊猫,
1 2 | ax = df.plot.barh() # or df.plot(), or similar ax.invert_yaxis() |
我认为解决此问题的最简单方法是在绘制之前反转熊猫数据框。例如:
1 2 | df = df.iloc[::-1] df.plot.barh(stacked=True); |
我认为这是熊猫barh功能中的错误。至少用户应该能够传递类似reverse_order = True等的参数。
我会认为这是一个错误,即条的y位置分配不正确。但是,补丁相对简单:
这只是条的正确顺序,也就是...,正确的顺序。因此,任何不正确的命令都是错误的命令。 :p
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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) |
常规修复很简单:
1 2 3 | handles, labels = axis.get_legend_handles_labels() # reverse to keep order consistent axis.legend(reversed(handles), reversed(labels), loc='upper left') |