Выравнивание цветовых полей и меток в дискретной цветовой полосе

Я пытаюсь создать заполненный контурный график с дискретными контурными уровнями, которые мне нужно контролировать, чтобы сравнивать значения из разных источников данных. Я думал, что это должно быть легко достигнуто с помощью fig.colorbar(c, ax=ax, ticks=my_levels). Однако, как видно из приведенного ниже примера, что-то пошло не так с выравниванием цветов и значений, и я не смог понять, что не так с моим кодом.

Пример неправильного выравнивания цветов на цветовой полосе

Вот код:

# -*- coding: cp1252 -*-
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
import numpy as np

def plot_discrete(x, y, data, cmax, nclevel=11):
    """Plot filled contour plot and add colorbar with discrete (linear) spacing"""
    matplotlib.rcParams.update({'font.size' : 22})
    # prepare plot
    fig = plt.figure(figsize=(10,7), dpi=150)
    fig.suptitle(unicode("Test ÄÖÜßäöü","latin-1"), fontsize=20, fontweight='bold')
    ax = fig.add_subplot(1,1,1)
    # determine contour levels and set color scale (norm)
    clevel = np.linspace(0., cmax, nclevel)
    print "clevel = ", clevel
    print "cmax, max(data) = ", cmax, np.max(data)
    norm = matplotlib.colors.BoundaryNorm(clevel, ncolors=256, clip=False)
    # generate the contour plot
    c = ax.contourf(x, y, data, level=clevel, norm=norm)
    # prep up axis formatting and labelling
    ax.set_xlabel('X',{'fontsize':20})
    ax.set_ylabel('Y',{'fontsize':20})
    ax.xaxis.set_major_formatter(ScalarFormatter())
    ax.yaxis.set_major_formatter(ScalarFormatter())
    # add the colorbar
    fig.colorbar(c, ax=ax, norm=norm, ticks=clevel, boundaries=clevel)
    plt.show()


if __name__ == "__main__":
    x = np.linspace(0.,10.,20)
    y = np.linspace(-10.,10.,21)
    data = np.zeros((x.size, y.size))
    for i,xx in enumerate(x):
        for j,yy in enumerate(y):
            data[i,j] = np.sqrt(xx)*yy**2
    plot_discrete(y, x, data, 360.)

person maschu    schedule 02.09.2013    source источник
comment
Запуск вашего кода на моем компьютере выдает этот вывод, который не демонстрирует такого же поведения. У меня установлен matplotlub 1.3.0, если вы еще не подумали об обновлении?   -  person Greg    schedule 03.09.2013
comment
Спасибо - это интересно. Тем не менее, ваш результат также не то, что я хочу, потому что уровни должны доходить до 360 и показывать темно-красный цвет в качестве конечного цвета, хотя на самом контурном графике темно-красного нет.   -  person maschu    schedule 03.09.2013
comment
Извините, я не правильно понял проблему.   -  person Greg    schedule 03.09.2013


Ответы (1)


После некоторого копания я считаю, что обнаружил вашу проблему:

Линия

c = ax.contourf(x, y, data, level=clevel, norm=norm)

должен иметь level как levels, что означает, что теперь он видит правильный аргумент и использует ваши пользовательские уровни!

person Greg    schedule 03.09.2013
comment
Большое спасибо! Это действительно так. Неприятная особенность контура принимать уровень без жалоб и заставлять его выглядеть почти правильно. Только одно маленькое дополнение: ключевое слово ticks=clevel по-прежнему имеет значение - без него вы можете получить пометку только каждой второй границы. - person maschu; 03.09.2013
comment
Хорошо, я удалил эту часть, так как она не была особенно полезной. - person Greg; 04.09.2013