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

Я использую следующий скрипт для построения графика:

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


person DonkeyKong    schedule 24.09.2015    source источник


Ответы (1)


Ключом в данном случае является norm, а не цветовая карта.

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

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

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

Если вам нужна дискретная цветовая полоса, есть вспомогательная функция, которая генерирует для вас как 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()

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

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

Если вместо этого мы хотим использовать непрерывную карту цветов, мы можем либо указать одни и те же аргументы 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()

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

person Joe Kington    schedule 24.09.2015