Python3.5中使用imshow()在Basemap上投影二维数组失败求助
问题原因分析
这个坑我之前帮人排查过,核心是**imshow()的默认坐标范围和Basemap的坐标轴范围完全不匹配**,导致你的二维数组被绘制到了坐标轴可视区域之外,自然看不到内容。而plot()能正常显示,是因为你传入的坐标刚好落在Basemap的坐标轴范围内。
具体来说:
- 当你创建圆柱投影的Basemap对象后,Matplotlib的坐标轴会自动适配Basemap的投影坐标范围(比如你如果设置了
llcrnrlon=-180, urcrnrlon=180, llcrnrlat=-90, urcrnrlat=90,坐标轴范围就是[-180, 180, -90, 90])。 - 但
imshow()默认是把数据从(0, 0)(左下角,取决于origin参数)到(ncols, nrows)(右上角)的范围绘制,这个区间和Basemap的坐标范围完全不重叠,所以画面一片空白。
两种解决方案
方案1:给imshow()指定extent和origin参数
直接强制imshow()的绘制范围和Basemap的坐标轴范围对齐,同时调整origin参数匹配地理数据的存储逻辑:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt import numpy as np # 创建圆柱投影Basemap m = Basemap(projection='cyl', llcrnrlon=-180, urcrnrlon=180, llcrnrlat=-90, urcrnrlat=90) m.drawcoastlines() # 绘制海岸线确认Basemap正常加载 # 生成测试二维数据(180行对应纬度,360列对应经度) data = np.random.rand(180, 360) # 关键:设置extent匹配Basemap的经纬度范围,origin='lower'对应纬度从-90到90 plt.imshow(data, extent=[-180, 180, -90, 90], origin='lower') plt.colorbar() # 添加色条方便查看数据分布 plt.show()
如果你的数据是按纬度从北到南存储的(比如第一行是90°N,最后一行是90°S),可以把origin设为'upper',同时调整extent的纬度顺序:
plt.imshow(data, extent=[-180, 180, 90, -90], origin='upper')
方案2:用pcolormesh()替代imshow()(更推荐)
pcolormesh()是Matplotlib专门为网格数据设计的绘制函数,和Basemap的兼容性更强,尤其是当你切换到非圆柱投影时。步骤是先生成经纬度网格,转换为Basemap的投影坐标,再绘制:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt import numpy as np m = Basemap(projection='cyl', llcrnrlon=-180, urcrnrlon=180, llcrnrlat=-90, urcrnrlat=90) m.drawcoastlines() # 生成经纬度网格 lon = np.linspace(-180, 180, 360) lat = np.linspace(-90, 90, 180) lon_grid, lat_grid = np.meshgrid(lon, lat) # 转换为Basemap的投影坐标(圆柱投影下和经纬度一致,其他投影必须做这步) x, y = m(lon_grid, lat_grid) data = np.random.rand(180, 360) # 使用pcolormesh绘制,shading='auto'适配不同版本的Matplotlib m.pcolormesh(x, y, data, shading='auto') plt.colorbar() plt.show()
为什么
plot()能正常工作? 假设你的plot()代码是类似这样的:
# 示例:绘制一条赤道线 lon_line = np.linspace(-180, 180, 100) lat_line = np.zeros(100) x_line, y_line = m(lon_line, lat_line) m.plot(x_line, y_line, 'r-')
这里你把经纬度转换成了Basemap的投影坐标,这些坐标刚好落在Basemap的坐标轴范围内,所以线条能正常显示。而imshow()默认没有做这个坐标对齐,所以看不到内容。
内容的提问来源于stack exchange,提问作者EP1
相关产品推荐
相关产品推荐

