如何用三个一维数组生成目标热力图,现有散点图如何调整优化?
问题描述
我需要基于3个一维数组生成热力图,预期效果如下图所示:
目前我仅能绘制散点图,其中散点的颜色、尺寸由第三个数组的取值决定,编写的代码如下:
xf = np.random.rand(1000) yf = np.random.rand(1000) zf = 1e5*np.random.rand(1000) ms1 = (zf).astype('int') from matplotlib.colors import LinearSegmentedColormap # Remove the middle 40% of the RdBu_r colormap interval = np.hstack([np.linspace(0, 0.4), np.linspace(0.6, 1)]) colors = plt.cm.RdBu_r(interval) cmap = LinearSegmentedColormap.from_list('name', colors) col = cmap(np.linspace(0,1,len(ms1))) #for i in range(len(ms1)): plt.scatter(xf, yf, c=zf, s=5*ms1/1e4, cmap=cmap,alpha=0.8)#, norm =matplotlib.colors.LogNorm()) ax1 =plt.colorbar(pad=0.01)
运行代码得到的实际效果如下图:
请问需要如何调整才能得到预期的热力图效果?我本质的需求是对x、y数组分组后计算对应z值的平均值。
解决方案
你当前用散点绘图的方式没法实现连续的热力效果,需要先对x、y做二维网格分箱,统计每个网格内z的平均值,再绘制热力矩阵即可,修改后的代码如下:
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap # 模拟数据和原逻辑保持一致 xf = np.random.rand(1000) yf = np.random.rand(1000) zf = 1e5*np.random.rand(1000) # 自定义色阶和原代码保持一致 interval = np.hstack([np.linspace(0, 0.4), np.linspace(0.6, 1)]) colors = plt.cm.RdBu_r(interval) cmap = LinearSegmentedColormap.from_list('name', colors) # 1. 定义分箱精度,数值越大热力图细节越丰富 bins = 50 # 2. 二维分箱统计每个网格内的z值总和、数据点数量 z_sum, x_edges, y_edges = np.histogram2d(xf, yf, bins=bins, weights=zf) point_count, _, _ = np.histogram2d(xf, yf, bins=bins) # 计算均值,无数据的网格赋值为NaN避免干扰 z_mean = np.where(point_count>0, z_sum/point_count, np.nan) # 3. 绘制热力图,注意矩阵转置匹配坐标轴 plt.pcolormesh(x_edges, y_edges, z_mean.T, cmap=cmap, alpha=0.8) plt.colorbar(pad=0.01) plt.show()
如果需要更平滑的热力效果,可以引入高斯滤波对均值矩阵做平滑处理,添加如下代码即可:
from scipy.ndimage import gaussian_filter # sigma参数控制平滑程度,可根据需求调整 z_mean_smooth = gaussian_filter(z_mean, sigma=1.5) # 替换绘图环节的z_mean为z_mean_smooth即可 plt.pcolormesh(x_edges, y_edges, z_mean_smooth.T, cmap=cmap, alpha=0.8)
内容的提问来源于stack exchange,提问作者jokerp
相关产品推荐
相关产品推荐

