Matplotlib 的色版:自定義您的顏色方案

數據視覺化是數據分析師和數據科學家表示複雜信息並產生有意義洞見的最好方法(如果不是最好的話)。為了充分利用您與利益相關者溝通的機會,我匯總了有關Matplotlib色板的有用信息。

正如你將在本篇文章中看到的,Matplotlib是Python中一個極具多樣性和可擴展性的視覺化庫。它提供了從簡單圖表到完全互動視覺的各式選項。如果你對Python不夠熟悉,我建議你在我們開始之前報名我們的Python入門課程來了解其基礎。個人來說,我也會將Python捷徑表放在手邊,因為它對常見函數來說是一個有用的參考。

選擇正確的Matplotlib色板

首先需要考量的就是決定使用序列、分歧還是分類色彩映射。選擇色彩映射時還應考慮的其他重要因素包括感知一致性,意思是數據值之間的等差被感知為顏色之間的等差,以及使用對色弱友好色彩映射選項,讓您的視覺效果對所有觀眾都容易理解。

選擇色彩映射時,您還應考慮不同的領域標準。例如,在海洋學研究中,不同深淺的藍色代表不同的水深。如果您對視覺化所需的正確色彩映射不確定,有許多不同的工具和資源可以提供指導。特別是,我們自己的數據視覺化與Matplotlib入門課程能夠幫助您應對許多情況。

Matplotlib中的不同色彩映射

在Python中,matplotlib.colormaps模塊提供了對內置色彩映射的訪問,這有助於您為項目選擇最合適的方案。以下是最常見的選項類別:

序列色彩映射

序列化色板代表有序數據,從低到高值進行排列。它們從淺色到深色漸變,顯示不同級別數據的大小。序列化色板的一個例子是在熱力圖中用於溫度數據,其中淺色代表較冷的溫度,深色則代表較高的溫度。

假設你有一個包含日期和溫度列的數據集。以下代碼將為溫度創建一個熱力圖。

# 引入所需的庫 import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.colors as mcolors # 步驟 1:從日期列中提取月份和日期信息 calendar_data = temperature_data.copy() # 創建一份副本以供操作 calendar_data['Month'] = calendar_data['Date'].dt.strftime('%B') calendar_data['Day'] = calendar_data['Date'].dt.day # 步驟 2:定義自然日歷序列的月份順序 month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # 將 'Month' 列轉換為指定順序的類別類型 calendar_data['Month'] = pd.Categorical(calendar_data['Month'], categories=month_names, ordered=True) # 步驟 3:重新整併數據以創建熱力圖的結構化表 monthly_temperature_table = calendar_data.pivot(index='Month', columns='Day', values='Temperature') # 步驟 4:設置熱力圖的繪圖 plt.figure(figsize=(12, 8)) # 定義溫度範圍的自定義規範化(可選) norm = mcolors.Normalize(vmin=15, vmax=35) # 使用順序色彩映射創建熱力圖 heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) # 添加色彩棒以表示溫度 colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) # 标籤坐标轴 plt.xlabel('Day of the Month') plt.ylabel('Month') # 將 y 軸刻度標籤设置为显示月份名称而不是数字 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # 為熱力圖添加標題 plt.title('Monthly Temperature Heatmap (Sequential Colormap)') # 顯示圖表 plt.grid(False) plt.show()

Matplotlib 順序色彩映射視覺化範例。作者圖片

分歧色彩映射

分歧型色版能夠凸顯與中心值兩個方向上的數據偏差。分歧型色版在正負方向上有對比的顏色。分歧型色版的一個常見應用是在金融數據中,用以表示盈利與虧損。

