如何更改matplotlib现有轴的子图投影?

Den*_*eev 29 python matplotlib subplot cartopy

我正在尝试构造一个简单的函数,它接受一个subplot instance(matplotlib.axes._subplots.AxesSubplot)并将其投影转换为另一个投影,例如,转换为其中一个cartopy.crs.CRS投影.

这个想法看起来像这样

import cartopy.crs as ccrs
import matplotlib.pyplot as plt

def make_ax_map(ax, projection=ccrs.PlateCarree()):
    # set ax projection to the specified projection
    ...
    # other fancy formatting
    ax2.coastlines()
    ...

# Create a grid of plots
fig, (ax1, ax2) = plt.subplots(ncols=2)
# the first subplot remains unchanged
ax1.plot(np.random.rand(10))
# the second one gets another projection
make_ax_map(ax2)
Run Code Online (Sandbox Code Playgroud)

当然,我可以使用fig.add_subplot()功能:

fig = plt.figure(figsize=(10,5))
ax1 = fig.add_subplot(121)
ax1.plot(np.random.rand(10))

ax2 = fig.add_subplot(122,projection=ccrs.PlateCarree())
ax2.coastlines()
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有一个适当的matplotlib方法来改变定义的子图轴投影.不幸的是,阅读matplotlib API没有帮助.

ajd*_*son 34

您无法更改现有轴的投影,原因如下.然而,解决你的根本问题是,仅仅使用subplot_kw参数plt.subplots()的matplotlib文档中描述这里.例如,如果您希望所有子图都具有cartopy.crs.PlateCarree可以执行的投影

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

# Create a grid of plots
fig, (ax1, ax2) = plt.subplots(ncols=2, subplot_kw={'projection': ccrs.PlateCarree()})
Run Code Online (Sandbox Code Playgroud)

关于实际问题,在创建轴集时指定投影将确定您获得的轴类,这对于每种投影类型都是不同的.例如

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

ax1 = plt.subplot(311)
ax2 = plt.subplot(312, projection='polar')
ax3 = plt.subplot(313, projection=ccrs.PlateCarree())

print(type(ax1))
print(type(ax2))
print(type(ax3))
Run Code Online (Sandbox Code Playgroud)

此代码将打印以下内容

<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>
Run Code Online (Sandbox Code Playgroud)

注意每个轴实际上是不同类的实例.

  • 谢谢!只是为了确认,`projection`关键字一次确定所有子图的类,所以无法在`subplot_kw`中传递几个投影?例如,第一列的`projection ='polar'`和`plt.subplots(ncols = 2)`创建的子图集的第二列的`projection = ccrs.PlateCarree()`? (3认同)
  • `subplot_kw` 中的关键字被传递到每个轴,所以我认为你不能做你所描述的事情。`subplots` 函数是一个方便的包装器,可以满足基本用例,如果您需要更多功能,您可以使用 `add_subplot` 或类似的函数编写自己的包装器函数。 (2认同)
  • 是的,可以通过在ImageGrid(或AxesGrid)中使用axes_class关键字来实现。在cartopy的图库中有一个[example](http://scitools.org.uk/cartopy/docs/latest/examples/axes_grid_basic.html)。还有一个cartopy的PR(虽然不被接受),可用于创建自定义的[`GeoAxesGrid`类](https://github.com/SciTools/cartopy/issues/835)。 (2认同)

dom*_*ecf 10

假设有多个轴用于 2D 绘图,例如......

fig = matplotlib.pyplot.Figure()
axs = fig.subplots(3, 4) # prepare for multiple subplots
# (some plotting here)
axs[0,0].plot([1,2,3])
Run Code Online (Sandbox Code Playgroud)

...人们可以简单地摧毁其中一个并用具有 3D 投影的新的替换它:

axs[2,3].remove()
ax = fig.add_subplot(3, 4, 12, projection='3d')
ax.plot_surface(...)
Run Code Online (Sandbox Code Playgroud)

请注意,与 Python 的其余部分不同,它使用从 1add_subplot开始(而不是从 0 开始)的行列索引。

编辑:更改了我关于索引的拼写错误。