選擇配色#

Seaborn 讓您輕鬆使用相當適合資料特徵和您的視覺化目標的顏色。此章節將說明指導您的選擇的基本原則,以及 seaborn 中協助您快速找出特定應用程式的最佳解決方案的工具。

繪圖中使用顏色的基本原則#

顏色的組成#

因為眼睛的工作方式,特定顏色可以用三個組成部分來定義。一般我們透過設定在顯示器中紅色、綠色和藍色通道的強度,於電腦中編寫顏色。但要分析色彩的可感知屬性,最好從色相飽和度明度通道來思考。

在非技術層面上,色相是區分「不同顏色」的組成部分。它是一種色彩的特性,讓人首先聯想到「紅色」和「藍色」等名稱。

飽和度(或稱色度)是色彩鮮豔程度。當兩個不同色相的顏色具有較高的飽和度時,看起來就會更為顯著。

明度對應於發射(或針對印刷顏色進行反射)的光量,範圍從黑色到白色。

變換色相來區分類別#

當你要在一個圖上繪製多個類別時,通常你應該改變元素的顏色。考慮這個簡單的例子:這兩個圖中哪一個比較容易計數三角形的個數?

../_images/color_palettes_9_0.png

在右邊這個圖中,橘色三角形「跳出來」,讓它很容易和圓形區分。這個跳出來的效果是由於我們的視覺系統優先處理顏色的差異。

藍色和橘色的顏色差異主要是取決於它们的色相。色相可以有效地表示類別:大多數人可以很容易區分中等的色相個數,而具有不同色相但相似亮度或強度的點顯得同等重要。它也讓圖表更容易討論。考慮這個範例

../_images/color_palettes_11_0.png

大多數人可以很快確定在左邊的圖中有五個不同的類別,並且如果被要求描述「藍色」的點,也可以做到。

在右邊的圖中,所有的點都是藍色的,但是明度和飽和度有所不同,就比較難以說明有多少個不同的類別。我們該如何討論一個特定的類別呢?「不太藍但也不是太不藍的點?」更甚的是,灰色的點似乎會隱沒在背景中,相較於更強烈的藍色點,它們的地位被貶低了。如果這些類別同樣重要,這是一個很差的表示方式。

因此,通用的原則是,使用色相變化來表示類別。上述是一些注意事項。如果你的圖中有很多顏色,可能會難以記住每種顏色的含意,除非類別和用來表示這些類別的顏色之間有既有的聯想。這會讓你的圖更難以解讀:觀看者必須不斷參考圖例才能理解所顯示的內容,而無法專注於資料。因此,你應該努力不要讓圖表過於複雜。而且要注意,並非每個人都用相同的方式看見顏色。同時改變形狀(或其他屬性)和顏色有助於患有異常色覺的人了解你的圖表,如果列印成黑白,也可以讓這些圖表(在某種程度上)保持可解讀性。

變換明度來表示數字#

另一方面,色相變化並不適合表示數字化資料。考慮此範例,在這個範例中,我們需要顏色來表示雙變異數直方圖中的數量。在左邊,我們使用一個環狀的配色範例,其中每個區塊中觀測值的漸進變化對應於色相的漸進變化。在右邊,我們使用一個配色範例,其中較亮顏色用來表示數量較多的區塊

../_images/color_palettes_14_0.png

使用基於色調的色板時,很難確定雙變數分佈的形狀。相比之下,亮度色板則使人更容易明確看出有兩個主要的峰值。

亮度的變化有助您看出資料中的結構,而亮度變化通常被直觀地視為重要性變化的表現。但右邊的圖形並未使用灰階顏色圖。它的色彩繽紛讓它更有趣味,而細微的色調變化也增加了兩個數值間的感知距離。因此,較小的差異將更容易釐清。

這些範例顯示,選擇顏色色板的考量不只是美學:所選的顏色如果使用得當,能顯示資料中的模式;若使用不當,則會隱藏這些模式。並沒有一定的最佳色板,但在某些特定的資料集和視覺化方法中,有些色板會比較好或比較差。

