【问题标题】:Using one background map for multiple plots with matplotlib-basemap?使用 matplotlib-basemap 对多个绘图使用一张背景图?
【发布时间】:2018-03-02 20:50:01
【问题描述】:

Matplotlibs 底图模块具有为地图绘制背景的能力,具有inbuilt functions for some basic maps 和绑定到arcgis maps 的能力。

两个选项都运行良好,但速度很慢 (see also here),尤其是 arcgis 选项。

对于单个地块,这不是一个大问题,但是对于多个地块(在我的情况下大约 500 个),这变得相当等待练习,另外,我不想向 arcgis 发送数百个请求,这总是无论如何都要获取相同的地图。

但是我如何设置/下载一次背景地图,并在绘制多个版本的循环中继续使用它?

我已经调整了 the great circle example from the documentation 与 etopo 背景,并通过一些颜色循环进行测试:

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# create new figure, axes instances.
fig=plt.figure()
ax=fig.add_axes([0.1,0.1,0.8,0.8])
# setup mercator map projection.
m = Basemap(llcrnrlon=-100.,llcrnrlat=20.,urcrnrlon=20.,urcrnrlat=60.,\
            rsphere=(6378137.00,6356752.3142),\
            resolution='l',projection='merc',\
            lat_0=40.,lon_0=-20.,lat_ts=20.)
# nylat, nylon are lat/lon of New York
nylat = 40.78; nylon = -73.98
# lonlat, lonlon are lat/lon of London.
lonlat = 51.53; lonlon = 0.08
# draw great circle route between NY and London
m.drawcoastlines()
m.etopo()
# draw parallels
m.drawparallels(np.arange(10,90,20),labels=[1,1,0,1])
# draw meridians
m.drawmeridians(np.arange(-180,180,30),labels=[1,1,0,1])

colors = ('r','b','k','y')
for p_color in colors:
    m.drawgreatcircle(nylon,nylat,lonlon,lonlat,linewidth=2,color=p_color)
    filename = '%s.png' % p_color
    plt.savefig(filename, dpi=100)

上述方法有效,但这只是因为我没有关闭情节。用我的真实数字,我很快就会耗尽记忆。如果我在循环末尾添加plt.close(),我的背景图就会丢失。当我将情节的设置放入循环时也是如此:

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# create new figure, axes instances.
# setup mercator map projection.
m = Basemap(llcrnrlon=-100.,llcrnrlat=20.,urcrnrlon=20.,urcrnrlat=60.,\
            rsphere=(6378137.00,6356752.3142),\
            resolution='l',projection='merc',\
            lat_0=40.,lon_0=-20.,lat_ts=20.)
# nylat, nylon are lat/lon of New York
nylat = 40.78; nylon = -73.98
# lonlat, lonlon are lat/lon of London.
lonlat = 51.53; lonlon = 0.08
# draw great circle route between NY and London
m.drawcoastlines()
m.etopo()
# draw parallels
m.drawparallels(np.arange(10,90,20),labels=[1,1,0,1])
# draw meridians
m.drawmeridians(np.arange(-180,180,30),labels=[1,1,0,1])

colors = ('r','b','k','y')
for p_color in colors:
    fig=plt.figure()
    ax=fig.add_axes([0.1,0.1,0.8,0.8])
    m.drawgreatcircle(nylon,nylat,lonlon,lonlat,linewidth=2,color=p_color)
    filename = '%s.png' % p_color
    plt.savefig(filename, dpi=100)
    plt.close()

当我在循环中执行整个m.Basemap…m.etopo 内容时,它似乎才起作用(忽略第一个选项的内存问题),但这太慢了。

如何设置“m”一次并继续使用它?

我可以通过绘制背景图一次,将我的数据绘制到透明背景上,然后将其与 imagemagick 结合来实现 MacGyver,但我觉得应该有更好的解决方案。

【问题讨论】:

    标签: python matplotlib plot maps matplotlib-basemap


    【解决方案1】:

    我想这个想法是保留底图而不是改变它。在循环中添加您想要从图像更改为图像的艺术家,保存图形,然后删除艺术家。

    from mpl_toolkits.basemap import Basemap
    import numpy as np
    import matplotlib.pyplot as plt
    # create new figure, axes instances.
    # setup mercator map projection.
    fig=plt.figure()
    ax=fig.add_axes([0.1,0.1,0.8,0.8])
    m = Basemap(llcrnrlon=-100.,llcrnrlat=20.,urcrnrlon=20.,urcrnrlat=60.,\
                rsphere=(6378137.00,6356752.3142),\
                resolution='l',projection='merc',\
                lat_0=40.,lon_0=-20.,lat_ts=20.)
    # nylat, nylon are lat/lon of New York
    nylat = 40.78; nylon = -73.98
    # lonlat, lonlon are lat/lon of London.
    lonlat = 51.53; lonlon = 0.08
    # draw great circle route between NY and London
    m.drawcoastlines()
    m.etopo()
    # draw parallels
    m.drawparallels(np.arange(10,90,20),labels=[1,1,0,1])
    # draw meridians
    m.drawmeridians(np.arange(-180,180,30),labels=[1,1,0,1])
    
    colors = ('r','b','k','y')
    for p_color in colors:
        gc = m.drawgreatcircle(nylon,nylat,lonlon,lonlat,linewidth=2,color=p_color)
        filename = 'output{}.png'.format(p_color)
        plt.savefig(filename, dpi=100)
        # remove previous plot from axes
        for line in gc:
            line.remove()
        del gc
    

    【讨论】:

    • 可行,但需要适应我的真实身材。我使用的是m.scatter,而不是m.drawgreatcircle,所以我必须删除它的'PathCollection' object,看起来简单的del gc 就可以了。但是,我在设置(和删除)其他元素时有点迷失。我在其中有一个plt.colorbar,当添加到循环中时,它会一遍又一遍地添加。在循环之外,它默认为jet 颜色图,与真实图形无关。一个简单的cb = plt.colorbar;循环中的del cb 产生ValueError: left cannot be >= right,但单独输入。
    • 我无法完全理解您的评论;您需要有关颜色条的进一步帮助,还是只是对颜色条不易更改的评论?
    • 两者。我只是想知道为什么 del gc 与 PathCollection 一起使用,但颜色条的 del cb 却没有。现在正在处理另一个评论,我想我已经解决了。
    • 颜色条更复杂,因为它位于自己的轴上。简单地删除它不是一种选择。您将改为在循环外创建一个颜色条轴 cax = fig.add_axes([...]),用循环内的颜色条填充它,fig.colorbar(scatter, cax=cax),保存后,清除颜色条轴,cax.clear()
    • 老实说,我觉得很明显,那些不应该在下一个循环步骤中保留的情节部分需要事先删除。那就是“……,然后删除艺术家”这句话。说,艺术家可以是你喜欢的任何东西。
    猜你喜欢
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多