将子图嵌入到Cartopy地图中

问题描述

我想将子图画布嵌入到cartopy投影地图中。我编写了这段代码,以使用矩形显示预期的结果:

#%%
import numpy as np
import cartopy as cr
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from cartopy.io import shapereader
import geopandas

resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution,category,name)
# read the shapefile using geopandas
df = geopandas.read_file(shpfilename)
# read the country borders
usa = df.loc[df['ADMIN'] == 'United States of America']['geometry'].values[0]
can = df.loc[df['ADMIN'] == 'Canada']['geometry'].values[0]
central_lon,central_lat = -80,60
extent = [-85,-55,40,62]
# ax = plt.axes(projection=ccrs.Orthographic(central_lon,central_lat))

#Golden ratio
phi = 1.618033987
h = 7
w = phi*h

fig = plt.figure(figsize=(w,h))
ax = fig.add_subplot(1,1,projection=ccrs.PlateCarree())
#Set map extent
ax.set_extent(extent)
ax.set_xticks(np.linspace(extent[0],extent[1],11))
ax.set_yticks(np.linspace(extent[2],extent[3],6))
ax.add_geometries(usa,crs=ccrs.PlateCarree(),facecolor='none',edgecolor='k')
# ax.gridlines()

ax.coastlines(resolution='50m')


nx,ny = 7,6

#Begin firts rectangle
xi = extent[0] + 0.5
yi = extent[2] + 0.5

x,y = xi,yi
#Loop for create the plots grid
for i in range(nx):
    for j in range(ny):
        #Inner rect height
        in_h = 2.8
        #Draw the rect
        rect = ax.add_patch(mpatches.Rectangle(xy=[x,y],width=phi*in_h,height=in_h,facecolor='blue',alpha=0.2,transform=ccrs.PlateCarree()))
        #Get vertex of the drawn rectangle
        verts = rect.get_path().vertices
        trans = rect.get_patch_transform()
        points = trans.transform(verts)
        #Refresh rectangle coordinates
        x += (points[1,0]-points[0,0]) + 0.2
        if j == ny-1:
            x = xi
    y += (points[2,1]-points[1,1]) + 0.2
    
    
# print(points)

fig.tight_layout()
fig.savefig('figure.pdf',format='pdf',dpi=90)
plt.show()

此例程将打印此图

Expected grid

我正在寻找一种嵌入与图中每个矩形匹配的图的方法。我尝试使用fig.add_axes,但无法使迷你画布与实际矩形匹配。

解决方法

由于建议您使用inset_axes将轴嵌入父轴中,请参阅文档here

我编写了简单的代码来演示其工作原理。显然,您需要对inset_axes的位置和大小进行一些调整,以实现所需的输出,但是我认为我的琐碎实现确实不错。

所有创建的轴实例都存储在列表中,以便以后可以访问。

import matplotlib.pyplot as plt
import numpy as np
fig,ax = plt.subplots()
axis = []
x = np.linspace(-85,-55)
y = np.linspace(40,62)
ax.plot(x,y)

offset_l = 0.05
offset_h = 0.12
num_x = 6
num_y = 7
xs = np.linspace(offset_l,1-offset_h,num_x)
ys = np.linspace(offset_l,num_y)

for k in range(num_x):
    for j in range(num_y):
        ax_ins = ax.inset_axes([xs[k],ys[j],0.1,0.1])
        ax_ins.axhspan(0,1,color='tab:blue',alpha=0.2)
        axis.append(ax_ins)

Output Figure

或者,您也可以使用数据坐标指定inset_axes位置,为此,您必须将方法中的kwarg transform设置为transform=ax.transData,另请参见下面的代码。

import matplotlib.pyplot as plt
import numpy as np

#Golden ratio
phi = 1.618033987
h = 7
w = phi*h

fig,ax = plt.subplots(figsize=(w,h))
axis = []
x = np.linspace(-85,y)

offset_l = 0.05
offset_h = 0.12
num_x = 6
num_y = 7

fig.tight_layout()
extent = [-85,-55,40,62]
xi = extent[0] + 0.5
yi = extent[2] + 0.5
in_h = 2.8
in_w = phi * 2.8
spacing = 0.4

for k in range(num_x):
    for j in range(num_y):
        ax_ins = ax.inset_axes([xi+k*(in_w + phi*spacing),yi+j*(in_h + spacing),in_w,in_h],transform=ax.transData)
        ax_ins.axhspan(0,alpha=0.2)
        axis.append(ax_ins)
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...