Установить диапазон цветовой шкалы в matplotlib - PullRequest
126 голосов
/ 30 июля 2010

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

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 против Y с использованием указанной цветовой карты. Оси X и Y идеальны, но цветовая карта распространяется между минимальным и максимальным значениями v. Я бы хотел, чтобы цветовая карта находилась в диапазоне от 0 до 1.

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

plt.axis(...)

Чтобы установить диапазоны осей, но для этого нужны аргументы только для минимального и максимального значений 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 не будут отображаться на графике, но будут отображаться на цветовой шкале сбоку.

Ответы [ 4 ]

149 голосов
/ 31 июля 2010

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

enter image description here

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()
67 голосов
/ 31 июля 2010

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

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)
plt.show()
14 голосов
/ 30 июля 2010

Не уверен, что это самое элегантное решение (именно это я и использовал), но вы можете масштабировать свои данные в диапазоне от 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 голосов
/ 22 августа 2018

Использование графического окружения и .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, потому что он быстрее (больше здесь ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...