如何更改现有轴的 matplotlib 子图投影?
How do I change matplotlib's subplot projection of an existing axis?
我正在尝试构建一个简单的函数,它接受一个子图实例 (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)
当然可以直接用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()
但我想知道是否有适当的 matplotlib
方法来更改已定义的子图轴投影 。不幸的是,阅读 matplotlib API 没有帮助。
您不能更改现有轴的投影,原因如下。但是,解决您的潜在问题的方法是简单地使用 matplotlib 文档 here 中描述的 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()})
关于实际问题,在创建轴集时指定投影决定了您获得的轴 class,这对于每种投影类型都是不同的。例如
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))
此代码将打印以下内容
<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>
注意每个轴实际上是不同 class 的实例。
关注这个问题的答案:
我发现了一个在创建斧头后改变它的投影的技巧,这似乎至少在下面的简单示例中有效,但我不知道这个解决方案是否是最好的方法
from matplotlib.axes import Axes
from matplotlib.projections import register_projection
class CustomAxe(Axes):
name = 'customaxe'
def plotko(self, x):
self.plot(x, 'ko')
self.set_title('CustomAxe')
register_projection(CustomAxe)
if __name__ == '__main__':
import matplotlib.pyplot as plt
fig = plt.figure()
## use this syntax to create a customaxe directly
# ax = fig.add_subplot(111, projection="customaxe")
## change the projection after creation
ax = plt.gca()
ax.__class__ = CustomAxe
ax.plotko(range(10))
plt.show()
假设有多个轴用于 2D 绘图,例如...
fig = matplotlib.pyplot.Figure()
axs = fig.subplots(3, 4) # prepare for multiple subplots
# (some plotting here)
axs[0,0].plot([1,2,3])
...可以简单地摧毁其中一个并用具有 3D 投影的新的替换它:
axs[2,3].remove()
ax = fig.add_subplot(3, 4, 12, projection='3d')
ax.plot_surface(...)
请注意,与 Python 的其余部分不同,add_subplot
使用 row-column 索引从 从 1 开始(而不是从 0 开始)。
编辑:更改了我关于索引的拼写错误。
我正在尝试构建一个简单的函数,它接受一个子图实例 (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)
当然可以直接用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()
但我想知道是否有适当的 matplotlib
方法来更改已定义的子图轴投影 。不幸的是,阅读 matplotlib API 没有帮助。
您不能更改现有轴的投影,原因如下。但是,解决您的潜在问题的方法是简单地使用 matplotlib 文档 here 中描述的 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()})
关于实际问题,在创建轴集时指定投影决定了您获得的轴 class,这对于每种投影类型都是不同的。例如
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))
此代码将打印以下内容
<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>
注意每个轴实际上是不同 class 的实例。
关注这个问题的答案:
我发现了一个在创建斧头后改变它的投影的技巧,这似乎至少在下面的简单示例中有效,但我不知道这个解决方案是否是最好的方法
from matplotlib.axes import Axes
from matplotlib.projections import register_projection
class CustomAxe(Axes):
name = 'customaxe'
def plotko(self, x):
self.plot(x, 'ko')
self.set_title('CustomAxe')
register_projection(CustomAxe)
if __name__ == '__main__':
import matplotlib.pyplot as plt
fig = plt.figure()
## use this syntax to create a customaxe directly
# ax = fig.add_subplot(111, projection="customaxe")
## change the projection after creation
ax = plt.gca()
ax.__class__ = CustomAxe
ax.plotko(range(10))
plt.show()
假设有多个轴用于 2D 绘图,例如...
fig = matplotlib.pyplot.Figure()
axs = fig.subplots(3, 4) # prepare for multiple subplots
# (some plotting here)
axs[0,0].plot([1,2,3])
...可以简单地摧毁其中一个并用具有 3D 投影的新的替换它:
axs[2,3].remove()
ax = fig.add_subplot(3, 4, 12, projection='3d')
ax.plot_surface(...)
请注意,与 Python 的其余部分不同,add_subplot
使用 row-column 索引从 从 1 开始(而不是从 0 开始)。
编辑:更改了我关于索引的拼写错误。