You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带地理地图的绘图设置正方形纵横比

解决6×6英寸正方形画布的地图散点图绘制问题

我尝试在世界地图上绘制散点图,希望将绘图设置为6英寸×6英寸的正方形。这需要调整地图的纵横比,但x轴最大值与最小值的差和y轴的差值不相等,增加了实现难度。以下是我目前的代码及生成的图。

代码生成的绘图

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.colors import Normalize
import numpy as np
import geopandas as gpd
#====================================================================
y_pred = np.random.random((389, 28, 14))
world = gpd.read_file("ne_110m_land/ne_110m_land.shp")

min_lat = 19.25
max_lat = -5.75
min_lon = 18.5
max_lon = 31.5

lat = np.tile(np.arange(max_lat, min_lat-0.5, -0.5).reshape(-1, 1), (1, int(max_lon - min_lon+1)))
lon = np.tile(np.arange(min_lon, max_lon+1, 1).reshape(1, -1), (int((max_lat - min_lat)*2)+1, 1))

#====================================================================
''' Plot map '''
norm = Normalize(vmin=0, vmax=max(y_pred.ravel()))

fig_map, ax_map = plt.subplots(1,1,figsize=(6,6), dpi=100, tight_layout=True)
fig_map.set_size_inches(6, 6)

map = ax_map.scatter(x=lon, y=lat, c=y_pred[date_idx], s=4, cmap='bwr', norm=norm)

world.plot(ax=ax_map, facecolor='none', edgecolor='black', linewidth=.5, alpha=1)

divider = make_axes_locatable(ax_map)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(map, cax=cax)

ax_map.set_xlim(-20, 60)
ax_map.set_ylim(-20, 20)
ax_map.set_aspect('equal')

plt.show()
fig_map.savefig('test.png', bbox_inches='tight', pad_inches=0)

问题根源

当前代码中ax_map.set_aspect('equal')强制坐标轴等比例,但x轴跨度为80(-20到60)、y轴跨度为40(-20到20),比例不匹配6×6的正方形画布,导致地图被挤压变形,无法填满画布。

修改方案

方案1:适配画布比例(允许地图轻微变形)

去掉强制等比例设置,让Matplotlib自动适配6×6画布的尺寸,同时完整显示目标区域:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.colors import Normalize
import numpy as np
import geopandas as gpd

y_pred = np.random.random((389, 28, 14))
world = gpd.read_file("ne_110m_land/ne_110m_land.shp")

min_lat = 19.25
max_lat = -5.75
min_lon = 18.5
max_lon = 31.5

lat = np.tile(np.arange(max_lat, min_lat-0.5, -0.5).reshape(-1, 1), (1, int(max_lon - min_lon+1)))
lon = np.tile(np.arange(min_lon, max_lon+1, 1).reshape(1, -1), (int((max_lat - min_lat)*2)+1, 1))

# 绘图部分
norm = Normalize(vmin=0, vmax=max(y_pred.ravel()))

# 仅设置一次画布尺寸即可
fig_map, ax_map = plt.subplots(1,1,figsize=(6,6), dpi=100, tight_layout=True)

# 替换未定义的date_idx为具体索引,示例用0
map = ax_map.scatter(x=lon, y=lat, c=y_pred[0], s=4, cmap='bwr', norm=norm)

world.plot(ax=ax_map, facecolor='none', edgecolor='black', linewidth=.5, alpha=1)

divider = make_axes_locatable(ax_map)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(map, cax=cax)

ax_map.set_xlim(-20, 60)
ax_map.set_ylim(-20, 20)
# 取消强制等比例,自动适配画布
ax_map.set_aspect('auto')

plt.show()
fig_map.savefig('test.png', bbox_inches='tight', pad_inches=0)

方案2:保持地理比例(无变形)

调整x轴范围,让x/y轴跨度比等于画布宽高比(1:1),同时确保目标区域完整显示:

# ... 其他代码不变
ax_map.set_xlim(0, 40)  # 跨度40,和y轴跨度一致
ax_map.set_ylim(-20, 20)
ax_map.set_aspect('equal')
# ... 其他代码不变

内容的提问来源于stack exchange,提问作者Innocuous Rift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:06