首页 > 解决方案 > Matplotlib:如果绘制了 numpy.nan 值,则不显示堆积条

问题描述

这个来自 matplotlib 网站的堆叠条形图的简单示例准确地展示了我正在尝试做的事情。但是,我使用的数据是动态的,并且通常包含零值。但是,当我绘制零值时,它们在图表上显示为一条细小的细线。根据其他一些 帖子的建议,我用 numpy.nan 值替换了零值。但是,这产生了一个新问题:如果该 x 值上的条之一是 numpy.nan,则不会显示堆叠条。

我将 matplotlib 与 Qt5Agg 后端一起使用,因为我在我的 PyQt5 应用程序中嵌入了 matplotlib 图。但是,我认为这与该问题无关,因为它可以在以下示例中重现。

这是网站上的一个简化示例:(1) Stacked Bars with Non-NaN Data,由以下内容生成:

import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt

menMeans = (10, 35, 30, 35, 27)
womenMeans = (20, 32, 34, 20, 25)
ind = np.arange(5)
width = 0.35

p1 = plt.bar(ind, menMeans, width)
p2 = plt.bar(ind, womenMeans, width, bottom=menMeans)

plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))
plt.axes().set_ylim(0, 80)

plt.show()

(2) 这个例子是我遇到的问题。它是由以下人员制作的:

import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt

menMeans = (np.nan, 35, 30, 35, 27)                                  # NAN VALUE WAS ADDED
womenMeans = (20, 32, 34, 20, 25)
ind = np.arange(5)
width = 0.35

p1 = plt.bar(ind, menMeans, width)
p2 = plt.bar(ind, womenMeans, width, bottom=menMeans)

plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))
plt.axes().set_ylim(0, 80)

plt.show()

问题:如何处理在 matplotlib 中的堆积条形图上绘制零值/numpy.nan 值?我想要的行为如下:不应显示零值条,但仍应允许显示其顶部的其他条。

这是我的第一篇文章。抱歉,如果我犯了任何错误。我试图完全遵守规则。

标签: pythonpython-3.xmatplotlib

解决方案


在您的论点中使用numpynan_to_num()将 NaN 替换为零:bottom=

menMeans = (np.nan, 35, 30, 35, 27)                                  # NAN VALUE WAS ADDED
womenMeans = (20, 32, 34, 20, 25)
ind = np.arange(5)
width = 0.35

p1 = plt.bar(ind, menMeans, width)
p2 = plt.bar(ind, womenMeans, width, bottom=np.nan_to_num(menMeans))  # no more NaNs in bottom=

plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))
plt.ylim((0,80))

plt.show()

PS:如果您使用的是 pyplot 方法(请参阅pyplot 和面向对象 API 之间的区别),您应该调用plt.ylim(),而不是您正在做的事情


推荐阅读