简体   繁体   English

如何控制在matplotlib 2.1.0 barh图表中显示条的顺序?

[英]How do I control the order to display bars in a matplotlib 2.1.0 barh chart?

I am using matplotlib 2.1.0 to display a horizontal bar graph. 我正在使用matplotlib 2.1.0来显示水平条形图。 I've sorted the data by value, but matplotlib is displaying the bars in alphabetic order of their labels. 我已经按值对数据进行了排序,但是matplotlib是以标签的字母顺序显示条形图。

fig, [ax1,ax2] = plt.subplots(nrows=1,ncols=2, figsize = (8,3))
probs = [ 0.748, 0.052, 0.0376, 0.022, 0.017 ]
names = [ 'hibiscus', 'petunia', 'iris', 'rose', 'hyacinth' ]
ax1.barh( names, probs )

The result looks roughly like this (sorry I cannot paste the image): 结果大致如下所示(抱歉,我无法粘贴图像):

    rose - **
 petunia - *****
    iris - ***
hyacinth - *
hibiscus - ************************************

As you can see, the bars are displayed in alphabetic (or reverse-alphabetic) order. 如您所见,这些条以字母(或反向字母)顺序显示。 I want them displayed in list order: 我希望它们以列表顺序显示:

hibiscus - ************************************
 petunia - *****
    iris - ***
    rose - **
hyacinth - *

I found a related question here on SO (I've lost the link now) that indicated this was a problem with an older version of matplotlib. 我在SO上找到了一个相关问题(我现在失去了链接),这表明这是较旧版本的matplotlib的问题。 This was the suggested solution: 这是建议的解决方案:

ax1.barh( range(len(names)), probs )
ax1.set_yticks( range(len(names)), names )

This approach displays the data in the proper order, or at least in reverse order. 这种方法以正确的顺序或至少以相反的顺序显示数据。 But it doesn't display the text labels. 但是它不显示文本标签。 Instead, matplotlib labels the bars by index and ignores the names entirely. 取而代之的是,matplotlib通过索引标记条形,并完全忽略名称。

       4 - *
       3 - **
       2 - ***
       1 - *****
       0 - ************************************

I don't have control over the version of matplotlib being used, so I'm looking for a way to tell matplotlib to display data in the proper order with the label names. 我无法控制所使用的matplotlib的版本,因此我正在寻找一种方法来告诉matplotlib使用标签名称以正确的顺序显示数据。

I also found this question: How to determine the order of bars in a matplotlib bar chart . 我也发现了这个问题: 如何确定matplotlib条形图中的条形顺序 That solution is using a pandas DataFrame. 该解决方案使用的是熊猫DataFrame。 I'm not using pandas and it seems like overkill to convert the data to a DataFrame just to convince matplotlib to behave nicely. 我没有使用熊猫,将数据转换为DataFrame只是为了说服matplotlib表现得好极了。

How do I control the order in which matplotlib displays the bars? 如何控制matplotlib显示条的顺序?


Addendum 附录

This question has been tagged as a duplicate of the other related question I had lost reference to: Pyplot sorting y-values automatically . 该问题被标记为与我不再参考的其他相关问题的重复: Pyplot自动对y值进行排序 The difference is subtle, but there is an important distinction between the two ways of calling barh() . 区别是细微的,但是在调用barh()的两种方式之间有重要的区别。 The code in this question first uses the return value of a call to subplots() like this: 这个问题中的代码首先使用对subplots()的调用的返回值,如下所示:

fig, [ax1,ax2] = plt.subplots(...)
ax1.barh(...)

The code in the other question uses a different interface: 另一个问题中的代码使用不同的接口:

plot.subplot(...)
plot.barh(...)

I don't know why these should work differently, but they do. 我不知道为什么它们应该以不同的方式工作,但是它们确实可以。 Specifically, the answer to the other question (quoted below) did not work with the code in this question. 具体来说,另一个问题(下面引用)的答案不适用于该问题中的代码。

plt.barh(range(len(w)),n)
plt.yticks(range(len(w)),w)

So I tried that solution, but it failed. 因此,我尝试了该解决方案,但失败了。

ax1.barh(range(len(names)),probs)
 ### this next call generated a runtime error because ax1 has no method yticks()
ax1.yticks(range(len(names)),names)

However, I discovered that there was an apparently similar call, so I tried it: 但是,我发现有一个显然相似的呼叫,因此我尝试了它:

ax1.barh( range(len(names)), probs )
ax1.set_yticks( range(len(names)), names )

As I discussed in the original post, this approach produced axis labels from the numeric index values and ignored the name strings. 正如我在原始文章中所讨论的那样,此方法从数字索引值生成了轴标签,而忽略了名称字符串。

One final remark: the actual answer to this question has been provided in the comments. 最后一点:评论中提供了该问题的实际答案。 I would like this question unlocked so Lorren or I can write a formal answer for anyone who runs across this same problem in the future. 我想解开这个问题,以便Lorren或我可以为将来遇到此问题的任何人写一个正式答案。

Thanks go to @LorranSutter, who gave me the necessary hint to answer this question. 感谢@LorranSutter,他给了我必要的提示来回答这个问题。

ax1.barh( range(len(names)), probs )
ax1.set_yticks( range(len(names))  )
ax1.set_yticklabels( names )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM