Установите Colorbar Range в matplotlib

У меня есть следующий код:

import matplotlib.pyplot as plt

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')

plt.colorbar()
plt.show()

Таким образом, это создает график значений "v" по осям X vs Y, используя указанную цветовую палитру. Оси X и Y идеальны, но цветовая палитра распространяется между минимальными и максимальными значениями v. Я хотел бы, чтобы цветная шкала находилась в диапазоне от 0 до 1.

Я думал об использовании:

plt.axis(...)

Чтобы установить диапазоны осей, но это принимает только аргументы для min и max X и Y, а не для цветовой карты.

Edit:

Для наглядности предположим, что у меня есть один граф, диапазон значений которого (0... 0,3), и другой график, значения которого (0,2... 0,8).

В обоих графиках я хочу, чтобы диапазон цветовой панели был (0... 1). В обоих графиках я хочу, чтобы этот диапазон цветов был идентичным, используя весь диапазон cdict выше (поэтому 0,25 на обоих графиках будет одного цвета). На первом графике все цвета от 0,3 до 1,0 не будут отображаться на графике, но будут отображаться в цветной клавише сбоку. В другом случае все цвета от 0 до 0,2 и от 0,8 до 1 не будут отображаться на графике, но в цветовой панели сбоку.

Ответ 1

Использование vmin и vmax заставляет диапазон для цветов. Вот пример:

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

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )

def do_plot(n, f, title):
    #plt.clf()
    plt.subplot(1, 3, n)
    plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
    plt.title(title)
    plt.colorbar()

plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()

Ответ 2

Используйте функцию CLIM (эквивалентно CAXIS в MATLAB):

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)
plt.show()

Ответ 3

Не уверен, что это самое элегантное решение (это то, что я использовал), но вы можете масштабировать свои данные в диапазоне от 0 до 1, а затем изменять цветную панель:

import matplotlib as mpl
...
ax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.5)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cm,
                       norm=mpl.colors.Normalize(vmin=-0.5, vmax=1.5))
cbar.set_clim(-2.0, 2.0)

С двумя разными пределами вы можете управлять диапазоном и легендой цветовой панели. В этом примере в полосе отображается только диапазон от -0,5 до 1,5, тогда как в цветовой палитре от -2 до 2 (так что это может быть ваш диапазон данных, который вы записываете до масштабирования).

Таким образом, вместо масштабирования цветовой карты вы масштабируете свои данные и подгоняете цветную панель.

Ответ 4

Использование среды рисунков и.set_clim()

Это может быть проще и безопаснее, если у вас есть несколько графиков:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )
data1 = np.clip(data,0,6)
data2 = np.clip(data,-6,0)
vmin = np.min(np.array([data,data1,data2]))
vmax = np.max(np.array([data,data1,data2]))

fig = plt.figure()
ax = fig.add_subplot(131)
mesh = ax.pcolormesh(data, cmap = cm)
mesh.set_clim(vmin,vmax)
ax1 = fig.add_subplot(132)
mesh1 = ax1.pcolormesh(data1, cmap = cm)
mesh1.set_clim(vmin,vmax)
ax2 = fig.add_subplot(133)
mesh2 = ax2.pcolormesh(data2, cmap = cm)
mesh2.set_clim(vmin,vmax)
# Visualizing colorbar part -start
fig.colorbar(mesh,ax=ax)
fig.colorbar(mesh1,ax=ax1)
fig.colorbar(mesh2,ax=ax2)
fig.tight_layout()
# Visualizing colorbar part -end

plt.show()

enter image description here

Одна цветная панель

Лучшей альтернативой является использование одной цветной полосы для всего участка. Существуют разные способы сделать это, этот учебник очень полезен для понимания наилучшего варианта. Я предпочитаю это решение, которое вы можете просто скопировать и вставить вместо предыдущей визуализации цветной части кода.

fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,
                    wspace=0.4, hspace=0.1)
cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])
cbar = fig.colorbar(mesh, cax=cb_ax)

enter image description here

PS

Я бы предложил использовать pcolormesh вместо pcolor потому что он быстрее (здесь больше информации).