|
標(biāo)簽: python 數(shù)據(jù)可視化 可視化 數(shù)據(jù)分析 大數(shù)據(jù) 一圖勝千言,使用Python的matplotlib庫,可以快速創(chuàng)建高質(zhì)量的圖形。 我們團(tuán)隊推出一個新的系列教程:Python數(shù)據(jù)可視化,針對初級和中級用戶,將理論和示例代碼相結(jié)合,分別使用matplotlib, seaborn, plotly等工具實現(xiàn)可視化。 本文主題是如何在Matplotlib中使用自定義顏色和colormap。 import osimport requestsimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport matplotlib as mpl%matplotlib inline
plt.style.use("ggplot")12345678910111. 自定義顏色Matplotlib繪圖接口通常包含’color’參數(shù),用于指定顏色,參數(shù)接受的數(shù)據(jù)格式包括:
對Python開發(fā)人員而言,前兩種方式應(yīng)該是最常用的。 查看Matplotlib支持的全部顏色名稱:查閱官方文檔。 看一個簡單的例子,分別創(chuàng)建曲線圖,柱狀圖,散點圖,通過參數(shù)’color’指定顏色。 fig, ax = plt.subplots(nrows=3, ncols=2, figsize=(12, 12))ax = ax.flatten()# 曲線圖x = np.linspace(0, 10, 50)y = np.sin(x)ax[0].plot(x, y)ax[0].set_title("Line plot: Default color")ax[1].plot(x, y, color="blue")ax[1].set_title("Line plot: Custom color")# 柱狀圖x = ["a", "b", "c", "d", "e", "f"]y = [1.2, 0.8, 2.5, 0.95, 1.35, 1.58]ax[2].bar(x, y)ax[2].set_title("Bar plot: Default color")ax[3].bar(x, y, color="purple")ax[3].set_title("Bar plot: Custom color")# 散點圖x = np.linspace(0, 3, 50)y = 10 + 2.5 * x + np.random.uniform(2, 10, 50)ax[4].scatter(x, y)ax[4].set_title("Scatter plot: Default color")ax[5].scatter(x, y, c="black")ax[5].set_title("Scatter plot: Custom color")1234567891011121314151617181920212223242526
'color’既可以設(shè)置統(tǒng)一的顏色,也可以單獨設(shè)置每個元素(每條曲線/每根柱子/每個點)的顏色,這時候需要提供一個表示顏色的數(shù)組。 # 以柱狀圖為例x = ["a", "b", "c", "d", "e", "f"]y = [1.2, 0.8, 2.5, 0.95, 1.35, 1.58]# 表示顏色的數(shù)組,這里用字符串表示顏色,也可以使用其它數(shù)據(jù)格式,如RGB或RGBA元組colors = ["red", "blue", "yellow", "gray", "green", "purple"]fig, ax = plt.subplots(figsize=(10, 7))ax.bar(x, y, color=colors)ax.set_title("Different colors for each bar")12345678910
有時候需要按照某個邏輯條件使用不同的顏色。例如一幅表示不同資產(chǎn)收益率的柱狀圖,當(dāng)收益率為正時,柱子顏色設(shè)置為綠色,當(dāng)收益率為負(fù)時,柱子顏色為紅色。這樣做的好處在于突出重點和差異。 實現(xiàn)方法跟上面的例子相似,先根據(jù)邏輯條件創(chuàng)建一個顏色數(shù)組,然后傳遞給’color’參數(shù)。這時候numpy.where()非常有用。 x = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]y = [1.2, 1.5, -0.5, -0.85, 0.58, -0.35, 1.55, 1.05, -1.2, 0.45, 0.58, 0.25]# y > 0, 柱子顏色為綠色,y < 0, 柱子顏色為紅色# 使用np.where()快速實現(xiàn)向量化判斷colors = np.where(np.array(y) > 0, "green", "red")fig, ax = plt.subplots(figsize=(10, 7))ax.bar(x, y, color=colors)ax.set_title("Green bar for positive, Red bar for negative")12345678910
2. 調(diào)色板(COLORMAP)調(diào)色板(colormap)是一組顏色的集合。Matplotlib提供了很多內(nèi)置調(diào)色板,通過mpl.cm.get_cmap()獲取。 想象一下,如果要為100個元素生成不同的顏色,就要準(zhǔn)備包含100種顏色的顏色列表,自定義顏色會非常耗費時間,這時候調(diào)色板就能解決問題。 合理利用調(diào)色板,可以快速按照需求生成顏色列表。 2.1 創(chuàng)建調(diào)色板,獲取顏色Matplotlib提供了很多內(nèi)置調(diào)色板,通過mpl.cm.get_cmap()獲取,提供兩個參數(shù),第一個是調(diào)色板的名稱,另外一個是顏色列表的長度。 # 獲取名為'viridis'的調(diào)色板,顏色列表長度為8,即包含8種顏色cmap = mpl.cm.get_cmap("viridis", 8)# type(cmap)123colormap對象可以理解為一個N*4N?4的二維表格,N是顏色列表的長度,每一行都是一個(R, G, B, A)元組,元組中每個元素都是取值[0, 1][0,1]的數(shù)字。 顏色列表存儲在colormap.colors屬性中。 cmap.colors1 array([[0.267004, 0.004874, 0.329415, 1. ], [0.275191, 0.194905, 0.496005, 1. ], [0.212395, 0.359683, 0.55171 , 1. ], [0.153364, 0.497 , 0.557724, 1. ], [0.122312, 0.633153, 0.530398, 1. ], [0.288921, 0.758394, 0.428426, 1. ], [0.626579, 0.854645, 0.223353, 1. ], [0.993248, 0.906157, 0.143936, 1. ]])12345678 注意并非每一個colormap對象都有colors屬性,當(dāng)colormap是ListedColormap類型,有colors屬性,當(dāng)colormap是ListedSegmentedColormap類型時沒有colors屬性。 獲取顏色列表的另一種方法是“索引”。 # 提供一個數(shù)組,長度跟顏色列表長度相同print(cmap(range(8))) # [0, 1, 2, ... 7]print(cmap(np.linspace(0, 1, 8))) # [0, 0.1428, 0.2857, ..., 1.0]123 [[0.267004 0.004874 0.329415 1. ] [0.275191 0.194905 0.496005 1. ] [0.212395 0.359683 0.55171 1. ] [0.153364 0.497 0.557724 1. ] [0.122312 0.633153 0.530398 1. ] [0.288921 0.758394 0.428426 1. ] [0.626579 0.854645 0.223353 1. ] [0.993248 0.906157 0.143936 1. ]] [[0.267004 0.004874 0.329415 1. ] [0.275191 0.194905 0.496005 1. ] [0.212395 0.359683 0.55171 1. ] [0.153364 0.497 0.557724 1. ] [0.122312 0.633153 0.530398 1. ] [0.288921 0.758394 0.428426 1. ] [0.626579 0.854645 0.223353 1. ] [0.993248 0.906157 0.143936 1. ]]12345678910111213141516 從上面代碼示例看出,colormap是可調(diào)用對象,傳遞一個[0, 1][0,1]的浮點值可以從顏色列表中獲取一個(R,G,B,A)元組。 為什么任意浮點值可以獲取顏色?因為colormap會使用“最近鄰插值法”從顏色列表中進(jìn)行推斷,生成一個新的RGBA元組。 cmap(0.3)1 (0.212395, 0.359683, 0.55171, 1.0)1 之前創(chuàng)建柱狀圖,自定義了一個顏色列表,現(xiàn)在我們用colormap直接生成一個顏色列表。 x = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]y = [1.2, 1.5, -0.5, -0.85, 0.58, -0.35, 1.55, 1.05, -1.2, 0.45, 0.58, 0.25]# 嘗試四種不同的調(diào)色板,分別生成顏色列表cmap_names = ["viridis", "RdBu", "Set1", "jet"]fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))ax = ax.flatten()for i, name in enumerate(cmap_names):
# 創(chuàng)建colormap對象,顏色列表長度和柱子的數(shù)量相同
cmap = mpl.cm.get_cmap(name, len(x))
# 從調(diào)色板中獲取顏色列表
colors = cmap(np.linspace(0, 1, len(x)))
# 每根柱子賦予不同的顏色
ax[i].bar(x, y, color=colors)
ax[i].set_title(f"Colormap: {name}")1234567891011121314151617
2.2 調(diào)色板類型我們已經(jīng)學(xué)習(xí)了如何創(chuàng)建colormap對象,以及如何獲取顏色。接下來要考慮的問題是:
Matplotlib提供3種類型的colormap:
從分類可以看出,選擇哪種調(diào)色板取決于數(shù)據(jù)類型。 要查看全部調(diào)色板,請查閱官方文檔。 def plot_colormap(cmap_name): fig, ax = plt.subplots(figsize=(6, 2)) cmap = mpl.cm.get_cmap(cmap_name) colors = cmap(np.linspace(0, 1, cmap.N)) ax.imshow([colors], extent=[0, 10, 0, 1]) ax.set_xticks([]) ax.set_yticks([]) ax.set_title(cmap_name)12345678 順序調(diào)色板, 如’binary’, 'viridis’,用于顯示從低到高變化的定量數(shù)據(jù)。 plot_colormap("viridis")1
發(fā)散調(diào)色板,如’RdBu’,'PuOr’,一種顏色到另一種顏色的快速變化,用于突出數(shù)據(jù)與均值的偏差。 plot_colormap("RdBu")1
定性調(diào)色板, 如’rainbow’, 'jet’,在幾種顏色之間快速變化,用于顯示定性/分類數(shù)據(jù)。 plot_colormap("rainbow")1
2.3 將數(shù)值映射為顏色有時候我們想把數(shù)值映射為顏色,簡單來說就是數(shù)值大小和顏色亮度等比例變化。 回顧上面的例子,當(dāng)我們創(chuàng)建柱狀圖并賦予每根柱子不同的顏色時,是按照順序從調(diào)色板中獲取顏色的,顏色的亮度與數(shù)值大小并沒有關(guān)聯(lián),現(xiàn)在我們更進(jìn)一步,根據(jù)數(shù)值大小生成對應(yīng)的顏色,這樣可以獲得更好的可視化效果。 步驟如下:
def num2color(values, cmap):
"""將數(shù)值映射為顏色"""
norm = mpl.colors.Normalize(vmin=np.min(values), vmax=np.max(values))
cmap = mpl.cm.get_cmap(cmap)
return [cmap(norm(val)) for val in values]x = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]y = np.arange(6, -6, -1)colors = num2color(y, "RdBu")fig, ax = plt.subplots(figsize=(10, 7))ax.bar(x, y, color=colors)ax.set_title("Barplot: Map numeric data to colors")123456789101112131415
這個映射過程有點麻煩,部分Matplotlib的繪圖接口可以自動完成這個過程。 以散點圖為例,ax.scatter()的兩個參數(shù)’c’, 'cmap’,分別控制要映射的數(shù)值,以及使用的調(diào)色板。 from sklearn.datasets import load_iris# 使用IRIS數(shù)據(jù)集做說明iris = load_iris()iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)# print(iris_df.head())fig, ax = plt.subplots(figsize=(10, 7))ax.scatter(
x=iris_df["petal length (cm)"],
y=iris_df["petal width (cm)"],
c=iris_df["petal length (cm)"], # 將petal length映射為顏色
cmap="Blues" # 選擇調(diào)色板,可以提供字符串,也可以提供colormap對象實例)ax.set_title("Scatter: Map numeric data to colors")123456789101112131415
3. 結(jié)論本文介紹了如何在Matplotlib中使用顏色,包含自定義顏色和調(diào)色板(colormap)的使用方法。在數(shù)據(jù)可視化中,正確使用顏色不僅能夠使圖表更加美觀,而且有助于利用視覺效果傳達(dá)核心信息。 |
|
|