數據量太大?散點圖裝不下怎么辦?用Python解決數據密度過大難題
當我們需要觀察比較2個變量間的關系時,散點圖是我們首選圖表。
可當數據量非常大,數據點又比較集中在某個區間中,圖表沒法看,密密麻麻的怎么看?
怎么辦?這時候就得看密度圖了
什么是密度圖?

所謂的密度圖 (Density Plot) 就是數據的分布稠密情況,它常用于顯示數據在連續時間段內的分布狀況。嚴格來說,它是由直方圖演變而來,類似于把直方圖進行了填充。
一般是使用平滑曲線來繪制數值水平來觀察分布,峰值數值位置是該時間段內最高度集中的地方。
它比直方圖適用性更強,不受分組數量(直方圖的條形數量不宜過多)的影響,能更好地界定分布形狀 。
本篇文章不談論直方圖,之后老海會專門總結關于直方圖的使用。
什么是2D密度圖?
說完了密度圖和直方圖,它們都是一維數據變量。
這下我們來看看2D密度圖,它顯示了數據集中兩個定量變量范圍內值的分布,有助于避免在散點圖中過度繪制。
如果點太多,則2D密度圖會計算2D空間特定區域內的觀察次數。
該特定區域可以是正方形或六邊形(六邊形),還可以估算2D內核密度估算值,并用輪廓表示它。
本篇文章主要描述一下2D密度圖的使用。

2D密度圖的基本數據樣式

2D密度圖的使用建議
- 密度圖是一種直方圖的代替方案,常用來觀察連續變量的分布情況
- 2D密度圖主要用來解決數據點密度過大的問題,要注意密度分割是否合理。
- 當數據范圍都非常集中,數據間變化不大時,密度圖往往很難觀察效果。
下面開始具體的操作案例
準備工作
還是和之前一樣,引入必要的工具包

- ## 初始字體設置,設置好可避免很多麻煩
- plt.rcParams['font.sans-serif']=['Source Han Sans CN'] # 顯示中文不亂碼,思源黑體
- plt.rcParams['font.size'] = 22 # 設置圖表全局字體大小,后期某個元素的字體大小可以自行調整
- plt.rcParams['axes.unicode_minus'] = False # 顯示負數不亂碼
- ## 初始化圖表大小
- plt.rcParams['figure.figsize'] = (20.0, 8.0) # 設置figure_size尺寸
- ## 初始化圖表分辨率質量
- plt.rcParams['savefig.dpi'] = 300 # 設置圖表保存時的像素分辨率
- plt.rcParams['figure.dpi'] = 300 # 設置圖表繪制時的像素分辨率
- ## 圖表的顏色自定義
- colors = ['#dc2624', '#2b4750', '#45a0a2', '#e87a59',
- '#7dcaa9', '#649E7D', '#dc8018', '#C89F91',
- '#6c6d6c', '#4f6268', '#c7cccf']
- plt.rcParams['axes.prop_cycle'] = plt.cycler( color=colors)
- path = 'D:\\系列文章\\'
- # 自定義文件路徑,可以自行設定
- os.chdir(path)
- # 設置為該路徑為工作路徑,一般存放數據源文件
設定圖表樣式和文件路徑

- Financial_data = pd.read_excel('虛擬演示案例數據.xlsx',sheet_name='二維表')
- Financial_data
讀入數據

- Financial_data = pd.read_excel('虛擬演示案例數據.xlsx',sheet_name='二維表')
- Financial_data
常見的6種密度圖表類型