美學確實很重要:人們越想看你的圖形,就越有可能從中學到東西。即使你製作的圖形只是為了自己用也一樣。在探索性資料分析中,你可能會產生許多類似的圖形。變更顏色色板會增加新奇感,讓你保持專注,準備好找出資料中有趣的特性。

那麼,你該如何選擇既能很好地呈現資料、又看起來很吸引人的顏色色板?

選擇顏色板的工具#

用於處理顏色色板最重要的函式是適切的 color_palette()。此函式提供介面,讓使用者能夠在 seaborn 中以大部分可能的方法產生顏色色板。而任何有 palette 參數的函式都會在內部使用它。

傳給 color_palette() 的主要參數通常是字串:特定色板的名稱,或是類別名稱以及其他參數,用於選取特定的成員。後一種情況下,color_palette() 會委派給更特定的函式,例如 cubehelix_palette()。你也可以傳遞一列使用 matplotlib 接受的任何方式指定的顏色(RGB 編組、十六進位碼,或 X11 表中的名稱)。傳回值是一個物件,會將 RGB 編組清單包裝起來,並提供一些有用的方法,例如轉換為十六進位碼,以及豐富的 HTML 呈現。

呼叫 color_palette() 而沒有任何參數,就會傳回目前的預設色彩盤,matplotlib(以及大多數的 seaborn 函數)會在沒有指定其他色彩的情況下使用。這個預設色彩盤可以使用相對應的 set_palette() 函數來設定,這個函數會在內部呼叫 color_palette() 並且使用相同的參數。

為了說明 color_palette() 提供的各種不同選項的用途,先說明一下色彩盤的分類架構會很有幫助。廣義來說,色彩盤可以分成下列三種類型

  • 質性色彩盤,適合用來表示類別資料

  • 順序色彩盤,適合用來表示數值資料

  • 發散色彩盤,適合用來表示具備類別邊界的數值資料

質性色彩盤#

質性色彩盤非常適合用來表示類別資料,因為它們大多數的變化都在色調成分。seaborn 中的預設色彩盤是具備十種不同色調的質性色彩盤

sns.color_palette()

這些色彩的排序順序與matplotlib 的預設色彩盤相同,為 "tab10",但它們稍微不那麼強烈。比較一下

sns.color_palette("tab10")

事實上,seaborn 有六種 matplotlib 色彩盤的變化,稱為 deepmutedpastelbrightdark 以及 colorblind。這些色彩盤橫跨平均亮度和飽和度值的範圍

../_images/color_palettes_22_0.svg

許多人發現預設 "deep" 色彩盤的溫和色調具有美學上的吸引力,但它們也比較不顯眼。因此,在某些情況下,它們可能較難以辨別,在製作出版圖表時需要注意這一點。 此比較 可以協助估計 seaborn 色彩盤在模擬不同形式色盲時的表現。

使用環狀色彩系統#

當您有很多類別時,找出獨特色調的最佳方法是均勻地在圓形色彩空間繪製間距一致的顏色(在維持亮度和飽和度恆定的情況下變更色調)。這是當需要使用比目前預設的色彩週期中更多的色彩來繪圖時,所有 seaborn 函式的預設值。

最常見的方法是使用hls色彩空間,這是 RGB 值的簡單變形。我們曾在之前的範例中看到這個色彩配置,說明如何繪製直方圖

sns.color_palette("hls", 8)

由於人體視覺系統運作的關係,在 RGB 值方面具有相同明度和飽和度的顏色,不一定會看起來強度相等。若要改善這點,seaborn 提供husl系統(已改名為 HSLuv)的介面,當您在色環中旋轉時,能達成亮度變化的程度較低。

sns.color_palette("husl", 8)

當 seaborn 需要使用比目前預設可用的色彩還多的分類配置時,它將採用此方法。

使用分類 Color Brewer 配置#

另一個視覺上吸引人的分類配置來源是Color Brewer工具(它也提供順序和區間配置,下文將說明)。

