0

问题

我正在使用 qtpy 制作一个 GUI,用户可以在其中切换地图选项。用户可以切换的一些选项是国家边界、线宽和颜色、网格线开/关等。理想情况下,我想设置地图投影,然后根据需要添加/删除/修改网格线,但是我没有看到任何真正的方法来做到这一点,至少没有一种方法能奏效,尤其是在更新网格线宽度、颜色等方面。

因此,我想出的解决方案是删除轴的先前实例并在请求更改时生成一个新实例。但是,在调用该.draw()方法时,我收到以下错误:

Traceback (most recent call last):
  File "/home/kwodzicki/.pyenv/versions/3.8.1/lib/python3.8/site-packages/matplotlib/cbook/__init__.py", line 216, in process
    func(*args, **kwargs)
  File "/home/kwodzicki/.local/lib/python3.8/site-packages/cartopy/mpl/gridliner.py", line 366, in _draw_event
    self._update_labels_visibility(event.renderer)
  File "/home/kwodzicki/.local/lib/python3.8/site-packages/cartopy/mpl/gridliner.py", line 780, in _update_labels_visibility
    specs, _ = self._segment_angle_to_text_specs(angle, lonlat)
  File "/home/kwodzicki/.local/lib/python3.8/site-packages/cartopy/mpl/gridliner.py", line 713, in _segment_angle_to_text_specs
    transform = mtrans.offset_copy(
  File "/home/kwodzicki/.pyenv/versions/3.8.1/lib/python3.8/site-packages/matplotlib/transforms.py", line 2937, in offset_copy
    raise ValueError('For units of inches or points a fig kwarg is needed')

此错误仅在绘制网格线时发生。如果我不绘制网格线,则轴(和海岸线)的删除和重绘工作不会出现任何错误。新的网格线似乎也正确绘制,但网格线的前一个实例很合适。

我的问题是,最好的方法是什么?我是否错过了更新现有网格线重量、颜色、标签等的方法?或者有没有办法完全删除网格线对象?

Python/包版本:

python     = 3.8.1
qtpy       = 1.9.0
matplotlib = 3.1.3
cartopy    = 0.19.0.post1

MWE

from qtpy.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QVBoxLayout

import cartopy.crs as ccrs

from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure

class FigureWidget( FigureCanvas ):
  def __init__(self, figure = None):
    if figure is None: figure = Figure( figsize=(5, 3) )
    super().__init__( figure )
    self.axes      = None
    self.linewidth = 0 

  def replot(self, **kwargs):
    self.linewidth = (self.linewidth % 5) + 1
    print( f'Linewidth : {self.linewidth}' )

    if self.axes: self.axes.remove()                                            # If axis exists already, remove it

    proj            = getattr(ccrs, 'Orthographic')
    self.axes       = self.figure.add_subplot( projection = proj( ) )
    self.coastlines = self.axes.coastlines( linewidth = self.linewidth )
    self.gridlines  = self.axes.gridlines(crs=ccrs.PlateCarree(), draw_labels=True)

    self.draw()

class BaseMap( QMainWindow ):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

    self.midRow = self._initMidRow()
    self._main  = QWidget()

    layout = QVBoxLayout(self._main)
    layout.addWidget( self.midRow )

    self.setCentralWidget(self._main)

    self.show()

  def _initMidRow( self ):
    self.figure = FigureWidget()
    self.figure.replot( )

    self.button = QPushButton('Replot')
    self.button.clicked.connect( self.figure.replot )                           # Call figure replot command when button is pushed
    
    layout    = QVBoxLayout()
    layout.addWidget( self.figure )
    layout.addWidget( self.button )

    widget = QWidget()
    widget.setLayout( layout )

    return widget

if __name__ == "__main__":
  import sys
  app = QApplication( sys.argv )
  inst = BaseMap()
  app.exec_()
4

0 回答 0