使用Matplotlib绘图时输出异常 - Cmap - Python
我在项目中有一个方法,用来检查一个像素的可靠性(也就是它被分类为边缘的准确性),然后我按照以下方式绘制这些像素:
White -> pixel doesn't have the required reliability
Blue -> pixel has the required reliability and it was classified as not edge
Red -> pixel has the required reliability and it was classified as an edge
这是我的代码:
def generate_data_reliability(classification_mean, data_uncertainty, x_axis_label, y_axis_label, plot_title,
file_path, reliability):
"""
:classification_mean : given a set of images, how was the mean classification for each pixel
:param data_uncertainty : the uncertainty about the classification
:param x_axis_label : the x axis label of the data
:param y_axis_label : the y axis label of the data
:param plot_title : the title of the data
:param file_path : the name of the file
"""
plt.figure()
# 0 -> certainty
# 1 -> uncertainty
r = 0
b = 0
w = 0
has_reliability = numpy.zeros((data_uncertainty.rows, data_uncertainty.cols), float)
for x, y in product(range(data_uncertainty.rows), range(data_uncertainty.cols)):
# I the uncertainty is > then the required reliability, doesn't show it
if data_uncertainty.data[x][y] > (1.0 - reliability):
has_reliability[x][y] = 0.5
w += 1
else:
has_reliability[x][y] = classification_mean.data[x][y]
if has_reliability[x][y] == 1.0:
r += 1
if has_reliability[x][y] == 0.0:
b += 1
print reliability, w+r+b, w, r, b
plt.title(plot_title)
plt.imshow(has_reliability, extent=[0, classification_mean.cols, classification_mean.rows, 0], cmap='bwr')
plt.xlabel(x_axis_label)
plt.ylabel(y_axis_label)
plt.savefig(file_path + '.png')
plt.close()
这是我得到的输出:
>>>> Prewitt
0.8 95100 10329 0 84771
0.9 95100 12380 0 82720
0.99 95100 18577 0 76523
从图中可以看出,当我要求的可靠性提高时,符合这个要求的像素就会变少(更多的像素会显示为白色,而没有一个是红色的)。
但是我得到的图像是这样的:
我不明白的是,如果符合要求的像素变少了,为什么我没有看到更多的白色像素,而是这些红色的。我没有改变我的对象,也没有对它们进行干扰。真是让人困惑。
我在这个问题上卡了大约三个小时,完全不知道哪里出错了。
补充说明:
在这个cmap中,0是蓝色,0.5是白色,1是红色,对吧?我很确定问题出在我使用了一个发散的颜色映射,有时候没有中心值。例如,在我这里发布的情况中,我没有红色值,所以我的值在0.5和1之间变化。然后,matplotlib自动将我的最小值设为红色,最大值设为蓝色。但是我该怎么做呢?我选择这个是因为我想用这样的颜色表示:0=蓝色,0.5=白色,1=红色(我的值总是0、0.5或1)。
任何帮助都将非常非常感谢。
提前谢谢你。
2 个回答
1
正如你在编辑中提到的,问题是由于颜色条范围的自动缩放造成的。你可以通过在调用 imshow()
时使用 vmin
和 vmax
这两个参数来强制设置颜色图的范围。
在你的情况下,可以这样做:
plt.imshow(has_reliability, vmin=0.0, vmax=1.0, extent=[0, classification_mean.cols, classification_mean.rows, 0], cmap='bwr')
这样一来,你的数据范围就不会影响颜色图的缩放了!不过,自己创建一个颜色图(就像你在自己的回答中提到的那样)可以让你在长远来看有更多的控制权。我觉得你提供的例子在值的范围内没有给出渐变效果(比如默认的颜色图在0.5到1.0之间的值会混合红色和白色),这可能正是你真正想要的效果!
0
好的,我可以通过使用自定义的颜色映射来实现我想要的效果。以下是代码:
@staticmethod
def generate_data_reliability(classification_mean, data_uncertainty, x_axis_label, y_axis_label, plot_title,
file_path, reliability):
"""
:param data_uncertainty : the uncertainty about the data
:param x_axis_label : the x axis label of the data
:param y_axis_label : the y axis label of the data
:param plot_title : the title of the data
:param file_path : the name of the file
"""
color_map = mpl.colors.ListedColormap(['blue', 'white', 'red'])
# From 0 to 0.24 -> blue
# From 0.25 to 0.4 -> white
# From 0.5 to 1.0 -> red
bounds = [0.0, 0.25, 0.5, 1.0]
norm = mpl.colors.BoundaryNorm(bounds, color_map.N)
plt.figure()
# 0 -> certainty
# 1 -> uncertainty
r = 0
b = 0
w = 0
has_reliability = numpy.zeros((data_uncertainty.rows, data_uncertainty.cols), float)
for x, y in product(range(data_uncertainty.rows), range(data_uncertainty.cols)):
# I the uncertainty is > then the required reliability, doesn't show it
if data_uncertainty.data[x][y] > (1.0 - reliability):
has_reliability[x][y] = 0.4
else:
has_reliability[x][y] = classification_mean.data[x][y]
plt.title(plot_title)
plt.imshow(has_reliability, extent=[0, classification_mean.cols, classification_mean.rows, 0],
interpolation='nearest', cmap=color_map, norm=norm)
plt.xlabel(x_axis_label)
plt.ylabel(y_axis_label)
plt.savefig(file_path + '.png')
plt.close()