KeyError:尝试使用axes.inset_axes添加GeoAxes时出现“geo”

问题描述 投票:0回答:1

我试图创建气象数据的垂直截面。我希望主图是一个普通的 matplotlib 图,显示垂直横截面数据,右上角的插图显示地图上横截面的位置。我之前已经能够使用Figure.add_axes在其他图中插入cartopy GeoAxes,所以我很惊讶它在这里使用inset_axes失败了。

更令人困惑的是,该错误被报告为插入轴的脊柱字典中关键字“geo”的 KeyError 。但是,打印插入轴的脊柱会显示关键字和关联的脊柱对象。

要重现的示例代码:

%matplotlib inline #This problem was encountered in a jupyter notebook,
#but I have no reason to think it wouldn't be the same in python
import matplotlib.pyplot as plt
from matplotlib.style import use as usestyle
from matplotlib import colors
from matplotlib.colors import BoundaryNorm
import matplotlib as mpl
import cartopy.crs as ccrs
from cartopy import feature as cfeature
from matplotlib.lines import Line2D

ramscrs = ccrs.Stereographic(central_longitude = -80, central_latitude = 42)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize = (4,8), dpi = 200, layout = "constrained")
axinset = ax1.inset_axes([0.75, 0.75, 0.25, 0.25], projection = ramscrs, zorder = 2)
print(type(axinset))
print(list(axinset.spines.keys()))
print(axinset.spines['geo'])

print(axinset.spines['geo'].stale)

错误回溯:

Error in callback <function _draw_all_if_interactive at 0x7f745c98ea70> (for post_execute):

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/pyplot.py:120, in _draw_all_if_interactive()
    118 def _draw_all_if_interactive():
    119     if matplotlib.is_interactive():
--> 120         draw_all()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
    130 for manager in cls.get_all_fig_managers():
    131     if force or manager.canvas.figure.stale:
--> 132         manager.canvas.draw_idle()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/backend_bases.py:2082, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   2080 if not self._is_idle_drawing:
   2081     with self._idle_draw_cntx():
-> 2082         self.draw(*args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:400, in FigureCanvasAgg.draw(self)
    396 # Acquire a lock on the shared font cache.
    397 with RendererAgg.lock, \
    398      (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    399       else nullcontext()):
--> 400     self.figure.draw(self.renderer)
    401     # A GUI class may be need to update a window using this draw, so
    402     # don't forget to call the superclass.
    403     super().draw()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/figure.py:3169, in Figure.draw(self, renderer)
   3167 if self.axes and self.get_layout_engine() is not None:
   3168     try:
-> 3169         self.get_layout_engine().execute(self)
   3170     except ValueError:
   3171         pass

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/layout_engine.py:274, in ConstrainedLayoutEngine.execute(self, fig)
    271 w_pad = self._params['w_pad'] / width
    272 h_pad = self._params['h_pad'] / height
--> 274 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
    275                              wspace=self._params['wspace'],
    276                              hspace=self._params['hspace'],
    277                              rect=self._params['rect'],
    278                              compress=self._compress)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:119, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
    109     return
    111 for _ in range(2):
    112     # do the algorithm twice.  This has to be done because decorations
    113     # change size after the first re-position (i.e. x/yticklabels get
   (...)
    117     # make margins for all the axes and subfigures in the
    118     # figure.  Add margins for colorbars...
--> 119     make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
    120                         w_pad=w_pad, hspace=hspace, wspace=wspace)
    121     make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
    122                           w_pad=w_pad)
    124     # if a layout is such that a columns (or rows) margin has no
    125     # constraints, we need to make all such instances in the grid
    126     # match in margin size.

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:371, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
    367     return
    369 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
    370                                  hspace=hspace, wspace=wspace)
--> 371 pos, bbox = get_pos_and_bbox(ax, renderer)
    372 # the margin is the distance between the bounding box of the axes
    373 # and its position (plus the padding from above)
    374 margin['left'] += pos.x0 - bbox.x0

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:619, in get_pos_and_bbox(ax, renderer)
    617 # pos is in panel co-ords, but we need in figure for the layout
    618 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 619 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
    620 if tightbbox is None:
    621     bbox = pos

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:1415, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1409 """
   1410 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1411 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1412 when encountering third-party subclasses that do not support it.
   1413 """
   1414 try:
