Почему структура цветовых карт 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 есть два типа цветовых карт
ListedColormap
sLinearSegmentedColormap
s
ListedColormap
s - это в основном список цветов. Вы получаете количество цветов черезcmap.N
а сами цвета вы получаете через cmap.colors
.
LinearSegmentedColormap
s определяются интерполяцией. Они хранят некоторые точки выборки в словаре и могут интерполировать между ними, в зависимости от количества необходимых цветов. Текущее количество цветов также доступно черезcmap.N
.
Разве все карты не должны быть одинаковыми по своей структуре?
Думаю, им стоит. По крайней мереLinearSegmentedColormap
s должен обнажить .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 карты.