- from scipy.stats import kde # 引入核密度計算方法
- # 為方便演示,創建6個子圖的畫板
- fig, axes = plt.subplots(3,2, figsize=(20, 20))
- # 第一個子圖,我們來畫一個基本的散點圖
- # 散點圖是最經典的觀察2個變量關系,但數據量非常大就會出數據點堆疊交錯,當值我們無法進一步探索
- axes[0][0].set_title('散點圖') # 設置標題
- axes_0 = axes[0][0].plot(Financial_data['材料'], Financial_data['管理'], 'ko') # 畫出散點圖
- # 第二個子圖,我們畫出六邊形蜂巢圖
- # 當尋找2個數值型變量的關系,數據量很大且不希望數據堆疊在一起,就可以按照蜂巢形狀切割數據點,計算每個六邊形里的點數來表達密度
- num_bins = 50 # 設置六邊形包含的距離
- axes[0][1].set_title('蜂巢六邊形圖') # 設置標題
- axes_1= axes[0][1].hexbin(Financial_data['材料'], Financial_data['管理'],
- gridsize=num_bins, # 設置六邊形的大小
- cmap="Blues" # 設置顏色組合
- )
- fig.colorbar(axes_1,ax=axes[0][1]) # 設置顏色顯示條
- # 第三個子圖,我們畫出2D直方圖。
- # 我們您需要分析兩個數據量比較大的數值變量關系時,2D直方圖非常有用,它可以避免在散點圖中出現的的數據密度過大問題
- num_bins = 50
- axes[1][0].set_title('2D 直方圖')
- axes_2 = axes[1][0].hist2d(Financial_data['材料'], Financial_data['管理'],
- bins=(num_bins,num_bins),
- cmap="Blues")
- # fig.colorbar(axes_2,ax=axes[1][0])
- # 第四個子圖,我們畫出高斯核密度圖
- # 考慮到想研究具有很多點的兩個數值變量之間的關系。可以考慮繪圖區域每個部分上的點數,來計算2D內核密度估計值。
- # 就像平滑的直方圖,這個方法不會使某個點掉入特定的容器中,而是會增加周圍容器的權重,比如顏色會加深。
- k = kde.gaussian_kde(Financial_data.loc[:,['材料','管理']].values.T) # 進行核密度計算
- xi, yi = np.mgrid[Financial_data['材料'].min():Financial_data['材料'].max():num_bins*1j, Financial_data['管理'].min():Financial_data['管理'].max():num_bins*1j]
- zi = k(np.vstack([xi.flatten(), yi.flatten()]))
- axes[1][1].set_title('高斯核密度圖')
- axes_3 = axes[1][1].pcolormesh(xi,
- yi,
- zi.reshape(xi.shape),
- cmap="Blues")
- fig.colorbar(axes_3,ax=axes[1][1]) # 設置顏色顯示條
- # 第五個子圖,我們畫出帶陰影效果的2D密度圖
- axes[2][0].set_title('帶陰影效果的2D密度圖')
- axes[2][0].pcolormesh(xi,
- yi,
- zi.reshape(xi.shape),
- shading='gouraud',
- cmap="Blues")
- # 第六個子圖,我們畫出帶輪廓線的密度圖
- axes[2][1].set_title('帶陰影+輪廓線的2D密度圖')
- axes_5 = axes[2][1].pcolormesh(xi,
- yi,
- zi.reshape(xi.shape),
- shading='gouraud',
- cmap="Blues")
- fig.colorbar(axes_5,ax=axes[2][1]) # 設置顏色顯示條
- # 畫出輪廓線
- axes[2][1].contour(xi,
- yi,
- zi.reshape(xi.shape))
- plt.show()
特別提一下:2D核密度估計圖

- sns.kdeplot(Financial_data['材料'],Financial_data['管理'])
- sns.despine() # 默認無參數狀態,就是刪除上方和右方的邊框,matplotlib貌似做不到

- sns.kdeplot(Financial_data['材料'],Financial_data['管理'],
- cmap="Reds",
- shade=True, # 若為True,則在kde曲線下面的區域中進行陰影處理,color控制曲線及陰影的顏色
- shade_lowest=True, # 如果為True,則屏蔽雙變量KDE圖的最低輪廓。
- # bw=.15
- )
- sns.despine() # 默認無參數狀態,就是刪除上方和右方的邊框,matplotlib貌似做不到

寫在最后
之前介紹了散點圖、熱力圖,這次的2D密度圖,也是觀察數據分布的好圖表
它同樣符合圖表演變原則,符合直方圖→1D密度圖→2D密度圖的變化過程
在解決數據點密度大,造成數據堆疊無法觀察的問題上,密度圖非常有用。
OK,今天先到這里了,老海日常隨筆總結,碼字不易,初心不改!
如果覺得喜歡,請動動小手關注和轉發,鼓勵一下我們。