Тот же диапазон цветовых полос для разных графиков – Matplotlib

Я изо всех сил пытаюсь сохранить один и тот же диапазон цветовых полос на разных графиках.

Например, у меня есть эти визуализации:

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

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

Которые производятся с этим кодом:

def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, file_path):
    plt.figure()

    x, y = numpy.mgrid[-x_dim:x_dim/:x_steps*1j, -y_dim:y_dim:y_steps*1j] 
    cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim, x_dim, -y_dim, y_dim])
    plt.colorbar(cs)

    plt.savefig(file_path + '.png', dpi=Vc.dpi)
    plt.close()

Я хочу иметь возможность сравнивать оба поля, поэтому я хотел бы использовать одно и то же сопоставление цветов для них обоих.

Мой первый подход состоял в том, чтобы использовать параметры v_min и v_max, используя минимальные/максимальные значения данных.

cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim, x_dim, -y_dim, y_dim], vmin=-1.00, vmax=1.05) # Manual setting to test

Затем я получил такое же сопоставление цветов:

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

Но я также хотел бы, чтобы на графике отображался тот же диапазон цветовых полос. я пытался использовать

cb = plt.colorbar(cs)
cb.set_clim(vmin=-1.00, vmax=1.05)

Без успеха.

Этот полный пример производит такое же поведение:

import matplotlib
import numpy as numpy
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'

delta = 0.025
x = numpy.arange(-3.0, 3.0, delta)
y = numpy.arange(-2.0, 2.0, delta)
X, Y = numpy.meshgrid(x, y)

Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians

Za = 10.0 * (Z2 - Z1)
Zb = 5.0 * (Z2 - Z1)

def bounds(scalar_fields):
    """
    Get the bounds of a set of scalar_fields
    :param scalar_fields : the scalar field set
    :return: a set of normalized vector field components
    """
    max_bound = -numpy.inf
    min_bound = numpy.inf

    for scalar_field in scalar_fields:
        max_lim = numpy.max(scalar_field)
        min_lim = numpy.min(scalar_field)
        if max_lim > max_bound:
            max_bound = max_lim
        if min_lim < min_bound:
            min_bound = min_lim

    return min_bound, max_bound

def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, v_min, v_max, file_path):
    plt.figure()

    x, y = numpy.mgrid[-x_dim/2:x_dim/2:x_steps*1j, -y_dim/2:y_dim/2:y_steps*1j]

    cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim/2.0, x_dim/2.0, -y_dim/2.0, y_dim/2.0],
                      vmin=v_min, vmax=v_max)
    cb = plt.colorbar(cs)

    plt.savefig(file_path + '.png')
    plt.close()

v_min, v_max = bounds([Za, Zb])
x_dim = y_dim = 6

y_steps = x.shape[0]
x_steps = y.shape[0]    

plot_contour(x_dim, y_dim, x_steps, y_steps, Za, v_min, v_max, 'Za')
plot_contour(x_dim, y_dim, x_steps, y_steps, Zb, v_min, v_max, 'Zb') 

Как я мог это сделать?

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


person pceccon    schedule 26.09.2014    source источник
comment
Поставить vmin и vmax на оба звонка? То, что вы делаете, должно работать. Можете ли вы воспроизвести это в полном вызываемом примере (включая синтетические данные)?   -  person tacaswell    schedule 26.09.2014
comment
Да, я ставлю этот параметр в оба вызова, функция одна и та же. Я сделаю это.   -  person pceccon    schedule 26.09.2014
comment
и я думаю, что set_clim должен идти на объект cs, а не на цветовую полосу.   -  person tacaswell    schedule 26.09.2014


Ответы (1)


Если вы хотите, чтобы цвета на цветовых полосах соответствовали одним и тем же значениям на двух контурных графиках, вам нужно не только управлять цветовой полосой, но и уровнями на контурном графике. То есть, чтобы сравнивать одинаковые уровни между графиками, графики должны иметь одинаковые уровни изолиний. Это легко сделать. Вот пример такого сюжета:

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

Есть два пути: 1) рассчитать уровни заранее; 2) использовать уровни с одного графика для установки уровней на другом. Я сделаю второй, так как из этого должно быть понятно, как делать первый (используя, например, levels = numpy.linspace(v_min, vmax, 10), правда, для ясности, я не использую здесь это, а даю mpl считать уровни).

Во-первых, здесь я также использую:

Za = 10.0 * (Z2 - Z1)
Zb = 6.0 * (Z2 - Z1)   # 6, rather than 5

Затем, чтобы построить:

def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, file_path, v_min, v_max, levels=None):
    x, y = numpy.mgrid[-x_dim/2:x_dim/2:x_steps*1j, -y_dim/2:y_dim/2:y_steps*1j]
    cs = plt.contourf(x, y, scalar_field, zorder=1, cmap=cm.jet, extent=[-x_dim/2.0, x_dim/2.0, -y_dim/2.0, y_dim/2.0], vmin=v_min, vmax=v_max, levels=levels)
    plt.colorbar(cs)
    return cs.levels

v_min, v_max = bounds([Za, Zb])

plt.figure()
plt.subplot(121)
levels = plot_contour(x_dim, y_dim, x_steps, y_steps, Za, 'Za', v_min, v_max)
plt.subplot(122)
plot_contour(x_dim, y_dim, x_steps, y_steps, Zb, 'Zb', v_min, v_max, levels=levels) 
plt.show()
person tom10    schedule 28.09.2014
comment
Значит, в этом примере не может быть 5? Минимальные и максимальные уровни одного сюжета должны охватывать пределы другого? У меня нет такого контроля данных, они взяты из прогнозов и, если условие, которое я упоминаю, необходимо, то через мой ансамбль этого не будет. :/ - person pceccon; 03.10.2014
comment
Нет, это был просто пример использования одного набора уровней для обоих. Вы можете указать уровни, как хотите, и вы можете просто, скажем, передать levels=np.arange(-5,6) обоим. Суть в том, что если вы хотите иметь две дискретизированные палитры цветов, совпадающие с уровнями (и, разумеется, эти уровни также совпадающие с контурами), то сами уровни должны совпадать. - person tom10; 03.10.2014
comment
Ok. Я попробую это здесь и приму ваш ответ. Спасибо, @tom10. - person pceccon; 03.10.2014
comment
Нет проблем, и нет необходимости принимать это, если оно в основном не делает то, что вы хотите. - person tom10; 03.10.2014
comment
Оно делает. (: Еще раз спасибо. - person pceccon; 03.10.2014
comment
Спасибо! Вы сделали мой день! Самая важная часть ответа заключается в том, что недостаточно установить vmin, vmax или параметры цветовой полосы, а просто установить уровни! - person Dr_Zaszuś; 23.12.2019