sns.color_palette("Set2")

請注意,定性的 Color Brewer 配置長度不一,而color_palette()的預設動作是提供完整的清單

sns.color_palette("Paired")

順序色彩配置#

第二大類的色彩配置稱為「順序」。當資料範圍從相對較低或不有趣的數值到相對較高或有趣的數值(或相反情況)時,這種對應關係就很適用。如上述所見,順序配置中變化的主要維度為明度。當您對數字資料進行對應時,一些 seaborn 函式預設會採用順序色彩配置。(基於歷史原因,分類和數字對應關係都是使用hue參數指定,例如在relplot()displot()等函式中,即使數值對應關係使用的色彩配置的色調變化相對較小)。

知覺統一配置#

由於預期代表數值,因此最佳的順序調色盤會是感知均勻的,也就是說兩個顏色的相對可辨率會和對應資料值之間的差異成正比。Seaborn 包含四個感知均勻順序色圖:"rocket""mako""flare""crest"。前兩個有非常廣的明亮度範圍,且很適合熱圖等應用程式,其中顏色會填滿繪製的空間

sns.color_palette("rocket", as_cmap=True)
rocket color map
sns.color_palette("mako", as_cmap=True)
mako color map

由於這些色圖的極端值接近白色,因此不適合為線條或點等元素著色:要在白色或灰色背景中辨別重要的值會很困難。「flare」和「crest」色圖是此類繪圖的較佳選擇。它們的光度變化範圍較受限,但會略微增加色調變化以彌補此點。亮度範圍的預設方向也相反,因此較小的值會有較淺的顏色

sns.color_palette("flare", as_cmap=True)
flare color map
sns.color_palette("crest", as_cmap=True)
crest color map

也可以使用 Matplotlib 提供的感知均勻色圖,例如 "magma""viridis"

sns.color_palette("magma", as_cmap=True)
magma color map
sns.color_palette("viridis", as_cmap=True)
viridis color map

Matplotlib 約定,每個連續色圖都有反轉版本,其後綴為 "_r"

sns.color_palette("rocket_r", as_cmap=True)
rocket_r color map

離散 vs. 連續對應#

需要注意的一點是,Seaborn 可以從順序色圖產生離散值,且執行此操作時不會使用最極端的值。比較 "rocket" 的離散版本與上面顯示的連續版本

sns.color_palette("rocket")

在內部,Seaborn 使用離散版本表示類別資料,在數值對應模式中則使用連續版本。離散順序色圖可以適合視覺化有內在順序的類別資料,特別是有色調變化時。

順序「cubehelix」調色盤#

感知均勻色圖很難透過程式產生,因為它們不是基於 RGB 色彩空間。cubehelix 系統提供了一項基於 RGB 的折衷方案:它產生具備亮度線性增加或減少以及一些持續色調變化的順序調色盤。雖然並非完全感知均勻,但產生的色圖有許多良好的特性。重要的是,設計程式的許多面向都可設定參數。

Matplotlib 內建有預設的 cubehelix 版本

sns.color_palette("cubehelix", as_cmap=True)
cubehelix color map

seaborn cubehelix_palette() 函數所傳回的預設調色盤與 matplotlib 預設內容略有不同,在於它不會像 matplotlib 那樣,在色相環上旋轉得那麼遠,且所涵蓋的強度範圍也沒有那麼廣。它也會反轉明度斜坡

sns.cubehelix_palette(as_cmap=True)
seaborn_cubehelix color map

其他 cubehelix_palette() 參數則會控制調色盤的看起來。您要變更的兩個主要內容為 start(0 至 3 之間的值)與 rot,也就是旋轉次數(任意值,但通常介於 -1 至 1 之間)

sns.cubehelix_palette(start=.5, rot=-.5, as_cmap=True)
seaborn_cubehelix color map

旋轉得越多,您將看到越多的色相變化

sns.cubehelix_palette(start=.5, rot=-.75, as_cmap=True)
seaborn_cubehelix color map