# 將 'Month' 設為索引 profit_loss_df.set_index('Month', inplace=True) # 設定圖形大小 plt.figure(figsize=(8, 4)) # 創建分歧型色版 cmap = plt.cm.RdYlGn # 使用 imshow 顯示數據為熱圖 im = plt.imshow(profit_loss_df.T, cmap=cmap, aspect='auto', vmin=-np.max(np.abs(profit_loss_data)), vmax=np.max(np.abs(profit_loss_data))) # 添加顏色條並標籤 cbar = plt.colorbar(im) cbar.set_label('Profit/Loss ($)') # 為每個單元格添加註釋 for i, month in enumerate(profit_loss_df.index): plt.text(i, 0, f'{profit_loss_df.loc[month, "Profit/Loss"]:.2f}', ha='center', va='center', color='black') # 設定 x 軸和 y 軸標籤和刻度 plt.xlabel('Month') plt.ylabel('') # y 軸不需要標籤,因為只有一行 plt.xticks(ticks=range(len(profit_loss_df.index)), labels=profit_loss_df.index, rotation=45) plt.yticks([]) # 隱藏 y 軸刻度,因為我們只有一行 # 添加標題 plt.title('Profit/Loss Heatmap (Diverging Colormap)') # 調整佈局以更好地顯示 plt.tight_layout() # 顯示圖表 plt.show()

Matplotlib 分歧型色版視覺化範例。作者圖像。

循環色調圖

循環色調圖對於視覺化表示重複或循環模式的數據非常有用,例如角度、波相位或一天中的時間。循環色調圖的一個應用實例是視覺化週期函數的相位,如正弦波。

# 創建正弦波數據 x = np.linspace(0, 2 * np.pi, 100) # 從0到2π的X值(一個完整的週期) y = np.sin(x) # Y值(X的正弦) # 創建一個圖形和坐標軸 plt.figure(figsize=(10, 6)) # 使用循環色調圖創建散點圖 # 根據正弦波週期中的位置為點著色 points = plt.scatter(x, y, c=x, cmap='twilight', edgecolor='black') # 添加顏色條以顯示波的相位 cbar = plt.colorbar(points) cbar.set_label('Wave Phase (Radians)', rotation=270, labelpad=15) # 為坐標軸標籤 plt.xlabel('Angle (Radians)') plt.ylabel('Sine Value') # 添加標題 plt.title('Sine Wave with Cyclic Colormap (Twilight)') # 顯示圖表 plt.grid(True) plt.show()

Matplotlib循環色調圖視覺化範例。作者圖像。

定性色調圖

質性色彩映射最適合表示沒有特定順序的類別數據。質性色彩映射的一個常見用例是餅圖,其中每個扇區代表一個不同的類別,可以輕鬆區分。

# 示例類別數據 categories = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E'] values = [20, 35, 25, 10, 10] # 設置圖形大小 plt.figure(figsize=(8, 8)) # 手動定義質性色彩映射 colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3'] # 手動選擇的色彩十六進制代碼 # 創建餅圖 plt.pie(values, labels=categories, autopct='%1.1f%%', startangle=90, colors=colors) # 等比例可以確保餅圖繪製成為圓形 plt.axis('equal') # 添加標題 plt.title('Pie Chart with Qualitative Colormap') # 顯示圖表 plt.show()

Matplotlib 質性色彩映射視覺化示例。圖片由作者提供。

彩虹色彩映射

彩虹色彩映射如hsv在需要廣泛色調範圍時使用。

生成循環數據 x = np.linspace(0, 2 * np.pi, 500) y = np.sin(x) 使用彩虹色調色板創建圖表 plt.scatter(x, y, c=x, cmap='hsv', s=50) 添加顏色條 plt.colorbar(label='Phase') 添加標籤和標題 plt.xlabel('Angle (radians)') plt.ylabel('Sine Value') plt.title('Cyclic Data Visualization using HSV Colormap') 顯示圖表 plt.show()

Matplotlib彩虹色調色板視覺化示例。圖片作者。

感知均勻的色調板

infernoplasma這樣的色調板在不同顯示媒介之間提供更好的可見性。

