如何用非均匀间隔的X、Y数据生成1D热力图?
解决非均匀间隔X、Y数据的热力图绘制问题
针对非均匀间隔数据无法在常规热力图中突出高频区域的问题,以下几种方法可以实现符合需求的热力图,同时保留折线图的线性分布特征:
方法1:核密度估计(KDE)生成热力图
KDE会根据数据点的分布密度生成连续的热力效果,自动让高频区域呈现暖色,完美适配非均匀数据。用scipy.stats.gaussian_kde配合Matplotlib即可实现:
import numpy as np import matplotlib.pyplot as plt from scipy.stats import gaussian_kde # 模拟非均匀间隔的X、Y数据(替换成你的真实数据) np.random.seed(42) x = np.concatenate([np.random.normal(0, 0.5, 500), np.random.normal(3, 0.2, 1000)]) y = np.concatenate([np.random.normal(0, 0.5, 500), np.random.normal(2, 0.2, 1000)]) # 计算核密度估计 xy = np.vstack([x, y]) kde = gaussian_kde(xy) # 创建均匀网格用于绘制 xi, yi = np.mgrid[x.min():x.max():100j, y.min():y.max():100j] zi = kde(np.vstack([xi.flatten(), yi.flatten()])) # 绘制热力图 plt.figure(figsize=(8,6)) plt.imshow(zi.reshape(xi.shape), extent=[x.min(), x.max(), y.min(), y.max()], origin='lower', cmap='viridis') plt.scatter(x, y, s=5, c='white', alpha=0.3) # 叠加原始数据点做参考 plt.colorbar(label='数据密度') plt.xlabel('X') plt.ylabel('Y') plt.title('KDE生成的非均匀数据热力图') plt.show()
方法2:插值到均匀网格(保留折线分布)
如果需要严格保留折线图的线性函数关系,可以先把非均匀数据插值到均匀网格,再基于插值结果绘制热力图。用scipy.interpolate.griddata实现:
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata from scipy.ndimage import gaussian_filter # 模拟折线图式的非均匀数据(Y随X线性变化+噪声) x = np.random.uniform(0, 10, 800) x = np.sort(x) y = 2*x + np.random.normal(0, 1, 800) + 5*np.sin(x/2) # 创建均匀网格 xi = np.linspace(x.min(), x.max(), 200) yi = np.linspace(y.min(), y.max(), 200) xi, yi = np.meshgrid(xi, yi) # 计算数据点密度并插值到网格 H, xedges, yedges = np.histogram2d(x, y, bins=50) H = gaussian_filter(H, sigma=2) # 平滑处理 zi = griddata( (xedges[:-1]+xedges[1:])/2, (yedges[:-1]+yedges[1:])/2, H.T, (xi, yi), method='cubic' ) # 绘制热力图+叠加原始折线 plt.figure(figsize=(8,6)) plt.contourf(xi, yi, zi, cmap='viridis', levels=20) plt.plot(x, y, 'r-', linewidth=1, alpha=0.5) plt.colorbar(label='数据密度') plt.xlabel('X') plt.ylabel('Y') plt.title('保留折线分布的插值热力图') plt.show()
方法3:Hexbin六边形分箱热力图
Matplotlib自带的hexbin会自动把数据分到六边形格子里,统计每个格子的点数,轻量化且直观,能自然突出高频区域:
import numpy as np import matplotlib.pyplot as plt # 模拟非均匀XY数据 x = np.concatenate([np.random.normal(2, 0.3, 600), np.random.normal(7, 0.5, 1200)]) y = 1.5*x + np.random.normal(0, 1, 1800) # 绘制hexbin热力图 plt.figure(figsize=(8,6)) hb = plt.hexbin(x, y, gridsize=30, cmap='viridis', mincnt=1) plt.plot(x, y, 'k.', markersize=2, alpha=0.2) plt.colorbar(hb, label='每个六边形内的点数') plt.xlabel('X') plt.ylabel('Y') plt.title('Hexbin分箱热力图') plt.show()
选择建议
- 若要突出数据密度分布,优先用KDE方法;
- 若要严格保留折线图的函数关系,选插值到均匀网格的方案;
- 追求计算速度和轻量化展示,直接用Hexbin分箱。
内容的提问来源于stack exchange,提问作者lynn233
相关产品推荐
相关产品推荐