您可以控制端點的明暗程度以及順序

sns.cubehelix_palette(start=2, rot=0, dark=0, light=.95, reverse=True, as_cmap=True)
seaborn_cubehelix color map

color_palette() 會接受一個字串代碼,開頭為 "ch:",以產生任意 cubehelix 調色盤。您可以在字串中傳遞參數名稱

sns.color_palette("ch:start=.2,rot=-.3", as_cmap=True)
seaborn_cubehelix color map

而為了精簡起見,每個參數都可以用其第一個字母指定

sns.color_palette("ch:s=-.2,r=.6", as_cmap=True)
seaborn_cubehelix color map

自訂順序調色盤#

對於一個自訂順序調色盤較為簡化的介面,您可以使用 light_palette()dark_palette(),它們都會從單一顏色開始,並產生調色盤,從淺色或深色飽和度低的值漸變到那個顏色

sns.light_palette("seagreen", as_cmap=True)
blend color map
sns.dark_palette("#69d", reverse=True, as_cmap=True)
blend color map

與 cubehelix 調色盤一樣,您也可以透過 color_palette() 或任何接受 palette 的地方,指定淺色或深色調色盤

sns.color_palette("light:b", as_cmap=True)
blend color map

透過加入 "_r" 將顏色圖反轉

sns.color_palette("dark:salmon_r", as_cmap=True)
blend color map

順序 Color Brewer 調色盤#

Color Brewer 函式庫也有一些順序調色盤的優良選項。它們包含具有單一主要色相的調色盤

sns.color_palette("Blues", as_cmap=True)
Blues color map

同時具有多色相選項

sns.color_palette("YlOrBr", as_cmap=True)
YlOrBr color map

發散色板#

第三類色板稱為「發散」,用於資料中高低值皆有意義,且橫跨中點值(通常為 0)應降低重要性的情況。選擇良好發散色板的規則與選擇良好連續色板的規則類似,但現在色圖中應有兩個主色調,一個在(或接近)每個極點。初始值具有類似的亮度和飽和度也很重要。

感知均勻發散色板#

Seaborn 內含兩個感知均勻發散色板:"vlag""icefire"。它們在極點上都使用藍色和紅色,許多人直覺將它們視為「冷」和「熱」

sns.color_palette("vlag", as_cmap=True)
vlag color map
sns.color_palette("icefire", as_cmap=True)
icefire color map

自訂發散色板#

也可以使用 Seaborn 函數 diverging_palette() 為發散資料建立自訂色圖。此函數使用 husl 色彩系統建立發散色板。傳遞給它的兩個色相(以角度為單位),並選擇性地傳遞極端的明亮度和飽和度值。使用 husl 代表極端值,以及達中點的坡道雖然不會十分感知均勻,但會非常平衡

sns.diverging_palette(220, 20, as_cmap=True)
blend color map

當想要避開無聊的冷暖色調時,這會很方便

sns.diverging_palette(145, 300, s=60, as_cmap=True)
blend color map

也可以建立中點較暗而非較亮的色板

sns.diverging_palette(250, 30, l=65, center="dark", as_cmap=True)
blend color map

這裡強調,使用紅色和綠色雖然直覺,但應加以避免

其他發散色板#

Matplotlib 內建其他一些不錯的發散色板,包含 Color Brewer 色板

sns.color_palette("Spectral", as_cmap=True)
Spectral color map

還有 coolwarm 色板,中間值與極端值之間的對比較低

sns.color_palette("coolwarm", as_cmap=True)
coolwarm color map

可以看到,有許多運用色彩至視覺化的選項。Seaborn 嘗試同時使用良好的預設值與提供高度靈活性。

這項討論僅是開端,而且有許多好的資源可讓您深入了解如何使用顏色於視覺化的技術。此處提供一個很棒的範例,是 一系列的部落格文章,出自 NASA Earth Observatory。matplotlib 文件中還有一個 實用教學,其中說明了其顏色圖的一些感知屬性。