Как определить цветовой код с абсолютными значениями с помощью matplotlib

Я использую следующий script для построения:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pylab as pl
import math
import matplotlib as mpl
from matplotlib.ticker import MultipleLocator
from matplotlib.colors import LinearSegmentedColormap
cdict1 = {'red': ((0.0, 1.0, 1.0),
 (0.4, 1.0, 1.0),
 (0.7, 0.0, 0.0),
 (1.0, 0.0, 0.0)),
 'green': ((0.0, 1.0, 1.0),
 (0.1, 0.0, 0.0),
 (1.0, 0.0, 0.0)),
 'blue': ((0.0, 1.0, 1.0),
 (0.1, 0.0, 0.0),
 (0.4, 0.0, 0.0),
 (1.0, 1.0, 1.0))
 }
white_blue_red = LinearSegmentedColormap('WhiteBlueRed', cdict1)
plt.register_cmap(cmap=white_blue_red)
x = np.loadtxt('data.dat',
 unpack=True)
plt.scatter(x[0], x[1], marker='.', s=3, linewidths=0, c=x[3], cmap= \
 plt.get_cmap('WhiteBlueRed')) # plt.cm.bwr 
plt.colorbar()
plt.show()

Определенная мной цветовая схема использует относительные значения (0 минимальное значение максимального значения функции 1). проблема в том, что я хочу использовать этот код для построения сотен разных файлов, и я хочу, чтобы каждый сюжет имел тот же самый цвет. Есть ли возможность определить цветовые карты с абсолютными значениями? Это решит мою проблему.

1 ответ

Ключ в этом случае - это norm, а не цветовая палитра.

Цветовая палитра определяет цвета для уже масштабированных данных. norm масштабирует данные до диапазона 0-1.

По умолчанию создается экземпляр Normalize, который масштабируется между минимальным и максимальным количеством данных или vmin и vmax kwargs, если они поставляются.

Однако есть несколько различных вспомогательных функций, которые могут быть полезны в вашем случае.

Если вам нужна дискретная цветовая полоса, есть вспомогательная функция для создания как norm, так и cmap для вас: matplotlib.colors.from_levels_and_colors Он принимает список значений и список цветов и возвращает BoundaryNorm экземпляр и экземпляр LinearSegmentedColormap:

Например:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
data1 = 3 * np.random.random((10, 10))
data2 = 5 * np.random.random((10, 10))
levels = [0, 1, 2, 3, 4, 5]
colors = ['red', 'brown', 'yellow', 'green', 'blue']
cmap, norm = matplotlib.colors.from_levels_and_colors(levels, colors)
fig, axes = plt.subplots(ncols=2)
for ax, dat in zip(axes, [data1, data2]):
 im = ax.imshow(dat, cmap=cmap, norm=norm, interpolation='none')
 fig.colorbar(im, ax=ax, orientation='horizontal')
plt.show()

Обратите внимание, что это создает дискретную цветовую палитру.

Если бы мы хотели использовать непрерывную colormap вместо этого, мы можем либо указать те же аргументы vmin и vmax, либо создать наш собственный экземпляр Normalize и передать его как аргумент norm для всех изображений.

Кроме того, существует аналогичная функция для создания непрерывной цветовой карты из списка цветов:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
data1 = 3 * np.random.random((10, 10))
data2 = 5 * np.random.random((10, 10))
colors = ['red', 'brown', 'yellow', 'green', 'blue']
cmap = LinearSegmentedColormap.from_list('name', colors)
norm = plt.Normalize(0, 5)
fig, axes = plt.subplots(ncols=2)
for ax, dat in zip(axes, [data1, data2]):
 im = ax.imshow(dat, cmap=cmap, norm=norm, interpolation='none')
 fig.colorbar(im, ax=ax, orientation='horizontal')
plt.show()

licensed under cc by-sa 3.0 with attribution.