Почему структура цветовых карт Matplotlib отличается?

Я могу построить RGB-компоненты некоторых цветовых карт Matplotlib с помощью этого простого скрипта Python:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap

mapa = cm.get_cmap('viridis', 256)

R = []; G = []; B = []

ind = np.linspace(1,256,256)

for item in mapa.colors:
    R.append(item[0])
    G.append(item[1])
    B.append(item[2])

plt.figure(1,figsize=(8,8))

plt.plot(ind,R,'r-')
plt.plot(ind,G,'g-')
plt.plot(ind,B,'b-')

plt.xlabel('$Colour \\ index$', fontsize=16, fontname="Times")
plt.ylabel('$RGB \\ component \\ weight$', fontsize=16, fontname="Times")

plt.show()

Некоторые, но не все. Он работает нормально с viridis, но не с пресловутыми цветными картами "jet", "prism" или "summer". Это происходит потому, что (кажется) эти карты не имеют атрибута 'colors':

runfile('F:/Documents/Programs/Python/Colourmap_Plot.py', wdir='F: / Documents / Programs / Python') Трассировка (последний вызов последним):

Файл "F:\Documents\Programs\Python\Colourmap_Plot.py", строка 37, для элемента в mapa.colors:

AttributeError: объект 'LinearSegmentedColormap' не имеет атрибута 'colors'

Интересно, почему это происходит. Разве все карты не должны быть одинаковыми по своей структуре? Как я могу отличить карты с атрибутом "цвета" от тех, у которых его нет? И, наконец, как построить компоненты одной из этих "несоответствующих" карт?

Спасибо.

1 ответ

Решение

В matplotlib есть два типа цветовых карт

  • ListedColormaps
  • LinearSegmentedColormaps

ListedColormaps - это в основном список цветов. Вы получаете количество цветов черезcmap.N а сами цвета вы получаете через cmap.colors.

LinearSegmentedColormaps определяются интерполяцией. Они хранят некоторые точки выборки в словаре и могут интерполировать между ними, в зависимости от количества необходимых цветов. Текущее количество цветов также доступно черезcmap.N.

Разве все карты не должны быть одинаковыми по своей структуре?

Думаю, им стоит. По крайней мереLinearSegmentedColormaps должен обнажить .colors атрибут тоже.

Как я могу отличить карты с атрибутом "цвета" от тех, у которых его нет?

Вы можете ввести или сравнить экземпляры.

if isinstance(cmap, matplotlib.colors.LinearSegmentedColormap):
    # do something
    print("Is a segmented map")
elif isinstance(cmap, matplotlib.colors.ListedColormap):
    # do something else
    print("Is a listed map")

Вы также можете проверить, существует ли атрибут,

if hasattr(cmap, "colors"):
    print("Is a listed map")
else:
    print("Is either not a colormap, or is a segmented one.")

И наконец, как построить компоненты одной из этих "несоответствующих" карт?

Возможный вариант получить цвета из палитры, независимо от их типа, - это вызвать палитру со списком / массивом целых чисел, эффективно индексируя все цвета доcmap.N:

colors = cmap(np.arange(0,cmap.N)) 

colors сейчас N by 4 фигурный массив цветов RGBA карты.

Другие вопросы по тегам