生成合成高程數據 x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) Z = np.sin(np.sqrt(X**2 + Y**2)) * 100 高程數據 使用'plasma'色調板繪製高程數據 plt.contourf(X, Y, Z, cmap='plasma') 添加顏色條 plt.colorbar(label='Elevation (m)') 添加標題和標籤 plt.title('Topographic Map (Plasma Colormap)') plt.xlabel('X Coordinate') plt.ylabel('Y Coordinate') 顯示圖表 plt.show()

Matplotlib 覺知一致色彩映射可视化範例。作者圖。

建立與修改 Matplotlib 色彩映射

雖然 Matplotlib 提供了多種內建的色彩映射,但有些情況下您可能會想要自定色彩。在 Matplotlib 中建立自定色彩映射的主要工具是 ListedColormapLinearSegmentedColormap

使用 ListedColormap 建立自定色彩映射

ListedColormap 讓您可以從特定顏色列表中建立色彩映射。這種方法在為分類數據中的不同類別分配特定顏色時非常有用。

from matplotlib.colors import ListedColormap # 分類數據 categories = ['Category A', 'Category B', 'Category C', 'Category D'] values = [25, 40, 35, 30] # 自定義顏色列表用於色图(例如,藍色、綠色、紅色和紫色的深淺變化) custom_colors = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd'] # 使用自定義顏色創建ListedColormap custom_cmap = ListedColormap(custom_colors) # 設置圖形大小 plt.figure(figsize=(8, 6)) # 使用自定義色图創建條形圖 bars = plt.bar(categories, values, color=custom_cmap.colors) # 添加標題 plt.title('Bar Chart with Custom ListedColormap') # 标記坐标轴 plt.xlabel('Categories') plt.ylabel('Values') # 顯示圖表 plt.show()

Matplotlib 自定義色图與ListedColormap。作者影像。

使用LinearSegmentedColormap創建自定義色图

LinearSegmentedColormap 允許您創建在顏色之間平滑過渡的色图。這個知識很有價值,因為連續數據通常需要漸變的顏色變化。在這裡,我還指定了我希望為視覺效果设置的間隔數量。

from matplotlib.colors import LinearSegmentedColormap 建立二維高斯函數的值網格 x = np.linspace(-2, 2, 500) y = np.linspace(-2, 2, 500) X, Y = np.meshgrid(x, y) Z = np.exp(- (X**2 + Y**2)) 定義從藍色到白色再到紅色過渡的自定義色板 colors = ['blue', 'white', 'red'] custom_cmap = LinearSegmentedColormap.from_list('blue_white_red', colors) 調整顏色類別數量(離散等級) 指定等級數量(例如,10表示10個不同的顏色帶) num_classes = 10 levels = np.linspace(Z.min(), Z.max(), num_classes) 設定圖形尺寸 plt.figure(figsize=(8, 6)) 使用調整後的色板繪製二維高斯函數 contour = plt.contourf(X, Y, Z, levels=levels, cmap=custom_cmap) 添加顏色條以顯示離散的顏色類別 plt.colorbar(contour, label='Gaussian Function Value') 為坐標軸添加標籤 plt.xlabel('X') plt.ylabel('Y') 添加標題 plt.title(f'2D Gaussian with {num_classes} Discrete Color Classes') 顯示圖表 plt.show()

Matplotlib 自定義調整顏色類別數量。圖片由作者提供。

自定義顏色範圍和強度

您可以透過操纵横截面或切割現有色彩映射來控制顏色強度或範圍。在以下示例中,顏色範圍被切割以顯示介於16至40度攝氏溫度。

# 設置熱力圖的繪圖 plt.figure(figsize=(12, 8)) # 為溫度範圍定義自定義規範化 norm = mcolors.Normalize(vmin=16, vmax=40) # 使用連續色彩映射創建熱力圖 heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) # 添加顏色條以表示溫度 colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) # 為軸添加標籤 plt.xlabel('Day of the Month') plt.ylabel('Month') # 設置y軸刻度以顯示月份名稱而非數字 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # 為熱力圖添加標題 plt.title('Monthly Temperature Heatmap (Sequential Colormap)') # 顯示繪圖 plt.grid(False) plt.show()

