带联合直方图的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
相关产品推荐
相关产品推荐

