如何创建Basemap实例并将其重复使用不同的"覆盖"?

时间:2017-05-17 14:46:36

标签: python matplotlib matplotlib-basemap

我想创建一次Basemap实例(因为它很昂贵),然后重复使用,例如,不同的contourf()覆盖。

为了澄清,我需要(底图+轮廓1)和(底图+轮廓2),而不是(底图+轮廓1 +轮廓2),这是this question的内容。

有一些示例herehere(同一作者的回复,相隔五年!),但我无法获得简单的可重复使用的代码段。

根据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层次结构。

1 个答案:

答案 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()

enter image description here

作为解决方法,要直接在jupyter笔记本中显示保存的图像,您可以

from IPython.display import Image, display

listOfImageNames = ['background.png','thing1.png', 'thing2.png']

for fn in listOfImageNames:
    display(Image(filename=fn))