標(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")1234567891011 1. 自定義顏色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)123 colormap對象可以理解為一個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á)核心信息,。 |
|