Matplotlib 自定義顏色範圍和強度。作者圖像。

組合現有的色彩映射

您也可以通過混合多個色版來組合現有的色版,以創建更複雜的可視化。

from matplotlib.colors import LinearSegmentedColormap, Normalize # 創建合成高程數據 x = np.linspace(-180, 180, 500) # 經度 y = np.linspace(-90, 90, 250) # 緯度 X, Y = np.meshgrid(x, y) Z = 5000 * np.sin(np.sqrt(X**2 + Y**2) * np.pi / 180) # 合成高程數據 # 定義基礎色版 ('viridis' 和 'cividis') cmap1 = plt.get_cmap('viridis') cmap2 = plt.get_cmap('cividis') # 通過混合兩個基礎色版來創建自定義色版 def blend_colormaps(cmap1, cmap2, blend_ratio=0.5): """Blend two colormaps together.""" c1 = cmap1(np.linspace(0, 1, 256)) c2 = cmap2(np.linspace(0, 1, 256)) blended_colors = (1 - blend_ratio) * c1 + blend_ratio * c2 return LinearSegmentedColormap.from_list('blended_cmap', blended_colors) # 創建混合色版 custom_cmap = blend_colormaps(cmap1, cmap2, blend_ratio=0.5) # 為可視化正規化數據 norm = Normalize(vmin=-5000, vmax=5000) # 設置圖形大小 plt.figure(figsize=(12, 6)) # 使用混合色版繪製合成高程數據 contour = plt.contourf(X, Y, Z, levels=100, cmap=custom_cmap, norm=norm) # 添加顏色條以顯示混合色彩映射 plt.colorbar(contour, label='Elevation (meters)') # 為坐標軸添加標籤 plt.xlabel('Longitude') plt.ylabel('Latitude') # 添加標題 plt.title('Geographical Elevation Data with Blended Colormap (Viridis + Cividis)') # 顯示圖表 plt.show()

Matplotlib 結合現有色彩映射。作者圖像。

使用 _r 後綴反轉色彩映射

您可以通过在 Matplotlib 中的色彩映射名稱後添加後綴 _r 來反轉任何色彩映射。

# 設置熱圖的繪圖 plt.figure(figsize=(12, 8)) # 為色彩範圍創建自定義規範化 norm = mcolors.Normalize(vmin=16, vmax=40) # 使用 imshow 和順序色彩映射繪製熱圖 im = plt.imshow(monthly_temperature_table, cmap='YlOrRd_r', norm=norm, aspect='equal') # 添加一個水平方向的顏色條 cbar = plt.colorbar(im, orientation='horizontal', pad=0.1) cbar.set_label('Temperature (°C)', labelpad=10) # 為軸添加標籤 plt.xlabel('Day of the Month') plt.ylabel('Month') # 設置 y 軸刻度以顯示月份名稱而不是數字 plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # 添加標題 plt.title('Temperature Heatmap (Sequential Colormap)') # 顯示繪圖 plt.show()

Matplotlib 使用 _r 後綴反轉色彩映射。作者圖像。

處理 Matplotlib 色彩映射中的常見錯誤

在使用 Matplotlib 的色图(colormaps)時,可能會遇到影響您工作流程的錯誤。以下是一些常見的錯誤以及如何排除它們。

AttributeError: module ‘matplotlib’ has no attribute ‘colormaps’

這個錯誤發生在您使用 Matplotlib 版本早於 3.4.0 來訪問 matplotlib.colormaps 時。色圖屬性是在 Matplotlib 3.4.0 中引入的。首先,使用以下代碼來檢查您的 Matplotlib 版本,以排除這個錯誤。

import matplotlib print(matplotlib.__version__)

使用以下 pip 指令進行升級。

pip install --upgrade matplotlib

如果您在升級 Matplotlib 版本時遇到問題,嘗試以下方法來訪問色圖。

plt.get_cmap('viridis') # 取代 matplotlib.colormaps['viridis']

不正確的色彩分配

