如何用Matplotlib从稀疏数据点插值生成等高线填充图?
从离散气象站点数据生成插值等高线填充地图的实现方案
嗨 Stephane!针对你想要把离散的小时温度站点数据转换成平滑等高线填充图的需求,我给你整理了一套实用的实现步骤,用Python的常用科学计算库就能搞定,一起来看看吧:
核心思路
要实现从稀疏点到填充等高线的转换,主要分三步:
- 生成覆盖目标区域的细密经纬度网格
- 把离散站点的温度值插值到网格上
- 绘制带地图底图的填充等高线
具体代码实现
1. 导入所需库
我们会用到numpy处理数组、scipy做插值、matplotlib绘图,还有cartopy来添加专业的地图底图(如果不需要地图底图可以跳过cartopy部分):
import numpy as np from scipy.interpolate import griddata, Rbf import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature
2. 准备你的数据
假设你已经有了三个浮点数组:
lat_array: 所有站点的纬度数组lon_array: 所有站点的经度数组temp_array: 对应站点的小时温度数组
(如果你的数据还没整理成数组,用np.array()把列表转成numpy数组即可)
3. 创建插值网格
先确定你要覆盖的经纬度范围,然后生成细密的网格点:
# 确定经纬度范围(可以用数据的最大最小值来自动设置) lon_min, lon_max = lon_array.min(), lon_array.max() lat_min, lat_max = lat_array.min(), lat_array.max() # 生成网格,这里的100j表示在纬度方向生成100个点,可根据需求调整密度 lon_grid, lat_grid = np.mgrid[lon_min:lon_max:100j, lat_min:lat_max:100j]
4. 执行插值
这里提供两种常用的插值方法,你可以根据数据情况选择:
方法一:griddata(简单易用,适合常规场景)
支持线性、三次、最近邻三种插值方式,三次插值会得到更平滑的结果:
# 用三次插值生成网格上的温度值 interp_temp = griddata( (lon_array, lat_array), # 离散点的坐标 temp_array, # 离散点的温度值 (lon_grid, lat_grid), # 目标网格 method='cubic' # 插值方法:'linear'/'cubic'/'nearest' )
方法二:Rbf(径向基函数插值,适合不规则分布的点)
如果你的站点分布很不均匀,Rbf插值效果会更好:
# 初始化径向基函数插值器 rbf_interp = Rbf(lon_array, lat_array, temp_array, function='multiquadric') # 生成网格温度值 interp_temp = rbf_interp(lon_grid, lat_grid)
5. 绘制填充等高线地图
现在把插值后的网格数据绘制成带地图底图的填充等高线:
# 设置地图投影(比如常用的PlateCarree投影,对应WGS84经纬度) fig, ax = plt.subplots( figsize=(10, 8), subplot_kw={'projection': ccrs.PlateCarree()} ) # 添加地图特征:海岸线、陆地、海洋 ax.add_feature(cfeature.COASTLINE, linewidth=0.5) ax.add_feature(cfeature.LAND, facecolor='lightgray') ax.add_feature(cfeature.OCEAN, facecolor='lightblue') # 绘制填充等高线 contour = ax.contourf( lon_grid, lat_grid, interp_temp, levels=15, # 等高线的层级数量,可调整 cmap='coolwarm', # 颜色映射,适合温度展示 transform=ccrs.PlateCarree() # 数据的投影 ) # 添加颜色条 plt.colorbar(contour, ax=ax, label='Temperature (°C)') # 添加原始站点数据作为参考(可选) ax.scatter(lon_array, lat_array, c='black', s=10, label='Original Stations') ax.legend() # 设置标题和坐标轴标签 ax.set_title('Hourly Temperature Interpolation') ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') plt.show()
注意事项
- 插值方法选择:如果追求平滑度选
cubic或Rbf的multiquadric;如果要快速插值选nearest或linear - 网格密度:
100j的数值越大,网格越密,结果越精细,但计算量也会增加 - 地图投影:如果你的数据用的是其他投影,要对应调整
cartopy.crs的参数 - NaN处理:如果插值后有NaN值,可以用
np.nan_to_num()处理,或者调整插值方法
这样你就能得到类似“Interpolated data”附件里的平滑填充等高线图啦!
内容的提问来源于stack exchange,提问作者Stephane
相关产品推荐
相关产品推荐

