如何基于坐标与强度数据绘制热力图?
问题描述
我有三个数组,分别存储x-y坐标和对应的强度值,尝试用seaborn的heatmap绘图,但heatmap仅接受单个数据参数,无法直接按x-y坐标对应强度值J[i]绘制。以下是最小可复现代码:
import matplotlib.pyplot as plt import numpy as np import seaborn as sn x=np.array([-1, 1, -1, 1, 0, 2, -2, 0, 2, -2, -2, 2]) y=np.array([1, 1, -1, -1, 2, 0, 0, -2, 2, 2, -2, -2]) J=np.array([-0.019, -0.019, -0.019, -0.019, -0.09, -0.09, -0.09, -0.09, 0.012, 0.012, 0.012, 0.012]) sn.heatmap(J.reshape(3,4)) plt.show()
实际需求是根据x[i]、y[i]对应绘制J[i],需要将x-y位置与J数组关联,不局限于seaborn,但必须使用插值方法(比如matplotlib.imshow也可)。目前找到的示例均基于随机生成器,没有针对特定网格点绘图的案例。
解决方案
核心思路是先将离散的x-y坐标点转换为规则网格,再通过插值填充网格内的数值,之后即可用热力图工具绘图。
1. 构建覆盖所有点的规则网格
先确定x、y的取值范围,生成覆盖所有离散点的规则网格(可调整网格密度控制绘图精细度):
import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import griddata import seaborn as sn # 原数据 x=np.array([-1, 1, -1, 1, 0, 2, -2, 0, 2, -2, -2, 2]) y=np.array([1, 1, -1, -1, 2, 0, 0, -2, 2, 2, -2, -2]) J=np.array([-0.019, -0.019, -0.019, -0.019, -0.09, -0.09, -0.09, -0.09, 0.012, 0.012, 0.012, 0.012]) # 获取坐标极值,确定网格范围 x_min, x_max = x.min(), x.max() y_min, y_max = y.min(), y.max() # 生成规则网格(第三个参数为网格点数,数值越大越精细) xi = np.linspace(x_min, x_max, 100) yi = np.linspace(y_min, y_max, 100) xi, yi = np.meshgrid(xi, yi)
2. 对离散点进行插值
使用scipy.interpolate.griddata填充网格数值,支持三种插值方法:
'linear':线性插值,平滑过渡'nearest':最近邻插值,保留离散点的尖锐变化'cubic':三次样条插值,效果更平滑,计算量稍大
# 选择插值方法生成网格强度值 zi = griddata((x, y), J, (xi, yi), method='cubic')
3. 绘图(两种方式可选)
方式一:Matplotlib imshow
适合需要自定义坐标范围的场景:
plt.figure(figsize=(8,6)) # origin='lower'确保y轴方向与实际坐标一致 plt.imshow(zi, extent=[x_min, x_max, y_min, y_max], origin='lower', cmap='viridis', interpolation='bilinear') plt.colorbar(label='强度值J') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title('插值后的强度热力图') plt.show()
方式二:Seaborn heatmap
如果偏好seaborn的样式,直接传入插值后的网格数组即可:
plt.figure(figsize=(8,6)) # 自定义刻度显示,避免刻度过多 sn.heatmap(zi, cmap='viridis', xticklabels=np.round(xi[0][::10], 2), yticklabels=np.round(yi[:,0][::10], 2)) plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title('Seaborn插值热力图') plt.show()
注意事项
- 网格密度(
linspace的第三个参数)可按需调整,数值越大图像越清晰,但计算时间会增加。 - 使用imshow时,
extent参数用于匹配实际坐标范围,origin='lower'避免y轴上下颠倒。 - 插值方法可根据数据特性选择,比如离散点变化剧烈时用
'nearest',需要平滑效果时用'cubic'。
内容的提问来源于stack exchange,提问作者user175924
相关产品推荐
相关产品推荐

