- 积分
- 25796
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2017-9-4
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 灭火器 于 2022-1-13 11:47 编辑
Cartopy 中的地图,即 GeoAxes,因为 aspect_ratio 固定为 1,所以在 add_axes 后其实际形状位置会发生变化,导致不符预期(可见 Cartopy 系列:对入门教程的补充)。因此 GeoAxes 与普通的 Axes 放在一起排版时总是效果很差,以至于需要手动对齐。这里介绍一个自制的函数,功能是根据已有的一个(组)Axes 的位置,新建一个等高或等宽的 Axes。代码如下
- import numpy as np
- import matplotlib.transforms as mtransforms
- def add_equal_axes(ax, loc, pad, width):
- '''
- 在原有的Axes旁新添一个等高或等宽的Axes并返回该对象.
- Parameters
- ----------
- ax : Axes or array_like of Axes
- 原有的Axes,也可以为一组Axes构成的数组.
- loc : {'left', 'right', 'bottom', 'top'}
- 新Axes相对于旧Axes的位置.
- pad : float
- 新Axes与旧Axes的间距.
- width: float
- 当loc='left'或'right'时,width表示新Axes的宽度.
- 当loc='bottom'或'top'时,width表示新Axes的高度.
- Returns
- -------
- ax_new : Axes
- 新Axes对象.
- '''
- # 无论ax是单个还是一组Axes,获取ax的大小位置.
- axes = np.atleast_1d(ax).ravel()
- bbox = mtransforms.Bbox.union([ax.get_position() for ax in axes])
- # 决定新Axes的大小位置.
- if loc == 'left':
- x0_new = bbox.x0 - pad - width
- x1_new = x0_new + width
- y0_new = bbox.y0
- y1_new = bbox.y1
- elif loc == 'right':
- x0_new = bbox.x1 + pad
- x1_new = x0_new + width
- y0_new = bbox.y0
- y1_new = bbox.y1
- elif loc == 'bottom':
- x0_new = bbox.x0
- x1_new = bbox.x1
- y0_new = bbox.y0 - pad - width
- y1_new = y0_new + width
- elif loc == 'top':
- x0_new = bbox.x0
- x1_new = bbox.x1
- y0_new = bbox.y1 + pad
- y1_new = y0_new + width
- # 创建新Axes.
- fig = axes[0].get_figure()
- bbox_new = mtransforms.Bbox.from_extents(x0_new, y0_new, x1_new, y1_new)
- ax_new = fig.add_axes(bbox_new)
- return ax_new
复制代码 add_equal_axes 函数的常见的使用场景为:已有一个 ax,在这个 ax 的右边新建一个等高的 cax,以便于之后作为 colorbar 使用。ax 有好几个也能正确处理,ax 是地图也没有影响。有了这个函数,就不再需要反反复复调节 add_axes 里的参数了。
也许有人会说,灵活的组图可以通过 matplotlib.gridspec.GridSpec 类进行设置,但它对于 GeoAxes 的效果不是很好。并且 GridSpec 的思路是在最开始就规划好组图网格,而 add_equal_axes 的思路是像搭积木一样,需要什么子图就随时添加。下面是一个例子
- import matplotlib.pyplot as plt
- import cartopy.crs as ccrs
- def add_center_text(ax, num):
- ax.text(
- 0.5, 0.5, num, fontsize='large', fontweight='bold', color='C3',
- ha='center', va='center', transform=ax.transAxes
- )
- fig = plt.figure()
- ax1 = fig.add_axes([0.1, 0.5, 0.4, 0.4], projection=ccrs.PlateCarree())
- ax1.set_global()
- ax1.stock_img()
- add_center_text(ax1, 1)
- ax2 = add_equal_axes(ax1, loc='right', pad=0.1, width=0.1)
- add_center_text(ax2, 2)
- ax3 = add_equal_axes([ax1, ax2], loc='bottom', pad=0.1, width=0.1)
- add_center_text(ax3, 3)
- ax4 = add_equal_axes(ax3, loc='bottom', pad=0.1, width=0.1)
- add_center_text(ax4, 4)
- ax5 = add_equal_axes([ax1, ax2, ax3, ax4], loc='right', pad=0.1, width=0.1)
- add_center_text(ax5, 5)
- plt.show()
复制代码
如果要把这个函数结合 plt.subplots 进行使用,建议先用 fig.subplots_adjust 调节已有组图的间隔。
|
|