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

时间:2022-06-27 23:41:06

I'm trying to construct a simple function that takes a subplot instance (matplotlib.axes._subplots.AxesSubplot) and transforms its projection to another projection, for example, to one of the cartopy.crs.CRS projections.

我正在尝试构建一个简单的函数,它接受一个子图实例(matplotlib.axes._subplots.AxesSubplot)并将其投影转换为另一个投影,例如,转换为cartopy.crs.CRS投影之一。

The idea looks something like this

这个想法看起来像这样

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)

Of course, I can just use fig.add_subplot() function:

当然,我可以使用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()

but I was wondering if there is a proper matplotlib method to change a subplot axis projection after it was defined. Reading matplotlib API didn't help unfortunately.

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

1 个解决方案

#1


22  

You can't change the projection of an existing axes, the reason is given below. However the solution to your underlying problem is simply to use the subplot_kw argument to plt.subplots() described in the matplotlib documentation here. For example, if you wanted all your subplots to have the cartopy.crs.PlateCarree projection you could do

您无法更改现有轴的投影,原因如下。但是,您的基本问题的解决方案只是使用matplotlib文档中描述的plt.subplots()的subplot_kw参数。例如,如果您希望所有子图都具有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()})

Regarding the actual question, specifying a projection when you create an axes set determines the axes class you get, which is different for each projection type. For example

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

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))

This code will print the following

此代码将打印以下内容

<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>

Notice how each axes is actually an instance of a different class.

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

#1


22  

You can't change the projection of an existing axes, the reason is given below. However the solution to your underlying problem is simply to use the subplot_kw argument to plt.subplots() described in the matplotlib documentation here. For example, if you wanted all your subplots to have the cartopy.crs.PlateCarree projection you could do

您无法更改现有轴的投影,原因如下。但是,您的基本问题的解决方案只是使用matplotlib文档中描述的plt.subplots()的subplot_kw参数。例如,如果您希望所有子图都具有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()})

Regarding the actual question, specifying a projection when you create an axes set determines the axes class you get, which is different for each projection type. For example

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

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))

This code will print the following

此代码将打印以下内容

<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>

Notice how each axes is actually an instance of a different class.

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