HOWTO · Matplotlib
使用 Python Matplotlib 自定義顏色圖
本文討論了我們如何在 Python 中使用 Matplotlib 建立自定義顏色圖。它將展示兩種使用 ListedColormap 類和 LinearSegmentedColormap 類在 Python 中使用 Matplotlib 建立自定義顏色圖的方法。
本頁內容
每個類別都需要明確區分顏色時,請使用 ListedColormap;值需要呈現漸層變化時,請使用 LinearSegmentedColormap。兩者都是 Matplotlib 顏色圖類別,可透過 cmap 引數傳入繪圖函式。本指南也會示範如何檢視內建顏色圖並取得其 RGBA 值。
在 Python 中使用 Matplotlib 建立自訂顏色圖
顏色圖會將數值對應至顏色。若要表示類別代碼或少量固定顏色,請定義 ListedColormap;若測量值的顏色需要平順混合,則請定義 LinearSegmentedColormap。套用任一顏色圖時,請使用符合待著色數值範圍的正規化設定,否則圖中顯示的顏色可能無法正確反映預期的資料範圍。
在 Python 中使用 Matplotlib 的 get_cmap() 函式存取顏色圖及其值
get_cmap() 函式可取得指定名稱的內建顏色圖。顏色圖可呼叫:傳入 0 到 1 之間的值,即可取得 RGBA 元組,最後一個分量代表不透明度。若要檢視取樣後的顏色,則可改為傳入一組數值。以下範例會印出一個取樣顏色:
import matplotlib.pyplot as plt
viridis = plt.get_cmap("viridis")
print(viridis(0.56))
(np.float64(0.120081), np.float64(0.622161), np.float64(0.534946), np.float64(1.0))
若要建立有限大小的查找表,可使用 viridis.resampled(8) 重新取樣顏色圖。ListedColormap 會透過 colors 提供其項目;LinearSegmentedColormap 等連續顏色圖則可藉由傳入數值並呼叫它來取樣。
在 Python 中使用 ListedColormap 的 colors 屬性建立自訂離散顏色圖
ListedColormap 可接受顏色名稱或數值 RGBA 項目。RGBA 各通道的值通常介於 0 到 1。當顏色圖以清單表示時,colors 屬性會包含其中的離散項目。以下獨立範例會建立這兩種形式,並將顏色名稱顏色圖套用至散佈圖中的類別代碼。請依照資料調整 categories 和正規化設定。
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, Normalize
named_map = ListedColormap(["darkorange", "gold", "lightseagreen"], name="groups")
rgba_map = ListedColormap([
(0.58, 0.41, 0.27, 1.0),
(0.00, 0.41, 0.27, 1.0),
(0.58, 0.00, 0.27, 1.0),
], name="rgba_groups")
x = [1, 2, 3, 4, 5, 6]
y = [1, 4, 2, 5, 3, 6]
categories = [0, 0, 1, 1, 2, 2]
plt.scatter(x, y, c=categories, cmap=named_map, norm=Normalize(0, 2))
plt.colorbar(ticks=[0, 1, 2])
plt.show()
Normalize(0, 2) 會將類別代碼對應至三個顏色項目,色彩列上的刻度則標示這些代碼。使用 rgba_map.colors 可檢視明確指定的 RGBA 清單。如果顏色數量與類別代碼不一致,請調整顏色圖或正規化設定,確保各類別依預期取得對應顏色。
如何在 Python 中建立自訂線性分段顏色圖?
LinearSegmentedColormap 會在指定位置之間插補顏色通道,以建立漸層。其 cdict(顏色字典)包含 red、green 和 blue 等通道索引鍵。各通道的資料列格式為 [x, yleft, yright]:x 是介於 0 到 1 的位置,其他值則分別表示該位置左右兩側的通道值。位置必須從 0 到 1 遞增。錨點左右兩側的值相等時,顏色會連續變化;值不同則表示顏色會跳變。
以下獨立範例會建立一個錨點漸層,以及另一個使用 from_list() 建立的漸層,並將兩者套用至範例資料中顯示。圖中的「Anchors」和「Color list」是保留的英文標題:「Anchors」標示錨點漸層,「Color list」標示以顏色清單建立的漸層。這些圖形尚未經過目視檢查。
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
cdict = {
"red": [(0.0, 0.0, 0.0), (0.5, 0.1, 0.1), (1.0, 1.0, 1.0)],
"green": [(0.0, 0.0, 0.0), (0.5, 0.8, 0.8), (1.0, 0.2, 0.2)],
"blue": [(0.0, 0.4, 0.4), (0.5, 0.1, 0.1), (1.0, 0.0, 0.0)],
}
anchor_map = LinearSegmentedColormap("anchor_gradient", cdict, N=256)
list_map = LinearSegmentedColormap.from_list(
"list_gradient", ["navy", "gold", "crimson"], N=256
)
values = np.arange(36).reshape(6, 6)
fig, axes = plt.subplots(1, 2)
for ax, cmap, title in zip(axes, [anchor_map, list_map], ["Anchors", "Color list"]):
image = ax.imshow(values, cmap=cmap)
ax.set_title(title)
fig.colorbar(image, ax=ax)
plt.tight_layout()
plt.show()
需要控制通道值或明確指定錨點時,請使用字典建構式。若要以命名顏色建立簡單的漸層,可使用 LinearSegmentedColormap.from_list();顏色會在整個顏色圖中插補。N 設定查找表的大小,gamma 則控制輸入位置的縮放。
結論
若要為離散類別指定特定顏色,請選擇 ListedColormap。若需要連續漸層,請選擇 LinearSegmentedColormap,並使用 cdict 錨點或 from_list() 顏色清單建立。使用 get_cmap() 取得內建顏色圖、檢視取樣後的 RGBA 值,再搭配適當的正規化設定將選定的顏色圖傳入繪圖函式。