简体   繁体   English

缩放 cartopy plot 时更新纬度/经度轴

[英]Update lat/lon axes when zooming on cartopy plot

I am plotting some data in cartopy.我在 cartopy 中绘制一些数据。 I would like to be able to zoom in on a region of the map and have the latitude/longitude axes update to reflect the zoomed in region.我希望能够放大 map 的区域并更新纬度/经度轴以反映放大的区域。 Instead, they just dissapear altogether when I zoom in. How do I fix this?相反,当我放大时,它们会完全消失。我该如何解决这个问题?

Here is my code for generating the axes这是我生成轴的代码

plt.figure()
ax = plt.axes(projection=cartopy.crs.PlateCarree())
ax.add_feature(cartopy.feature.LAND, edgecolor='black')
gl = ax.gridlines(crs=cartopy.crs.PlateCarree(), draw_labels=True,
                  linewidth=2, color='gray', alpha=0.5, linestyle='--')
# plot some stuff here

It is possible to update the cartopy gridliners in interactive mode, but you need to subclass the Navigation toolbar.可以在交互模式下更新 cartopy 网格线,但您需要对 Navigation 工具栏进行子类化。

In this example below I have used a PySide/QT5 example code that allows me to substitute a subclassed toolbar, then merged in the gridliner example code.在下面的示例中,我使用了 PySide/QT5 示例代码,它允许我替换子类工具栏,然后合并到 gridliner 示例代码中。 The overloaded toolbar callbacks recreate the gridlines everytime zoom/pan/home is used.每次使用 zoom/pan/home 时,重载的工具栏回调都会重新创建网格线。

I used python3.8, matplotlib-3.4.2, cartopy-0.20我用过python3.8、matplotlib-3.4.2、cartopy-0.20

import sys
from PySide2 import QtWidgets
from PySide2.QtWidgets import QVBoxLayout

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import cartopy.crs as ccrs


class CustomNavigationToolbar(NavigationToolbar):
    toolitems = [t for t in NavigationToolbar.toolitems if t[0] in ('Home', 'Pan', 'Zoom', 'Save')]

    def __init__(self, canvas, parent, coordinates=True, func_recreate_gridlines=None):
        print('CustomNavigationToolbar::__init__')
        super(CustomNavigationToolbar, self).__init__(canvas, parent, coordinates)
        self.func_recreate_gridlines = func_recreate_gridlines

    def home(self, *args):
        print('CustomNavigationToolbar::home')
        super(CustomNavigationToolbar, self).home(*args)
        if self.func_recreate_gridlines is not None:
            self.func_recreate_gridlines()

    def release_pan(self, event):
        print('CustomNavigationToolbar::release_pan')
        super(CustomNavigationToolbar, self).release_pan(event)
        if self.func_recreate_gridlines is not None:
            self.func_recreate_gridlines()

    def release_zoom(self, event):
        print('CustomNavigationToolbar::release_zoom')
        super(CustomNavigationToolbar, self).release_zoom(event)
        if self.func_recreate_gridlines is not None:
            self.func_recreate_gridlines()


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        print('ApplicationWindow::__init__')
        super().__init__()

        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        self.layout = QVBoxLayout(self._main)

        self.fig = Figure()
        self.canvas = FigureCanvas(self.fig)
        self.toolbar = CustomNavigationToolbar(self.canvas, self,
                                               coordinates=True,
                                               func_recreate_gridlines=self.recreate_gridlines)
        self.layout.addWidget(self.canvas)
        self.addToolBar(self.toolbar)

        # figure setup taken from gridlines example at
        # https://scitools.org.uk/cartopy/docs/latest/matplotlib/gridliner.html
        projection = ccrs.RotatedPole(pole_longitude=120.0, pole_latitude=70.0)
        self.ax = self.canvas.figure.add_subplot(1, 1, 1, projection=projection)
        self.ax.set_extent([-6, 3, 48, 58], crs=ccrs.PlateCarree())
        self.ax.coastlines(resolution='10m')

        self._gl = None
        self.recreate_gridlines()

    def recreate_gridlines(self):
        print('ApplicationWindow::recreate_gridlines')

        print(' remove old gridliner artists')
        if self._gl is not None:
            for artist_coll in [self._gl.xline_artists, self._gl.yline_artists, self._gl.xlabel_artists, self._gl.ylabel_artists]:
                for a in artist_coll:
                    a.remove()
            self.ax._gridliners = []

        print(' self.ax.gridlines()')
        self._gl = self.ax.gridlines(crs=ccrs.PlateCarree(),
                                     draw_labels=True, dms=True, x_inline=False, y_inline=False)


if __name__ == "__main__":
    qapp = QtWidgets.QApplication(sys.argv)
    app = ApplicationWindow()
    app.show()
    qapp.exec_()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM