【问题标题】:How do I control the order to display bars in a matplotlib 2.1.0 barh chart?如何控制在 matplotlib 2.1.0 barh 图表中显示条形的顺序?
【发布时间】:2018-07-20 11:30:03
【问题描述】:

我正在使用 matplotlib 2.1.0 来显示水平条形图。我已经按值对数据进行了排序,但 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 )

结果大概是这样的(抱歉我无法粘贴图片):

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

如您所见,条形图按字母(或反字母)顺序显示。我希望它们按列表顺序显示:

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

我在 SO 上发现了一个相关问题(我现在失去了链接),表明这是旧版本的 matplotlib 的问题。这是建议的解决方案:

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

这种方法以正确的顺序或至少以相反的顺序显示数据。但它不显示文本标签。相反,matplotlib 按索引标记条形并完全忽略名称。

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

我无法控制正在使用的 matplotlib 的版本,所以我正在寻找一种方法来告诉 matplotlib 以正确的顺序显示带有标签名称的数据。

我也发现了这个问题:How to determine the order of bars in a matplotlib bar chart。该解决方案正在使用 pandas DataFrame。我没有使用 pandas,将数据转换为 DataFrame 似乎是为了说服 matplotlib 表现良好。

如何控制 matplotlib 显示条形的顺序?


附录

此问题已被标记为与我丢失的其他相关问题的重复:Pyplot sorting y-values automatically。区别是微妙的,但是调用barh() 的两种方式之间有一个重要的区别。这个问题中的代码首先使用了对subplots() 的调用的返回值,如下所示:

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

另一个问题中的代码使用了不同的接口:

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

我不知道为什么它们的工作方式会有所不同,但它们确实如此。具体来说,另一个问题的答案(引用如下)不适用于此问题中的代码。

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

所以我尝试了那个解决方案,但失败了。

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)

但是,我发现有一个明显相似的调用,所以我尝试了一下:

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

正如我在原帖中所讨论的,这种方法从数字索引值生成轴标签并忽略名称字符串。

最后一点:该问题的实际答案已在 cmets.xml 中提供。我希望解锁这个问题,以便 Lorren 或我可以为将来遇到同样问题的任何人写一个正式的答案。

【问题讨论】:

  • 尝试使用ax1.set_yticklabels(names)
  • 谢谢@LorranSutter!我不得不进行更多实验才能发现,除了您的建议之外,我还必须删除set_yticks() 的第二个参数,使其看起来像这样:ax1.set_yticks( range(len(names)) )。现在它工作得很好。谢谢!

标签: python matplotlib


【解决方案1】:

感谢@LorranSutter,他给了我必要的提示来回答这个问题。

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

【讨论】:

    猜你喜欢
    • 2012-09-26
    • 2013-12-31
    • 2016-03-08
    • 2021-10-29
    • 1970-01-01
    • 2015-10-11
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多