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

带联合直方图的Basemap绘制:调整直方图轴与底图轴匹配的方法咨询

带联合直方图的Basemap绘制:调整直方图轴与底图轴匹配的方法咨询

我最近在用Basemap做带联合直方图的地图可视化,写了下面这段代码,但遇到个问题——没法用sharex/sharey选项来调整直方图的尺寸,导致直方图的轴和底图的轴没法对齐(我猜是Basemap的投影机制搞的鬼)。有没有大佬知道怎么调整顶部直方图的x轴,让它和底图的x轴范围匹配,同时让右侧直方图的y轴和底图的y轴范围匹配呀?

我的代码如下:

import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np

plt.figure(figsize=(8, 8))

gs = plt.GridSpec(3, 3)

ax_main = plt.subplot(gs[1:3, :2])
ax_lon = plt.subplot(gs[0, :2])
ax_lat = plt.subplot(gs[1:3, 2])

m = Basemap(projection='merc', resolution='i', llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat,
            urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat, ax=ax_main)

try:
    m.drawcoastlines(linewidth=0.5)
except:
    pass

m.drawcountries()
m.drawmapboundary()

lon_range = urcrnrlon - llcrnrlon
lat_range = urcrnrlat - llcrnrlat

lat_interval = round(0.2 * lat_range, 2)
lon_interval = round(0.2 * lon_range, 2)

parallels = np.arange(-90, 90, lat_interval)
meridians = np.arange(-180, 180, lon_interval)

m.drawparallels(parallels, labels=[0, 1, 0, 0], fontsize=8, dashes=[1, 5])
m.drawmeridians(meridians, labels=[0, 0, 1, 0], fontsize=8, dashes=[1, 5])

m.fillcontinents(color='#F0F0F0', lake_color='#F0F0F0')

x1, y1 = m(LON_1, LAT_1)
x2, y2 = m(LON_2, LAT_2)

ax_main.scatter(x1, y1, c='steelblue', alpha=.8,  s=8, label='Data 1')
ax_main.scatter(x2, y2, c='red', alpha=.8, s=8, label='Data 2')

ax_main.set_xlabel('Longitude', fontsize=12, labelpad=10)
ax_main.set_ylabel('Latitude', fontsize=12, labelpad=10)
ax_main.legend(loc='upper right')

# Histogram of longitude
ax_lon.hist(LON_1, bins=20, histtype='step', density=True, color='steelblue',
            align='mid', label='Data 1')
ax_lon.hist(LON_2, bins=20, histtype='step', density=True, color='red',
            align='mid', label='Data2')
ax_lon.set_xticks([])
ax_lon.set_yticks([])

# Histogram of latitude
ax_lat.hist(LAT_1, bins=20, histtype='step', density=True, color='steelblue', align='mid',
            orientation='horizontal', label='Data 1')
ax_lat.hist(LAT_2, bins=20, histtype='step', density=True, color='red', align='mid',
            orientation='horizontal', label='Data 2')

ax_lat.set_yticks([])
ax_lat.set_xticks([])

plt.tight_layout()
plt.show()

问题补充:

我试过用sharex/sharey来关联轴,但这样直方图就显示不正常了,推测是Basemap的投影机制导致的冲突。


解决方案(手动同步轴范围)

其实这个问题核心是Basemap会把经纬度转换成投影后的平面坐标,而sharex/sharey是基于原始坐标轴的线性关联,自然会出问题。咱们可以手动提取底图的轴范围,直接应用到直方图上:

  • 给顶部经度直方图同步x轴范围:在绘制完底图的内容后,添加一行代码,把ax_main的x轴范围赋值给ax_lon:
    ax_lon.set_xlim(ax_main.get_xlim())
    
  • 给右侧纬度直方图同步y轴范围:同样添加一行代码,把ax_main的y轴范围赋值给ax_lat:
    ax_lat.set_ylim(ax_main.get_ylim())
    

修改后的关键代码片段

把这两行代码放在绘制完底图散点、设置完底图标签之后,直方图绘制之前即可:

# 底图相关设置完成后添加
ax_lon.set_xlim(ax_main.get_xlim())
ax_lat.set_ylim(ax_main.get_ylim())

# 然后再绘制直方图...

这样调整后,顶部直方图的x轴范围就会和底图的投影x轴完全匹配,右侧直方图的y轴范围也会和底图的投影y轴对齐,完美解决轴不匹配的问题~

备注:内容来源于stack exchange,提问作者Roland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 07:04:51