如何用matplotlib和basemap将一维CSV气象数据绘制成数值着色地图?
解决一维气象数据在Basemap上的可视化问题
一、先搞定散点图的颜色映射
你之前用map.scatter没实现颜色对应,其实是没用到c参数——直接把数据列表传给c,再指定颜色映射(colormap)就能实现低温蓝、高温红的效果。直接上代码:
import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import pandas as pd # 读取CSV数据 df = pd.read_csv('your_data.csv') lons = df['longitude'].values lats = df['latitude'].values temp_data = df['water_temp'].values # 替换成你的目标数据列名 # 初始化Basemap(可根据需求调整投影和范围) m = Basemap(projection='merc', llcrnrlat=-80, urcrnrlat=80, llcrnrlon=-180, urcrnrlon=180, resolution='l') # 转换经纬度为地图投影坐标 x, y = m(lons, lats) # 绘制带颜色映射的散点图 scatter = m.scatter(x, y, c=temp_data, cmap='coolwarm', s=10, alpha=0.8) # 添加颜色条并标注 plt.colorbar(scatter, label='水温(℃)') # 绘制基础地图要素 m.drawcoastlines() m.drawcountries() plt.title('全球水温分布') plt.show()
这里s控制点的大小,alpha控制透明度,cmap='coolwarm'刚好是蓝到红的渐变,完美匹配你的需求。
二、实现类似pcolormesh的填色效果(一维转二维)
如果想要连续的填色区域而不是离散点,就得把一维数据转成二维网格。核心是用插值把零散的点数据填充到规则网格上,步骤如下:
1. 生成规则网格点
先定义你想要的网格分辨率,比如按0.5度间隔生成全球范围的经纬度网格:
import numpy as np from scipy.interpolate import griddata # 生成规则网格的经纬度序列 grid_lon = np.linspace(-180, 180, 720) # 0.5度间隔,共720个点 grid_lat = np.linspace(-80, 80, 320) # 转换为网格矩阵 grid_x, grid_y = np.meshgrid(grid_lon, grid_lat) # 把网格坐标转换为Basemap投影坐标 grid_mx, grid_my = m(grid_x, grid_y)
2. 插值填充数据
用griddata把一维的点数据插值到网格上,可选三种插值方法:
nearest:最近邻插值,速度最快,适合离散点密集的场景linear:线性插值,平滑度中等,平衡速度和效果cubic:三次插值,最平滑但计算耗时最长
# 执行插值 grid_temp = griddata((lons, lats), temp_data, (grid_lon, grid_lat), method='linear')
3. 用pcolormesh绘制填色图
# 绘制连续填色图 m.pcolormesh(grid_mx, grid_my, grid_temp, cmap='coolwarm', alpha=0.7) # 添加颜色条和地图要素 plt.colorbar(label='水温(℃)') m.drawcoastlines() m.drawcountries() plt.title('全球水温分布(插值填色)') plt.show()
三、实用注意事项
- 先处理数据缺失值:
df = df.dropna(subset=['longitude', 'latitude', 'water_temp']),避免插值报错 - 如果数据点稀疏,
linear/cubic插值可能出现NaN空白区域,可以先用nearest插值填充空白,再叠加其他插值结果 - Basemap已停止维护,若后续换工具,
cartopy的实现逻辑和上述完全通用
内容的提问来源于stack exchange,提问作者Tmpecho
相关产品推荐
相关产品推荐