-> 1415     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1416 except TypeError:
   1417     return obj.get_tightbbox(*args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:4408, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4405     bbox_artists = self.get_default_bbox_extra_artists()
   4407 for a in bbox_artists:
-> 4408     bbox = a.get_tightbbox(renderer)
   4409     if (bbox is not None
   4410             and 0 < bbox.width < np.inf
   4411             and 0 < bbox.height < np.inf):
   4412         bb.append(bbox)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:506, in GeoAxes.get_tightbbox(self, renderer, *args, **kwargs)
    498 """
    499 Extend the standard behaviour of
    500 :func:`matplotlib.axes.Axes.get_tightbbox`.
   (...)
    503 gridliners before calculating the tight bounding box.
    504 """
    505 # Shared processing steps
--> 506 self._draw_preprocess(renderer)
    508 return super().get_tightbbox(renderer, *args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:487, in GeoAxes._draw_preprocess(self, renderer)
    484 # If data has been added (i.e. autoscale hasn't been turned off)
    485 # then we should autoscale the view.
    486 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 487     self.autoscale_view()
    489 # Adjust location of background patch so that new gridlines below are
    490 # clipped correctly.
    491 self.patch._adjust_location()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:897, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
    890 def autoscale_view(self, tight=None, scalex=True, scaley=True):
    891     """
    892     Autoscale the view limits using the data limits, taking into
    893     account the projection of the geoaxes.
    894 
    895     See :meth:`~matplotlib.axes.Axes.imshow()` for more details.
    896     """
--> 897     super().autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
    898     # Limit the resulting bounds to valid area.
    899     if scalex and self.get_autoscalex_on():

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:2930, in _AxesBase.autoscale_view(self, tight, scalex, scaley)
   2927     set_bound(x0, x1)
   2928     # End of definition of internal function 'handle_single_axis'.
-> 2930 handle_single_axis(
   2931     scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin,
   2932     x_stickies, self.set_xbound)
   2933 handle_single_axis(
   2934     scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin,
   2935     y_stickies, self.set_ybound)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:2927, in _AxesBase.autoscale_view.<locals>.handle_single_axis(scale, shared_axes, name, axis, margin, stickies, set_bound)
   2925 if not self._tight:
   2926     x0, x1 = locator.view_limits(x0, x1)
-> 2927 set_bound(x0, x1)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:3530, in _AxesBase.set_xbound(self, lower, upper)
   3527 if upper is None:
   3528     upper = old_upper
-> 3530 self.set_xlim(sorted((lower, upper),
   3531                      reverse=bool(self.xaxis_inverted())),
   3532               auto=None)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:3650, in _AxesBase.set_xlim(self, left, right, emit, auto, xmin, xmax)
   3648         raise TypeError("Cannot pass both 'right' and 'xmax'")
   3649     right = xmax
-> 3650 return self.xaxis._set_lim(left, right, emit=emit, auto=auto)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axis.py:1225, in Axis._set_lim(self, v0, v1, emit, auto)
   1222     self._set_autoscale_on(bool(auto))
   1224 if emit:
-> 1225     self.axes.callbacks.process(f"{name}lim_changed", self.axes)
   1226     # Call all of the other axes that are shared with this one
   1227     for other in self.axes._shared_axes[name].get_siblings(self.axes):

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:314, in CallbackRegistry.process(self, s, *args, **kwargs)
    312 except Exception as exc:
    313     if self.exception_handler is not None:
--> 314         self.exception_handler(exc)
    315     else:
    316         raise

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:98, in _exception_printer(exc)
     96 def _exception_printer(exc):
     97     if _get_running_interactive_framework() in ["headless", None]:
---> 98         raise exc
     99     else:
    100         traceback.print_exc()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:309, in CallbackRegistry.process(self, s, *args, **kwargs)
    307 if func is not None:
    308     try:
--> 309         func(*args, **kwargs)
    310     # this does not capture KeyboardInterrupt, SystemExit,
    311     # and GeneratorExit
    312     except Exception as exc:

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:2317, in _trigger_patch_reclip(event)
   2315 axes = event.axes
   2316 # trigger the outline and background patches to be re-clipped
-> 2317 axes.spines['geo'].stale = True
   2318 axes.patch.stale = True

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/spines.py:574, in Spines.__getitem__(self, key)
    570     else:
    571         raise ValueError(
    572             'Spines does not support slicing except for the fully '
    573             'open slice [:] to access all spines.')
--> 574 return self._dict[key]

KeyError: 'geo'

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/IPython/core/formatters.py:340, in BaseFormatter.__call__(self, obj)
    338     pass
    339 else:
--> 340     return printer(obj)
    341 # Finally look for special method names
    342 method = get_real_method(obj, self.print_method)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/backend_bases.py:2342, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2336     renderer = _get_renderer(
   2337         self.figure,
   2338         functools.partial(
   2339             print_method, orientation=orientation)
   2340     )
   2341     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2342         self.figure.draw(renderer)
   2344 if bbox_inches:
   2345     if bbox_inches == "tight":

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/figure.py:3169, in Figure.draw(self, renderer)
   3167 if self.axes and self.get_layout_engine() is not None:
   3168     try:
-> 3169         self.get_layout_engine().execute(self)
   3170     except ValueError:
   3171         pass

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/layout_engine.py:274, in ConstrainedLayoutEngine.execute(self, fig)
    271 w_pad = self._params['w_pad'] / width
    272 h_pad = self._params['h_pad'] / height
--> 274 return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
    275                              wspace=self._params['wspace'],
    276                              hspace=self._params['hspace'],
    277                              rect=self._params['rect'],
    278                              compress=self._compress)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:119, in do_constrained_layout(fig, h_pad, w_pad, hspace, wspace, rect, compress)
    109     return
    111 for _ in range(2):
    112     # do the algorithm twice.  This has to be done because decorations
    113     # change size after the first re-position (i.e. x/yticklabels get
   (...)
    117     # make margins for all the axes and subfigures in the
    118     # figure.  Add margins for colorbars...
--> 119     make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
    120                         w_pad=w_pad, hspace=hspace, wspace=wspace)
    121     make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
    122                           w_pad=w_pad)
    124     # if a layout is such that a columns (or rows) margin has no
    125     # constraints, we need to make all such instances in the grid
    126     # match in margin size.

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:371, in make_layout_margins(layoutgrids, fig, renderer, w_pad, h_pad, hspace, wspace)
    367     return
    369 margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
    370                                  hspace=hspace, wspace=wspace)
