如何在非均匀分辨率的物理距离坐标系中绘制数组
非规则网格云层模拟数据的可视化解决方案
问题背景
处理一组64×30(XZ平面)的云层大气模拟数据,要求以物理距离(千米)为坐标绘制消光系数等物理量分布图,而非数组索引/像素坐标。已知参数:
- 水平分辨率:55m
- 垂直轴范围0-1000m,分辨率非均匀:
- 云下(0-400m):分辨率50m,对应数组索引z[0]-z[9]
- 云层内(400-850m):分辨率25m,对应数组索引z[9]-z[26]
- 云上(850-1000m):分辨率50m,对应数组索引z[26]-z[29]
核心需求:高效绘制非规则网格上的数组数据。
已尝试方案
- 基础方法:将数据整理为64×30矩阵后用
matplotlib.pyplot.imshow绘制,通过extent设置物理坐标。但仅适用于均匀分辨率,垂直方向因分辨率差异导致高度显示失真。 - 暴力修改法:手动增加云外区域点数使垂直分辨率统一为25m,存在云层显示压缩、物理正确性存疑、无法适配云下非均匀物理量、需手动调参等问题。
- 插值法:使用
scipy.interpolate.griddata插值,调整坐标为物理距离后仍需依赖extent参数,未达到最优效果。
可行解决方案
核心思路:使用支持非均匀网格的绘图函数
matplotlib的pcolormesh或contourf可直接处理非均匀坐标网格,无需修改原始数据或插值,既能保证物理坐标的准确性,又能高效可视化。
步骤与代码示例
1. 构建真实物理坐标数组
先根据已知分辨率生成水平(X)和垂直(Z)方向的物理坐标(转换为千米单位):
import numpy as np import matplotlib.pyplot as plt # 水平方向坐标(64个点,55m分辨率 → 0.055km/步) x = np.arange(64) * 0.055 # 范围:0 ~ 3.465km # 垂直方向坐标(分三段构建,避免重复点) # 云下:0-400m,50m分辨率 → 0 ~ 0.4km,共10个点 z_lower = np.arange(0, 401, 50) / 1000 # 云层内:400-850m,25m分辨率 → 0.4 ~ 0.85km,共17个点(跳过与云下重复的0.4km) z_mid = np.arange(425, 851, 25) / 1000 # 云上:850-1000m,50m分辨率 → 0.85 ~ 1.0km,共3个点(跳过与云层内重复的0.85km) z_upper = np.arange(900, 1001, 50) / 1000 # 合并为完整垂直坐标数组(共10+17+3=30个点,匹配数据维度) z = np.concatenate([z_lower, z_mid, z_upper])
2. 直接绘制非均匀网格数据
假设你的消光系数数据存储在EXT数组(形状64×30,X轴为第一维度,Z轴为第二维度),使用pcolormesh绘制:
# 转置数据以匹配Z×X的网格结构 extinction_data = EXT.T plt.figure(figsize=(10, 6)) # 传入真实物理坐标,直接绘制 pcm = plt.pcolormesh(x, z, extinction_data, cmap='viridis') # 设置轴标签与样式 plt.xlabel('水平距离 (km)') plt.ylabel('高度 (km)') plt.title('云层消光系数分布') plt.colorbar(pcm, label='消光系数') # 可选:将高度轴设置为从下到上(0km在底部) plt.gca().invert_yaxis() plt.show()
3. 等值线填充图替代方案
若需要等值线形式的可视化,可使用contourf,用法类似:
plt.figure(figsize=(10, 6)) cf = plt.contourf(x, z, extinction_data, levels=20, cmap='viridis') plt.xlabel('水平距离 (km)') plt.ylabel('高度 (km)') plt.title('云层消光系数等值线分布') plt.colorbar(cf, label='消光系数') plt.gca().invert_yaxis() plt.show()
方案优势
- 物理准确性:完全保留原始数据的空间分辨率,无虚假数据引入或信息损失
- 高效性:无需插值或数据修改,直接基于原始数据绘制
- 灵活性:支持任意非均匀网格结构,适配不同的分辨率区间
内容的提问来源于stack exchange,提问作者Tom Briand
相关产品推荐
相关产品推荐

