爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 6215|回复: 2

[经验总结] Cartopy组图插入南海小地图

[复制链接]

新浪微博达人勋

发表于 2022-3-17 17:15:26 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
下午群里有人问到怎么在组图里插入南海小地图,试出来的方法总结如下。在公众号的很多画图教程里,南海小地图的 GeoAxes 都是通过 fig.add_axes([left, bottom, width, height]) 方法添加。为了控制小地图的大小、让它位于大地图的右下角并与边框对齐,需要手动调整 [left, bottom, width, height] 参数的值。这样不仅非常繁琐,并且在画组图时更是会让人无从下手。这里利用大地图在 figure 上的位置,根据这个参数按需求决定小地图的位置。
实现上是先用 get_position 方法获取大地图的位置,然后考虑到 GeoAxes 的 aspect_ratio 固定为 1,其经纬度范围决定好之前形状是未知的,所以等到小地图的绘图流程结束后,再等比例缩小其宽高,最后利用 set_position 方法移动到大地图的右下角。
这个方法的优点是需要调节的参数只有 shrink 一个,不再需要我们手动试错了。缺点是仅适用于方形边框的大地图,对于扇形边框恐怕还得手动设置,不知道坛友有没有别的方法。
  1. import matplotlib.pyplot as plt
  2. import matplotlib.transforms as mtransforms
  3. import cartopy.crs as ccrs

  4. def adjust_sub_axes(ax_main, ax_sub, shrink):
  5.     '''
  6.     将ax_sub调整到ax_main的右下角. shrink指定缩小倍数.
  7.     当ax_sub是GeoAxes时, 需要在其设定好范围后再使用此函数.
  8.     '''
  9.     bbox_main = ax_main.get_position()
  10.     bbox_sub = ax_sub.get_position()
  11.     # 使shrink=1时ax_main与ax_sub等宽或等高.
  12.     if bbox_sub.width > bbox_sub.height:
  13.         ratio = bbox_main.width / bbox_sub.width * shrink
  14.     else:
  15.         ratio = bbox_main.height / bbox_sub.height * shrink
  16.     wnew = bbox_sub.width * ratio
  17.     hnew = bbox_sub.height * ratio
  18.     bbox_new = mtransforms.Bbox.from_extents(
  19.         bbox_main.x1 - wnew, bbox_main.y0,
  20.         bbox_main.x1, bbox_main.y0 + hnew
  21.     )
  22.     ax_sub.set_position(bbox_new)

  23. proj = ccrs.PlateCarree()
  24. fig = plt.figure(figsize=(10, 8))
  25. subplot_kw = {'projection': proj}
  26. axes_main = fig.subplots(3, 3, subplot_kw=subplot_kw)
  27. axes_sub = fig.subplots(3, 3, subplot_kw=subplot_kw)

  28. extents_main = [75, 135, 5, 55]
  29. extents_sub = [105, 125, 0, 25]

  30. for ax_main, ax_sub in zip(axes_main.flat, axes_sub.flat):
  31.     ax_main.set_extent(extents_main, crs=proj)
  32.     ax_main.stock_img()

  33.     ax_sub.set_extent(extents_sub, crs=proj)
  34.     ax_sub.stock_img()
  35.     adjust_sub_axes(ax_main, ax_sub, shrink=0.3)

  36. plt.show()
复制代码
map.png

评分

参与人数 1金钱 +20 贡献 +2 收起 理由
付亚男 + 20 + 2 已经够可以了,还要啥自行车

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2022-3-20 22:00:07 | 显示全部楼层
太棒了
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2023-10-19 09:08:27 | 显示全部楼层
感谢lz,这是目前画九段线小图最好的方法之一了,另一个是用局部放大函数
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表