在 matplotlib 图上嵌入小地图(cartopy)
embed small map (cartopy) on matplotlib figure
# imports
from collections import namedtuple
import numpy as np
import xarray as xr
import shapely
import cartopy
我的数据是这样的。
我有一个感兴趣的区域(此处定义为 all_region
)。我有一个 xr.DataArray
包含我的变量。
我想对 select 一个 PIXEL(纬度、经度对)执行此操作,并在线图的一角绘制一张小地图,显示此处的像素所在位置。
Region = namedtuple('Region',field_names=['region_name','lonmin','lonmax','latmin','latmax'])
all_region = Region(
region_name="all_region",
lonmin = 32.6,
lonmax = 51.8,
latmin = -5.0,
latmax = 15.2,
)
data = np.random.normal(0,1,(12, 414, 395))
lats = np.linspace(-4.909738, 15.155708, 414)
lons = np.linspace(32.605801, 51.794488, 395)
months = np.arange(1,13)
da = xr.DataArray(data, coords=[months, lats, lons], dims=['month','lat','lon'])
这些是我需要修复的函数才能使用插入轴。
我有这些函数可以根据 xarray 对象绘制我的时间序列,以及纬度、经度点的位置。
def plot_location(region):
""" use cartopy to plot the region (defined as a namedtuple object)
"""
lonmin,lonmax,latmin,latmax = region.lonmin,region.lonmax,region.latmin,region.latmax
fig = plt.figure()
ax = fig.gca(projection=cartopy.crs.PlateCarree())
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.set_extent([lonmin, lonmax, latmin, latmax])
return fig, ax
def select_pixel(ds, loc):
""" (lat,lon) """
return ds.sel(lat=loc[1],lon=loc[0],method='nearest')
def turn_tuple_to_point(loc):
""" (lat,lon) """
from shapely.geometry.point import Point
point = Point(loc[1], loc[0])
return point
def add_point_location_to_map(point, ax, color=(0,0,0,1), **kwargs):
""" """
ax.scatter(point.x,
point.y,
transform=cartopy.crs.PlateCarree(),
c=[color],
**kwargs)
return
这里我画图
# choose a lat lon location that want to plot
loc = (2.407,38.1)
# 1. plot the TIME SERIES FOR THE POINT
fig,ax = plt.subplots()
pixel_da = select_pixel(da, loc)
pixel_da.plot.line(ax=ax, marker='o')
# 2. plot the LOCATION for the point
fig,ax = plot_location(all_region)
point = turn_tuple_to_point(loc)
add_point_location_to_map(point, ax)
我有绘制区域的功能,但我想把它放在图形一角的轴上!像这样:
我该怎么做?我看过 inset_locator
method 但据我所知 mpl_toolkits.axes_grid1.parasite_axes.AxesHostAxes
无法分配投影,这是 cartopy 所必需的。
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
proj=cartopy.crs.PlateCarree
axins = inset_axes(ax, width="20%", height="20%", loc=2, projection=proj)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-162-9b5fd4f34c3e> in <module>
----> 1 axins = inset_axes(ax, width="20%", height="20%", loc=2, projection=proj)
TypeError: inset_axes() got an unexpected keyword argument 'projection'
我没有安装 cartopy
来直接测试它,但我相信您可以通过直接手动创建插图轴来避免这个问题,using fig.add_axes()
。如果要指定其相对于主轴的位置,可以使用主轴 get_position()
.
返回的信息轻松计算 rect
参数
例如:
pad = 0.05
w = 0.4
h = 0.25
fig, ax = plt.subplots()
a = ax.get_position()
ax2 = fig.add_axes([a.x1-(w+pad)*a.width,a.y1-(h+pad)*a.height,w*a.width,h*a.height], projection="hammer")
mpl_toolkits.axes_grid1.inset_locator.inset_axes
没有 projection
关键字。它只提供了一个 axes_class
参数。现在人们可能会想直接为该参数提供 cartopy.mpl.geoaxes.GeoAxes
,但这会丢失实际使用的投影。因此,另外需要通过 axes_kwargs
参数设置投影。
inset_axes(..., axes_class=cartopy.mpl.geoaxes.GeoAxes,
axes_kwargs=dict(map_projection=cartopy.crs.PlateCarree()))
完整示例:
import cartopy
import cartopy.mpl.geoaxes
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax = plt.subplots()
ax.plot([4,5,3,1,2])
axins = inset_axes(ax, width="40%", height="40%", loc="upper right",
axes_class=cartopy.mpl.geoaxes.GeoAxes,
axes_kwargs=dict(map_projection=cartopy.crs.PlateCarree()))
axins.add_feature(cartopy.feature.COASTLINE)
plt.show()
# imports
from collections import namedtuple
import numpy as np
import xarray as xr
import shapely
import cartopy
我的数据是这样的。
我有一个感兴趣的区域(此处定义为 all_region
)。我有一个 xr.DataArray
包含我的变量。
我想对 select 一个 PIXEL(纬度、经度对)执行此操作,并在线图的一角绘制一张小地图,显示此处的像素所在位置。
Region = namedtuple('Region',field_names=['region_name','lonmin','lonmax','latmin','latmax'])
all_region = Region(
region_name="all_region",
lonmin = 32.6,
lonmax = 51.8,
latmin = -5.0,
latmax = 15.2,
)
data = np.random.normal(0,1,(12, 414, 395))
lats = np.linspace(-4.909738, 15.155708, 414)
lons = np.linspace(32.605801, 51.794488, 395)
months = np.arange(1,13)
da = xr.DataArray(data, coords=[months, lats, lons], dims=['month','lat','lon'])
这些是我需要修复的函数才能使用插入轴。
我有这些函数可以根据 xarray 对象绘制我的时间序列,以及纬度、经度点的位置。
def plot_location(region):
""" use cartopy to plot the region (defined as a namedtuple object)
"""
lonmin,lonmax,latmin,latmax = region.lonmin,region.lonmax,region.latmin,region.latmax
fig = plt.figure()
ax = fig.gca(projection=cartopy.crs.PlateCarree())
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.set_extent([lonmin, lonmax, latmin, latmax])
return fig, ax
def select_pixel(ds, loc):
""" (lat,lon) """
return ds.sel(lat=loc[1],lon=loc[0],method='nearest')
def turn_tuple_to_point(loc):
""" (lat,lon) """
from shapely.geometry.point import Point
point = Point(loc[1], loc[0])
return point
def add_point_location_to_map(point, ax, color=(0,0,0,1), **kwargs):
""" """
ax.scatter(point.x,
point.y,
transform=cartopy.crs.PlateCarree(),
c=[color],
**kwargs)
return
这里我画图
# choose a lat lon location that want to plot
loc = (2.407,38.1)
# 1. plot the TIME SERIES FOR THE POINT
fig,ax = plt.subplots()
pixel_da = select_pixel(da, loc)
pixel_da.plot.line(ax=ax, marker='o')
# 2. plot the LOCATION for the point
fig,ax = plot_location(all_region)
point = turn_tuple_to_point(loc)
add_point_location_to_map(point, ax)
我有绘制区域的功能,但我想把它放在图形一角的轴上!像这样:
我该怎么做?我看过 inset_locator
method 但据我所知 mpl_toolkits.axes_grid1.parasite_axes.AxesHostAxes
无法分配投影,这是 cartopy 所必需的。
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
proj=cartopy.crs.PlateCarree
axins = inset_axes(ax, width="20%", height="20%", loc=2, projection=proj)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-162-9b5fd4f34c3e> in <module>
----> 1 axins = inset_axes(ax, width="20%", height="20%", loc=2, projection=proj)
TypeError: inset_axes() got an unexpected keyword argument 'projection'
我没有安装 cartopy
来直接测试它,但我相信您可以通过直接手动创建插图轴来避免这个问题,using fig.add_axes()
。如果要指定其相对于主轴的位置,可以使用主轴 get_position()
.
rect
参数
例如:
pad = 0.05
w = 0.4
h = 0.25
fig, ax = plt.subplots()
a = ax.get_position()
ax2 = fig.add_axes([a.x1-(w+pad)*a.width,a.y1-(h+pad)*a.height,w*a.width,h*a.height], projection="hammer")
mpl_toolkits.axes_grid1.inset_locator.inset_axes
没有 projection
关键字。它只提供了一个 axes_class
参数。现在人们可能会想直接为该参数提供 cartopy.mpl.geoaxes.GeoAxes
,但这会丢失实际使用的投影。因此,另外需要通过 axes_kwargs
参数设置投影。
inset_axes(..., axes_class=cartopy.mpl.geoaxes.GeoAxes,
axes_kwargs=dict(map_projection=cartopy.crs.PlateCarree()))
完整示例:
import cartopy
import cartopy.mpl.geoaxes
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax = plt.subplots()
ax.plot([4,5,3,1,2])
axins = inset_axes(ax, width="40%", height="40%", loc="upper right",
axes_class=cartopy.mpl.geoaxes.GeoAxes,
axes_kwargs=dict(map_projection=cartopy.crs.PlateCarree()))
axins.add_feature(cartopy.feature.COASTLINE)
plt.show()