【问题标题】:Getting unexpected output when plotting with Matplotlib - Cmap - Python使用 Matplotlib - Cmap - Python 绘图时得到意外输出
【发布时间】:2014-04-12 00:54:28
【问题描述】:

我在我的项目中有一个方法,我在该方法中验证一个像素是否具有所需的可靠性(就其是否为边缘的分类而言),并按以下方案绘制像素:

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

可以看出,随着所需的可靠性越来越高,具有这种可靠性的像素越少(更多的像素将被绘制为白色,并且没有一个是红色的)。

但这是我得到的情节:

我不知道为什么,如果具有所需可靠性的像素较少,我不会得到更多的白色像素,而是这些红色像素。我不会改变我的对象,来弄乱它们。哦

我被困在这个问题上大约 3 个小时,不知道出了什么问题。

编辑:

在这个cmap中,0 是蓝色,0.5 是白色,1 是红色,不是吗?我很确定问题是因为我使用的是发散的颜色图,有时并没有中心值。例如,在我在这里发布的情况下,我没有红色值,所以我的值在 0.5 和 1 之间变化。然后,matplotlib 自动将我的最小值设置为红色,将我的最大值设置为蓝色。但我怎么能这样做呢?我选择这个是因为想在方案中表示颜色:0=蓝色、0.5=白色和 1=红色(我的值将始终为 0、0.5 或 1)。

任何帮助都将非常非常感谢。

提前谢谢你。

【问题讨论】:

  • 您能否发布一个简单的工作示例(包括示例图像以在您的代码中运行),以便您制作的图可以重现?
  • 嗨,@three_pineapples。有一个与 9 个线程并行运行的项目需要 1 小时(生成输入图像)。提供代码有点复杂。 :S 但我发现问题出在哪里(见编辑),我只是不知道如何解决它。 :S

标签: python matplotlib plot colormap


【解决方案1】:

正如您在编辑中提到的,问题是由颜色条范围的自动缩放引起的。您可以通过在调用imshow() 时使用vminvmax 关键字参数来强制设置颜色图的范围。

在你的情况下,这将是:

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 之间的不同数量的白色)这可能是你真正想要的!

【讨论】:

    【解决方案2】:

    嗯,我可以使用自定义颜色图来实现我想要的。这是代码:

    @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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 2023-01-27
      • 2021-09-28
      相关资源
      最近更新 更多