Получение неожиданного вывода при построении графика с помощью 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

Как видно, чем выше требуемая надежность, тем меньше пикселей имеют эту надежность (большее количество пикселей будет белыми, и ни один из них не будет красным).

Но это сюжеты, которые я получаю:

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

Не знаю, почему, если у меня меньше пикселей с нужной надежностью, у меня получается больше не белых пикселей, а вот этих красных. Я не меняю свои объекты, чтобы возиться с ними. Оо

Я застрял в этой проблеме около 3 часов, не зная, что не так.

ИЗМЕНИТЬ:

В этом cmap 0 — синий, 0,5 — белый и 1 — красный, не так ли? Я почти уверен, что проблема в том, что я использую расходящуюся цветовую карту, а иногда и не имею центрального значения. Например, в ситуации, которую я разместил здесь, у меня нет красных значений, поэтому мои значения варьируются от 0,5 до 1. Затем matplotlib автоматически устанавливает мое минимальное значение красным, а максимальное значение — синим. Но как я мог это сделать? Я выбрал это, потому что хотел бы представить цвета на схеме: 0 = синий, 0,5 = белый и 1 = красный (мои значения всегда будут 0, 0,5 или 1).

Любая помощь будет очень, очень признательна.

Заранее спасибо.


person pceccon    schedule 12.04.2014    source источник
comment
Можете ли вы опубликовать минималистичный рабочий пример (включая образец изображения для запуска вашего кода), чтобы можно было воспроизвести сделанные вами графики?   -  person three_pineapples    schedule 12.04.2014
comment
Привет, @three_pineapples. есть проект, который работает параллельно с 9 потоками, занимает 1 час (для создания входных изображений). Как-то сложно предоставить код. :S Но я обнаружил, в чем проблема (см. РЕДАКТИРОВАТЬ), я просто еще не знаю, как ее решить. :С   -  person pceccon    schedule 12.04.2014


Ответы (2)


Как вы упомянули в своем редактировании, проблема вызвана автоматическим масштабированием диапазона цветовой полосы. Вы можете указать диапазон палитры, используя аргументы ключевых слов vmin и vmax для вызова imshow().

В вашем случае это будет:

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), что, вероятно, в любом случае вам действительно нужно!

person three_pineapples    schedule 13.04.2014

Ну, я мог бы добиться того, чего хочу, используя пользовательскую палитру. Это код:

@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()
person pceccon    schedule 12.04.2014