我想创建一次Basemap实例(因为它很昂贵),然后重复使用,例如,不同的contourf()覆盖。
为了澄清,我需要(底图+轮廓1)和(底图+轮廓2),而不是(底图+轮廓1 +轮廓2),这是this question的内容。
有一些示例here和here(同一作者的回复,相隔五年!),但我无法获得简单的可重复使用的代码段。
根据second example,我的代码结构如下:
%matplotlib inline
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
def get_basemap():
fig = plt.figure('Background')
fig.add_subplot(111)
map_ = Basemap(resolution='c', projection='stere', width=12000000,
height=8000000, lat_ts=50, lat_0=50, lon_0=260.)
map_.drawcoastlines()
map_.drawmapboundary()
map_.fillcontinents(zorder=-1)
fig.canvas.draw()
background = fig.canvas.copy_from_bbox(fig.bbox)
return map_, background
def plot_thing1(map_, background, lats, lons, data):
fig = plt.figure('Contourf', frameon=False)
fig.add_subplot(111, frameon=False)
fig.canvas.restore_region(background)
x, y = map_(*np.meshgrid(lons, lats))
map_.contourf(x, y, data, zorder=0)
fig.show()
def plot_thing2(map_, background, lats, lons, ugrd, vgrd):
fig = plt.figure('Quiver', frameon=False)
fig.add_subplot(111, frameon=False)
fig.canvas.restore_region(background)
x, y = map_(*np.meshgrid(lons, lats))
map_.quiver(x, y, ugrd, vgrd, zorder=0)
fig.show()
min_lat, max_lat = 20, 70
min_lon, max_lon = 210, 310
lats = np.arange(min_lat, max_lat)
lons = np.arange(min_lon, max_lon)
shape = len(lats), len(lons)
# Run this once to get a reusable basemap
map_, background = get_basemap()
# Random data for thing1
data = np.random.rand(*shape)
plot_thing1(map_, background, lats, lons, data)
# Random data for thing2
ugrd, vgrd = np.random.rand(*shape), np.random.rand(*shape)
plot_thing2(map_, background, lats, lons, ugrd, vgrd)
但plot_thing1()
生成了两个"图#34;一个是底图背景,另一个是轮廓,另一个是轮廓(而不是在一个图中叠加在底图上的轮廓)。并且plot_thing2()
只会产生箭数。
如何让它们出现在同一个地块上? (并在plot_thing1()
,plot_thing2()
等中重复使用底图。这可能与附加到错误的活动图/子图/轴上的内容有关,但我无法理解围绕Basemap()
如何适应matplotlib
层次结构。
答案 0 :(得分:2)
以下保存三张图像,单独的背景,带有等高线图的背景和带箭袋的背景:
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
def get_basemap():
fig = plt.figure('Background')
fig.add_subplot(111)
map_ = Basemap(resolution='c', projection='stere', width=12000000,
height=8000000, lat_ts=50, lat_0=50, lon_0=260.)
map_.drawcoastlines()
map_.drawmapboundary()
map_.fillcontinents(zorder=-1)
return map_
def plot_thing1(map_, lats, lons, data):
x, y = map_(*np.meshgrid(lons, lats))
c = map_.contourf(x, y, data, zorder=0)
return c
def plot_thing2(map_, lats, lons, ugrd, vgrd):
x, y = map_(*np.meshgrid(lons, lats))
q = map_.quiver(x, y, ugrd, vgrd, zorder=0)
return q
min_lat, max_lat = 20, 70
min_lon, max_lon = 210, 310
lats = np.arange(min_lat, max_lat)
lons = np.arange(min_lon, max_lon)
shape = len(lats), len(lons)
# Run this once to get a reusable basemap
m = get_basemap()
plt.savefig("background.png")
#Plot stuff on the axes
data = np.random.rand(*shape)
c = plot_thing1(m, lats, lons, data)
plt.savefig("thing1.png")
#remove the contourplot from the axes:
for member in c.collections:
member.remove()
#Plot new stuff on the axes
ugrd, vgrd = np.random.rand(*shape), np.random.rand(*shape)
q = plot_thing2(m, lats, lons, ugrd, vgrd)
plt.savefig("thing2.png")
# to remove the quiver use
# q.remove()
plt.show()
作为解决方法,要直接在jupyter笔记本中显示保存的图像,您可以
from IPython.display import Image, display
listOfImageNames = ['background.png','thing1.png', 'thing2.png']
for fn in listOfImageNames:
display(Image(filename=fn))