您可能在传递超出预期范围值或颜色映射使用不当时遇到不正确的颜色分配。如果颜色映射本应用于连续数据却应用于分类数据,或者反之,也可能引起不正确的颜色分配。

为确保您的数据在预期范围内,始终使用vmaxvmin参数对数据进行归一化或缩放。

import matplotlib.colors as mcolors # 创建一个示例温度数据集 data = np.random.rand(10, 10) * 100 # 调整范围以匹配您的数据 # 创建一个颜色归一化实例以将数据缩放到颜色映射的范围 norm = mcolors.Normalize(vmin=0, vmax=100) # 使用'viridis'颜色映射和指定的归一化创建热图 plt.imshow(data, cmap='viridis', norm=norm, interpolation='nearest') plt.colorbar() plt.show()

为了更精细的控制,您可以在绘图函数中显式定义颜色边界,使用boundariesnorm参数。

视觉伪影和意外的结果

當處理離散或低解析度的數據時,你可能會經驗到意外的色帶、過多的對比或色彩滲漏。當你的數據範圍有限但使用連續色調圖顯示時,就會出現這個問題。

為了解決這個問題,使用更多的數據點或調整顏色等級數量以平滑過渡。

# 在色調圖中增加箱數 cmap = plt.get_cmap('viridis', 256) plt.imshow(data, cmap=cmap)

你可以將色調圖分為固定的等級來適當地處理離散數據。

cmap = plt.get_cmap('inferno', 10) # 將色調圖分為10個離散等級 plt.imshow(data, cmap=cmap)

你也可以檢查顯示設定並調整解析度,特別是在保存視覺化時,以避免低解析度的圖表。

plt.savefig('plot.png', dpi=300) # 以較高解析度保存圖形

由於剪裁造成的色彩失真

當數據包含超出預期顏色範圍的極端值時,會發生顏色失真。這會導致數據的部分被剪切並指定為色調映射中的最小或最大顏色。

為了避免顏色失真,請使用vminvmax調整顏色限制以符合您的數據範圍,防止剪切。

plt.imshow(data, cmap='plasma', vmin=0, vmax=100)

您還應該使用健壯縮放來處理離群值,通過設置排除極端值的自定義限制。

import numpy as np robust_vmin, robust_vmax = np.percentile(data, [2, 98]) # 使用百分位數來移除極端離群值 plt.imshow(data, cmap='inferno', vmin=robust_vmin, vmax=robust_vmax)

3D繪圖中色調映射顯示不正確

如果3D表面上的數據映射存在問題,色調映射可能在3D視覺化中無法正確顯示。為了解決這個問題,請確保z軸數據被規範化以適合色調映射的預期範圍。此外,使用適當的色調映射限制以捕獲z值的全部範圍。

from mpl_toolkits.mplot3d import Axes3D 為3D表面繪圖生成樣本數據 X, Y = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) Z = np.sin(np.sqrt(X**2 + Y**2)) 創建一個3D坐標軸對象 ax = plt.axes(projection='3d') 使用'viridis'色彩映射來繪製表面,並調整顏色範圍 ax.plot_surface(X, Y, Z, cmap='viridis', vmin=np.min(Z), vmax=np.max(Z)) plt.show()

結論

選擇正確的色彩映射是一個非常重要的步驟,因為它實際上會影響用戶如何看待和理解你的數據。在我看來,花很多時間在數據分析上,而在最後一步——也就是你傳達發現的部分——馬虎對待,是一個很大的錯誤。

幸運的是,Matplotlib提供了許多選項,確保你的視覺呈現能夠講述一個引人入勝的故事。報名我們的課程,Matplotlib數據視覺化入門,成為專家。此外,如果你是一個同時使用Python和Seaborn進行視覺化的用戶(同時掌握兩者非常好),請閱讀我們的Seaborn選擇顏色快速指南,然後跟隨我們的Seaborn數據視覺化入門課程。

Source:
https://www.datacamp.com/tutorial/matplotlib-colormaps