使用Python繪制動態(tài)方塊熱力圖
在數(shù)據(jù)可視化的世界里,熱力圖一直是展現(xiàn)矩陣數(shù)據(jù)分布的強(qiáng)大工具。它能讓枯燥的數(shù)值瞬間變得生動形象,幫助我們快速捕捉數(shù)據(jù)中的模式、異常和趨勢。今天,我要分享一種別具一格的熱力圖繪制方式 ——方塊大小與顏色雙變量可視化,通過 Python 代碼實現(xiàn)一個既美觀又信息豐富的可視化作品。如果你曾為如何讓數(shù)據(jù) “活起來” 而煩惱,這篇文章一定會給你帶來新的靈感!
為什么選擇這種熱力圖?
傳統(tǒng)熱力圖通常只通過顏色深淺來表達(dá)數(shù)值大小,而我們今天要實現(xiàn)的版本增加了一個維度 ——方塊面積。這種雙變量可視化的優(yōu)勢在于:
- 顏色感知更直觀:人類視覺對顏色的敏感度極高,不同色調(diào)能快速傳遞數(shù)值層級
- 面積大小強(qiáng)化差異:當(dāng)數(shù)值差異較大時,面積變化比顏色變化更具沖擊力
- 信息密度更高:在有限空間內(nèi)展示更多維度的數(shù)據(jù)特征
這種可視化方式特別適合:
- 特征重要性分析(如機(jī)器學(xué)習(xí)模型的特征權(quán)重)
- 二維數(shù)據(jù)分布展示(如用戶行為矩陣、市場份額分析)
- 數(shù)據(jù)對比場景(如不同條件下的指標(biāo)對比)
代碼實現(xiàn):從 0 到 1 的可視化之旅
先來看完整代碼,我們將逐步拆解每一個神奇的步驟:
import numpy as np import matplotlib.pyplot as plt # 隨機(jī)生成一個 10x10 的矩陣,值域在 0 到 1 之間 np.random.seed(0) data = np.random.rand(10, 10) fig, ax = plt.subplots(figsize=(8, 6)) # 創(chuàng)建顏色映射(使用 colormap) cmap = plt.cm.RdYlGn norm = plt.Normalize(vmin=0, vmax=1) # 繪制方塊 for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] color = cmap(norm(value)) size = value * 900 # 控制面積大小(最大 900) # 使用 scatter 繪制方塊 ax.scatter(j + 1, 10 - i, s=size, c=[color], marker='s', edgecolor='black') # 設(shè)置坐標(biāo)軸 ax.set_xticks(np.arange(1, 11)) ax.set_yticks(np.arange(1, 11)) ax.set_xticklabels(np.arange(1, 11)) ax.set_yticklabels(np.arange(1, 11)) ax.set_xlabel("K (w)", fontsize=12) ax.set_ylabel("Samples", fontsize=12) # 添加標(biāo)題 ax.set_title("Square Heatmap Plot", fontsize=14, fontweight='bold') # 添加顏色條 sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) sm.set_array([]) cbar = plt.colorbar(sm, ax=ax) cbar.set_label("") # 添加網(wǎng)格線模擬邊框 ax.set_xlim(0.5, 10.5) ax.set_ylim(0.5, 10.5) ax.set_xticks(np.arange(0.5, 11.5, 1), minor=True) ax.set_yticks(np.arange(0.5, 11.5, 1), minor=True) ax.grid(which='minor', color='black', linewidth=1) ax.tick_params(which='minor', length=0) plt.tight_layout() plt.show()
效果如下
核心組件拆解:每一行代碼都在做什么?
1. 數(shù)據(jù)準(zhǔn)備:打造可視化的基石
np.random.seed(0) data = np.random.rand(10, 10)
np.random.seed(0) 是為了保證結(jié)果可復(fù)現(xiàn),就像給隨機(jī)數(shù)生成器設(shè)定一個 “起點”,這樣別人運行代碼時能得到和你一樣的數(shù)據(jù)~
np.random.rand(10, 10) 生成一個 10x10 的隨機(jī)矩陣,數(shù)值范圍在 0 到 1 之間。這里就是替換自己數(shù)據(jù)的關(guān)鍵位置!你可以:
- 從文件讀取數(shù)據(jù):data = np.loadtxt('your_data.csv', delimiter=',')
- 加載已有的 numpy 數(shù)組:data = np.array(your_custom_data)
- 甚至手動定義矩陣:data = np.array([[0.1, 0.5], [0.8, 0.3]])
提示: 如果你的數(shù)據(jù)值域不在 0-1 之間,后續(xù)的顏色映射和大小計算需要相應(yīng)調(diào)整哦~
2. 畫布搭建:準(zhǔn)備好展示數(shù)據(jù)的舞臺
fig, ax = plt.subplots(figsize=(8, 6))
plt.subplots() 創(chuàng)建一個 Figure 對象和一個 Axes 對象,這是 Matplotlib 繪圖的標(biāo)準(zhǔn)流程~
figsize=(8, 6) 設(shè)置畫布大小為 8 英寸寬、6 英寸高,你可以根據(jù)數(shù)據(jù)量調(diào)整這個參數(shù),比如數(shù)據(jù)是 20x20 的,可以設(shè)為 (10,10) 讓每個方塊更清晰。
3. 顏色系統(tǒng):讓數(shù)據(jù)穿上絢麗的外衣
cmap = plt.cm.RdYlGn norm = plt.Normalize(vmin=0, vmax=1)
cmap = plt.cm.RdYlGn 選擇了一個從紅色到黃色再到綠色的顏色映射,數(shù)值小的地方顯示紅色,數(shù)值大的地方顯示綠色,中間過渡自然~
你可以換成其他顏色映射:
- plt.cm.viridis(藍(lán)綠黃漸變,適合連續(xù)數(shù)據(jù))
- plt.cm.coolwarm(藍(lán)紅漸變,適合正負(fù)值對比)
- plt.cm.Blues(單色系藍(lán)色,適合單一趨勢數(shù)據(jù))
norm = plt.Normalize(vmin=0, vmax=1) 定義了數(shù)值到顏色的映射規(guī)則,將數(shù)據(jù)范圍歸一化到 0-1,這樣顏色變化能準(zhǔn)確反映數(shù)值差異。如果你的數(shù)據(jù)值域是 5-100,這里要改成vmin=5, vmax=100哦!
4. 方塊繪制:數(shù)據(jù)可視化的核心邏輯
for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] color = cmap(norm(value)) size = value * 900 # 控制面積大?。ㄗ畲?900) ax.scatter(j + 1, 10 - i, s=size, c=[color], marker='s', edgecolor='black')
這部分是代碼的靈魂!我們通過雙重循環(huán)遍歷矩陣的每個元素:
value = data[i, j] 取出當(dāng)前位置的數(shù)值
color = cmap(norm(value)) 將數(shù)值轉(zhuǎn)換為對應(yīng)的顏色,這里用到了前面定義的顏色映射和歸一化規(guī)則
size = value * 900 計算方塊面積,數(shù)值越大方塊越大。這里的 900 是一個縮放因子,你可以調(diào)整它來控制方塊的大小范圍,比如改成 500 讓方塊更小,或者 1500 讓差異更明顯~
ax.scatter(...) 是繪制方塊的關(guān)鍵函數(shù):
- j + 1, 10 - i 是方塊的坐標(biāo),注意這里10 - i是為了讓 y 軸從上到下遞增,符合矩陣的行列索引習(xí)慣
- s=size 控制面積大小
- c=[color] 設(shè)置顏色,注意用列表包裹顏色值
- marker='s' 將散點形狀設(shè)為正方形(square),也可以換成'o'圓形、'^'三角形等
- edgecolor='black' 添加黑色邊框,讓每個方塊更清晰可辨
5. 細(xì)節(jié)優(yōu)化:讓圖表更專業(yè)美觀
# 設(shè)置坐標(biāo)軸 ax.set_xticks(np.arange(1, 11)) ax.set_yticks(np.arange(1, 11)) ax.set_xticklabels(np.arange(1, 11)) ax.set_yticklabels(np.arange(1, 11)) ax.set_xlabel("K (w)", fontsize=12) ax.set_ylabel("Samples", fontsize=12) # 添加標(biāo)題 ax.set_title("Square Heatmap Plot", fontsize=14, fontweight='bold') # 添加顏色條 sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) sm.set_array([]) cbar = plt.colorbar(sm, ax=ax) cbar.set_label("") # 添加網(wǎng)格線模擬邊框 ax.set_xlim(0.5, 10.5) ax.set_ylim(0.5, 10.5) ax.set_xticks(np.arange(0.5, 11.5, 1), minor=True) ax.set_yticks(np.arange(0.5, 11.5, 1), minor=True) ax.grid(which='minor', color='black', linewidth=1) ax.tick_params(which='minor', length=0)
這部分是讓圖表從 “能用” 到 “精美” 的關(guān)鍵:
- 坐標(biāo)軸設(shè)置:明確 x 軸和 y 軸的刻度位置和標(biāo)簽,ax.set_xlabel和ax.set_ylabel可以換成你自己的變量名稱,比如 “時間(小時)”“用戶活躍度” 等。
- 標(biāo)題添加:ax.set_title讓圖表有一個清晰的主題,fontweight='bold'讓標(biāo)題更醒目。
- 顏色條:這是熱力圖的 “翻譯器”,告訴讀者顏色對應(yīng)的數(shù)值范圍。sm.set_array([])是一個小技巧,用于初始化顏色映射對象。
- 網(wǎng)格線與邊框:這里用了一個巧妙的方法 —— 通過設(shè)置次要刻度(minor ticks)并繪制網(wǎng)格線,模擬出每個方塊的邊框。ax.set_xlim(0.5, 10.5)將坐標(biāo)軸范圍擴(kuò)展到 0.5-10.5,這樣 10x10 的矩陣剛好占據(jù)整個區(qū)域,網(wǎng)格線就像一個個小格子~
自定義你的可視化:從模仿到創(chuàng)新
1. 替換成你自己的數(shù)據(jù)
正如前面提到的,數(shù)據(jù)生成部分是最容易替換的地方。假設(shè)你有一個從 Excel 中導(dǎo)出的 15x15 的用戶行為數(shù)據(jù)矩陣,路徑為user_behavior.csv,你可以這樣做:
# 從CSV文件讀取數(shù)據(jù) data = np.loadtxt('user_behavior.csv', delimiter=',') # 或者使用pandas讀?。ǜ`活) import pandas as pd data = pd.read_csv('user_behavior.csv').values
如果你的數(shù)據(jù)值域不是 0-1,比如是 10-100,需要調(diào)整顏色映射和大小計算:
# 假設(shè)數(shù)據(jù)值域是10-100 vmin, vmax = 10, 100 norm = plt.Normalize(vmin=vmin, vmax=vmax) size = (value - vmin) / (vmax - vmin) * 900 # 歸一化后計算大小
2. 調(diào)整顏色映射和視覺效果
如果你不喜歡 RdYlGn 顏色映射,可以嘗試其他方案:
# 冷色調(diào)到暖色調(diào)(適合顯示數(shù)值遞增趨勢) cmap = plt.cm.Blues # 紅黃色調(diào)(適合突出高數(shù)值區(qū)域) cmap = plt.cm.OrRd # 彩虹色調(diào)(適合展示復(fù)雜模式) cmap = plt.cm.rainbow
3. 優(yōu)化大數(shù)據(jù)量場景
如果你的數(shù)據(jù)是 100x100 的大矩陣,直接繪制可能會顯得擁擠,這時可以:
- 調(diào)整畫布大小:fig, ax = plt.subplots(figsize=(12, 12))
- 減小邊框和網(wǎng)格線寬度:ax.grid(which='minor', color='black', linewidth=0.5)
- 取消邊框:ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False)
4. 添加交互功能(進(jìn)階)
如果想讓圖表更動態(tài),可以使用matplotlib的交互功能或結(jié)合ipywidgets:
from matplotlib.widgets import Slider # 創(chuàng)建滑塊來調(diào)整大小縮放因子 ax_slider = plt.axes([0.25, 0.02, 0.65, 0.03]) slider = Slider(ax_slider, 'Size Scale', 100, 2000, valinit=900) def update(val): scale = slider.val for i in range(data.shape[0]): for j in range(data.shape[1]): value = data[i, j] size = value * scale # 這里需要先清除之前的散點,再重新繪制 # 由于scatter返回的是PathCollection對象,可以保存后更新 fig.canvas.draw_idle() slider.on_changed(update)
應(yīng)用場景:讓可視化解決實際問題
這種雙變量熱力圖在實際場景中能做什么?舉幾個栗子:
1. 機(jī)器學(xué)習(xí)特征重要性可視化
假設(shè)你訓(xùn)練了一個隨機(jī)森林模型,想展示各特征的重要性:
# 假設(shè)feature_importances是形狀為(20,)的數(shù)組 data = feature_importances.reshape(4, 5) # 調(diào)整為4x5的矩陣便于可視化
2. 市場份額分析
展示不同地區(qū)、不同產(chǎn)品的市場占有率:
# 行:地區(qū)(華北、華東、華南、西北、西南) # 列:產(chǎn)品(A、B、C、D) data = np.array([ [0.35, 0.25, 0.15, 0.25], [0.28, 0.32, 0.18, 0.22], [0.40, 0.20, 0.15, 0.25], [0.22, 0.30, 0.25, 0.23], [0.25, 0.25, 0.30, 0.20] ])
3. 圖像像素強(qiáng)度可視化
將灰度圖像轉(zhuǎn)換為熱力圖展示:
from skimage import data import matplotlib.pyplot as plt # 加載示例圖像 image = data.camera() # 歸一化到0-1 data = image / 255.0
注意事項:避坑指南
方塊重疊問題:當(dāng)數(shù)值差異很大時,大的方塊可能會覆蓋小的方塊??梢酝ㄟ^調(diào)整size的縮放因子或添加透明度來解決:
ax.scatter(..., alpha=0.8) # 添加透明度
坐標(biāo)軸標(biāo)簽旋轉(zhuǎn):當(dāng) x 軸標(biāo)簽較多時,可能會重疊,可以旋轉(zhuǎn)標(biāo)簽:
ax.set_xticklabels(np.arange(1, 11), rotation=45, ha='right')
性能問題:處理超大矩陣(如 1000x1000)時,雙重循環(huán)會很慢??梢愿挠胮colormesh結(jié)合PatchCollection優(yōu)化,但需要重寫繪制邏輯~
顏色對比度:選擇顏色映射時要考慮色盲友好性,plt.cm.viridis是一個不錯的選擇,或者使用seaborn的調(diào)色板:
import seaborn as sns cmap = sns.color_palette("coolwarm", as_cmap=True)
結(jié)語:讓數(shù)據(jù)開口說話
可視化的魅力在于將抽象的數(shù)字轉(zhuǎn)化為直觀的視覺信號,幫助我們理解數(shù)據(jù)背后的故事。今天分享的方塊熱力圖通過顏色和大小雙重維度,讓數(shù)據(jù)呈現(xiàn)更加立體生動。無論是科研數(shù)據(jù)展示、商業(yè)數(shù)據(jù)分析還是日常數(shù)據(jù)探索,這種可視化方式都能為你增添一份力量~
現(xiàn)在,快試試用你自己的數(shù)據(jù)繪制吧!只需要替換data變量的定義部分,調(diào)整顏色映射和大小參數(shù),就能得到屬于你的專屬可視化作品~
以上就是使用Python繪制動態(tài)方塊熱力圖的詳細(xì)內(nèi)容,更多關(guān)于Python繪制熱力圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python正常時間和unix時間戳相互轉(zhuǎn)換的方法
這篇文章主要介紹了python正常時間和unix時間戳相互轉(zhuǎn)換的方法,涉及時間字符串與Unix時間戳的實現(xiàn)與轉(zhuǎn)換技巧,需要的朋友可以參考下2015-04-04win8下python3.4安裝和環(huán)境配置圖文教程
這篇文章主要為大家詳細(xì)介紹了win8下python3.4安裝和環(huán)境配置圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07python網(wǎng)頁請求urllib2模塊簡單封裝代碼
這篇文章主要分享一個python網(wǎng)頁請求模塊urllib2模塊的簡單封裝代碼,有需要的朋友參考下2014-02-02Python使用ntplib庫同步校準(zhǔn)當(dāng)?shù)貢r間的方法
NTP網(wǎng)絡(luò)時間協(xié)議其實大家平時或多或少都能接觸到,包括Windows在內(nèi)的操作系統(tǒng)中的很多Internet時間同步功能都是在NTP的基礎(chǔ)上來做,這里我們來看一下Python使用ntplib庫同步校準(zhǔn)當(dāng)?shù)貢r間的方法2016-07-07Python自定義函數(shù)定義,參數(shù),調(diào)用代碼解析
這篇文章主要介紹了Python自定義函數(shù)定義,參數(shù),調(diào)用代碼解析,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12使用Python實現(xiàn)調(diào)整Excel中的行列順序
調(diào)整Excel?行列順序指的是改變工作表中行或列的位置,以便更好地展示和分析數(shù)據(jù),本文將介紹如何通過Python高效地調(diào)整Excel?行列順序,感興趣的可以了解下2025-01-01Python mutiprocessing多線程池pool操作示例
這篇文章主要介紹了Python mutiprocessing多線程池pool操作,結(jié)合實例形式分析了Python多線程模塊multiprocessing進(jìn)程池相關(guān)操作技巧,需要的朋友可以參考下2019-01-01