【发布时间】: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