Cartopy:遍历多个范围而无需重新生成地图图像/删除Gridliner对象

问题描述

我试图在地图上绘制出源点和接收点的地图,这些地图上我会根据源和接收器的位置放大地图。对于源和接收者的每种组合,我都有一个新的地图,具有新的范围。我想找到一种方法,可以一次下载地图图像,然后每次都更改范围,这样就不必每次都加载地图图像(我必须制作成千上万个)。所有事件都在一个国家/地区发生,因此我希望下载整个国家/地区的地图,然后更改每个循环的范围。

我实际上已经部分解决了这个问题,但是我遇到了网格问题。最初,我首先将范围设置为整个国家,然后将其加载到图像中,然后保存。然后,我可以重置每个源接收器对的范围,绘制两个点,然后保存图像。然后,我只需要擦除两个点中的每一个,然后可以再次设置范围。

但是,一旦在网格中添加了经度和纬度标签,就会遇到问题。每次迭代后,我都无法擦除网格和标签,因此它们最终只是在彼此之上分层,标签开始在整个图上移动。我摆脱网格的唯一方法是清除轴,但这会删除地图图像。

我的问题:是否有一种方法可以仅擦除gridliner对象(不隐藏标签和网格,而是实际删除)?如果不是,是否有其他方法可以在开始时加载图像,这样我就可以每次清除轴,而不必在新的tiler中完全重新加载?

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.io.img_tiles import Stamen

whole_extent = [18,42,8,36]
tiler = Stamen('terrain-background')

fig = plt.figure(figsize=(13.75,10))
ax1 = plt.axes(projection=ccrs.PlateCarree())
ax1.set_extent(whole_extent,crs=ccrs.PlateCarree())
ax1.add_image(tiler,6)
#Need to save initial figure to lock in initial picture,otherwise it locks in the extent from the first loop and any map that goes outside the extent of the first loop is white space
plt.savefig('plots/001_Wholefigure.png')


eventlist=[['A',22,15,30,30],['B',18],['C',38,24,21,15],['D',25,12,28,16],['E',32,11]]

for i in eventlist:
    eventname = i[0]
    slon = i[1] #source lon
    slat = i[2] #source lat
    lon = i[3] #receiver lon
    lat = i[4] #receiver lat

    print(f'{eventname} in progress')
    
    # Sets the zoomed in extent based on source/receiver locations
    if lon > slon:
        lonmin = slon - 2
        lonmax = lon + 2
    else:
        lonmin = lon - 2
        lonmax = slon + 2

    if lat > slat:
        latmin = slat -2
        latmax = lat + 2
    else:
        latmin = lat - 2
        latmax = slat + 2

    zoomextent = [lonmin,lonmax,latmin,latmax]


    # MAP
    ax1.set_extent(zoomextent,crs=ccrs.PlateCarree())
    receiverloc = ax1.plot(lon,lat,'r*',label='Receiver')
    sourceloc = ax1.plot(slon,slat,'k^',label='Source')
    text = ax1.text(slon+0.1,slat+0.1,eventname)
    legend = ax1.legend(loc="upper right")
    
    gl = ax1.gridlines(crs=ccrs.PlateCarree(),draw_labels=True,linewidth=2,color='gray',alpha=0.5,linestyle='--')
    gl.bottom_labels = gl.right_labels = False

    plt.savefig(f'plots/{eventname}.png')

    # Delete the two markers and the text so they don't show up on next loop
    receiverloc.pop(0).remove()
    sourceloc.pop(0).remove()
    text.remove()

在这里上传了两张图的图像,您可以在“ E”中看到问题。我不知道如何删除网格,清除轴会删除地图图像。 A E

解决方法

因为它依赖于某些私有属性,所以它不是一个很好的解决方案,但这可以在循环结束时添加:

# Remove all artists created by the gridliner
for artist in (gl.xline_artists + gl.yline_artists +
               gl.bottom_label_artists + gl.top_label_artists +
               gl.left_label_artists + gl.right_label_artists):
    artist.remove()

# Remove the created gridliner from the list
ax1._gridliners.remove(gl)

# Try to re-connect to the draw event,which since it's already
# connected will return the existing connection id
cid = gl.axes.figure.canvas.mpl_connect('draw_event',gl._draw_event)

# Disconnect using that cid
gl.axes.figure.canvas.mpl_disconnect(cid)

这有效地撤消了ax.gridlines()和创建Gridliner实例的作用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...