基于不规则XY网格的Matplotlib等高线图绘制问题求助
解决方案:不规则XY网格的等高线可视化
你的数据属于非结构化/不规则网格数据:每个y值对应一组独立的x和z数组,各组x的元素并不对齐,因此Matplotlib常规的contour/contourf要求的规则网格输入不适用。以下是两种可行的可视化方案:
方案1:直接使用三角剖分绘制(无需插值)
Matplotlib的tricontourf专门用于处理非结构化数据,它会自动对散点进行三角剖分并填充等高线。
代码实现
import pickle import numpy as np import matplotlib.pyplot as plt # 加载数据 with open('data.pkl', 'rb') as f: data_loaded = pickle.load(f) x_list, y_arr, z_list = data_loaded['eigenenergies'], data_loaded['r_primes'], data_loaded['dc_intensities'] # 将数据扁平化:把每组x/z展开,对应重复y值 x_flat = np.concatenate(x_list) y_flat = np.repeat(y_arr, [len(x_group) for x_group in x_list]) z_flat = np.concatenate(z_list) # 绘制三角剖分填充等高线 num_levels = 1000 plt.tricontourf( x_flat, y_flat, z_flat, levels=np.linspace(z_flat.min(), z_flat.max(), num_levels), cmap='viridis' # 可根据需求更换配色 ) # 添加标注 colorbar = plt.colorbar() colorbar.set_label(r"Intensity") plt.xlabel(r'$E \;\;[J]$') plt.ylabel(r'$r^\prime \;[\AA]$') plt.title('DC') plt.show()
优缺点
- 优势:完全保留原始数据分布,无插值误差,计算速度快
- 劣势:若数据分布不均,边缘区域可能出现三角剖分的锯齿效果
方案2:插值到规则网格后绘制
如果需要平滑的规则网格可视化,可以用scipy的插值工具将非结构化数据映射到规则网格上,再用常规contourf绘制。
代码实现
import pickle import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata # 加载数据(同方案1) with open('data.pkl', 'rb') as f: data_loaded = pickle.load(f) x_list, y_arr, z_list = data_loaded['eigenenergies'], data_loaded['r_primes'], data_loaded['dc_intensities'] # 扁平化数据 x_flat = np.concatenate(x_list) y_flat = np.repeat(y_arr, [len(x_group) for x_group in x_list]) z_flat = np.concatenate(z_list) # 定义规则网格范围与密度 x_min, x_max = x_flat.min(), x_flat.max() y_min, y_max = y_arr.min(), y_arr.max() xi = np.linspace(x_min, x_max, 1000) # x方向取1000个点,可调整 yi = np.linspace(y_min, y_max, 100) # y方向取100个点,可调整 xi_mesh, yi_mesh = np.meshgrid(xi, yi) # 插值(可选method: 'nearest'/'linear'/'cubic') zi = griddata( (x_flat, y_flat), z_flat, (xi_mesh, yi_mesh), method='linear' # 线性插值平衡速度与精度 ) # 绘制规则网格等高线 num_levels = 1000 plt.contourf( xi_mesh, yi_mesh, zi, levels=np.linspace(z_flat.min(), z_flat.max(), num_levels), cmap='viridis' ) # 添加标注 colorbar = plt.colorbar() colorbar.set_label(r"Intensity") plt.xlabel(r'$E \;\;[J]$') plt.ylabel(r'$r^\prime \;[\AA]$') plt.title('DC (Interpolated to Regular Grid)') plt.show()
插值方法说明
nearest:最近邻插值,速度最快,结果最粗糙,无平滑效果linear:线性插值,速度适中,结果平滑度中等,无额外数据生成cubic:三次插值,速度最慢,结果最平滑,但会生成额外的中间值
内容的提问来源于stack exchange,提问作者AspiringPhysicist
相关产品推荐
相关产品推荐