--> 371 pos, bbox = get_pos_and_bbox(ax, renderer)
    372 # the margin is the distance between the bounding box of the axes
    373 # and its position (plus the padding from above)
    374 margin['left'] += pos.x0 - bbox.x0

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_constrained_layout.py:619, in get_pos_and_bbox(ax, renderer)
    617 # pos is in panel co-ords, but we need in figure for the layout
    618 pos = pos.transformed(fig.transSubfigure - fig.transFigure)
--> 619 tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
    620 if tightbbox is None:
    621     bbox = pos

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/artist.py:1415, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
   1409 """
   1410 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
   1411 *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
   1412 when encountering third-party subclasses that do not support it.
   1413 """
   1414 try:
-> 1415     return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
   1416 except TypeError:
   1417     return obj.get_tightbbox(*args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:4408, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
   4405     bbox_artists = self.get_default_bbox_extra_artists()
   4407 for a in bbox_artists:
-> 4408     bbox = a.get_tightbbox(renderer)
   4409     if (bbox is not None
   4410             and 0 < bbox.width < np.inf
   4411             and 0 < bbox.height < np.inf):
   4412         bb.append(bbox)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:506, in GeoAxes.get_tightbbox(self, renderer, *args, **kwargs)
    498 """
    499 Extend the standard behaviour of
    500 :func:`matplotlib.axes.Axes.get_tightbbox`.
   (...)
    503 gridliners before calculating the tight bounding box.
    504 """
    505 # Shared processing steps
--> 506 self._draw_preprocess(renderer)
    508 return super().get_tightbbox(renderer, *args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:487, in GeoAxes._draw_preprocess(self, renderer)
    484 # If data has been added (i.e. autoscale hasn't been turned off)
    485 # then we should autoscale the view.
    486 if self.get_autoscale_on() and self.ignore_existing_data_limits:
--> 487     self.autoscale_view()
    489 # Adjust location of background patch so that new gridlines below are
    490 # clipped correctly.
    491 self.patch._adjust_location()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:897, in GeoAxes.autoscale_view(self, tight, scalex, scaley)
    890 def autoscale_view(self, tight=None, scalex=True, scaley=True):
    891     """
    892     Autoscale the view limits using the data limits, taking into
    893     account the projection of the geoaxes.
    894 
    895     See :meth:`~matplotlib.axes.Axes.imshow()` for more details.
    896     """
--> 897     super().autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
    898     # Limit the resulting bounds to valid area.
    899     if scalex and self.get_autoscalex_on():

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:2930, in _AxesBase.autoscale_view(self, tight, scalex, scaley)
   2927     set_bound(x0, x1)
   2928     # End of definition of internal function 'handle_single_axis'.
-> 2930 handle_single_axis(
   2931     scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin,
   2932     x_stickies, self.set_xbound)
   2933 handle_single_axis(
   2934     scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin,
   2935     y_stickies, self.set_ybound)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:2927, in _AxesBase.autoscale_view.<locals>.handle_single_axis(scale, shared_axes, name, axis, margin, stickies, set_bound)
   2925 if not self._tight:
   2926     x0, x1 = locator.view_limits(x0, x1)
-> 2927 set_bound(x0, x1)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:3530, in _AxesBase.set_xbound(self, lower, upper)
   3527 if upper is None:
   3528     upper = old_upper
-> 3530 self.set_xlim(sorted((lower, upper),
   3531                      reverse=bool(self.xaxis_inverted())),
   3532               auto=None)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
    448 if len(args) > name_idx:
    449     warn_deprecated(
    450         since, message="Passing the %(name)s %(obj_type)s "
    451         "positionally is deprecated since Matplotlib %(since)s; the "
    452         "parameter will become keyword-only %(removal)s.",
    453         name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axes/_base.py:3650, in _AxesBase.set_xlim(self, left, right, emit, auto, xmin, xmax)
   3648         raise TypeError("Cannot pass both 'right' and 'xmax'")
   3649     right = xmax
-> 3650 return self.xaxis._set_lim(left, right, emit=emit, auto=auto)

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/axis.py:1225, in Axis._set_lim(self, v0, v1, emit, auto)
   1222     self._set_autoscale_on(bool(auto))
   1224 if emit:
-> 1225     self.axes.callbacks.process(f"{name}lim_changed", self.axes)
   1226     # Call all of the other axes that are shared with this one
   1227     for other in self.axes._shared_axes[name].get_siblings(self.axes):

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:314, in CallbackRegistry.process(self, s, *args, **kwargs)
    312 except Exception as exc:
    313     if self.exception_handler is not None:
--> 314         self.exception_handler(exc)
    315     else:
    316         raise

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:98, in _exception_printer(exc)
     96 def _exception_printer(exc):
     97     if _get_running_interactive_framework() in ["headless", None]:
---> 98         raise exc
     99     else:
    100         traceback.print_exc()

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:309, in CallbackRegistry.process(self, s, *args, **kwargs)
    307 if func is not None:
    308     try:
--> 309         func(*args, **kwargs)
    310     # this does not capture KeyboardInterrupt, SystemExit,
    311     # and GeneratorExit
    312     except Exception as exc:

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py:2317, in _trigger_patch_reclip(event)
   2315 axes = event.axes
   2316 # trigger the outline and background patches to be re-clipped
-> 2317 axes.spines['geo'].stale = True
   2318 axes.patch.stale = True

File ~/miniconda3/envs/paperplots/lib/python3.10/site-packages/matplotlib/spines.py:574, in Spines.__getitem__(self, key)
    570     else:
    571         raise ValueError(
    572             'Spines does not support slicing except for the fully '
    573             'open slice [:] to access all spines.')
--> 574 return self._dict[key]

KeyError: 'geo'

<Figure size 800x1600 with 2 Axes>

相关软件包的版本:

python: 3.10.12 卡托皮:0.22.0 matplotlib:3.7.2 朱皮特:1.0.0

如果我需要提供更多信息,请告诉我。

我原以为 ax1.inset_axes(projection = ramscrs) 能够正常工作。它在使用Figure.add_axes时有效,那么为什么在使用Axes.inset_axes时不行呢?

python python-3.x matplotlib cartopy
1个回答
0
投票

对于未来的读者,答案将是升级到 Cartopy v0.24 或更高版本。 但是,该版本尚未发布,因此您可以使用旧版工具包版本的

inset_axes
来解决该问题:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import cartopy.crs as ccrs
from cartopy.mpl.geoaxes import GeoAxes

ramscrs = ccrs.Stereographic(central_longitude=-80, central_latitude=42)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(4,8), dpi=200, layout='constrained')
axinset = inset_axes(ax1, width='25%', height='25%', loc='upper right',
                     axes_class=GeoAxes, axes_kwargs={'projection': ramscrs})

plt.show()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.