Skip to content

Changing mouse cursor broken on mpl-master #335

@ianhi

Description

@ianhi

Describe the issue

matplotlib/matplotlib#20589 by @QuLogic introduced changes to how cursors are handled in webagg so now the following:

%matplotlib ipympl
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.tight_layout()

Breaks with this error message:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backend_bases.py in _wait_cursor_for_draw_cm(self)
   3011             try:
-> 3012                 self.set_cursor(cursors.WAIT)
   3013                 yield

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in set_cursor(self, cursor)
    385             }[cursor]
--> 386             self.canvas.send_event("cursor", cursor=cursor)
    387         self.cursor = cursor

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in send_event(self, event_type, **kwargs)
    339         if self.manager:
--> 340             self.manager._send_event(event_type, **kwargs)
    341 

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in _send_event(self, event_type, **kwargs)
    503         for s in self.web_sockets:
--> 504             s.send_json(payload)
    505 

~/Documents/oss/matplotlib/ipympl/ipympl/backend_nbagg.py in send_json(self, content)
    183         if content['type'] == 'cursor':
--> 184             self._cursor = cursors_str[content['cursor']]
    185 

KeyError: 'wait'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-1-a791764e6d70> in <module>
      2 import matplotlib.pyplot as plt
      3 fig, ax = plt.subplots()
----> 4 plt.tight_layout()

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/pyplot.py in tight_layout(pad, h_pad, w_pad, rect)
   2541 @_copy_docstring_and_deprecators(Figure.tight_layout)
   2542 def tight_layout(*, pad=1.08, h_pad=None, w_pad=None, rect=None):
-> 2543     return gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
   2544 
   2545 

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/figure.py in tight_layout(self, pad, h_pad, w_pad, rect)
   3149                                "compatible with tight_layout, so results "
   3150                                "might be incorrect.")
-> 3151         renderer = _get_renderer(self)
   3152         with getattr(renderer, "_draw_disabled", nullcontext)():
   3153             kwargs = get_tight_layout_figure(

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backend_bases.py in _get_renderer(figure, print_method)
   1555                 figure.canvas._get_output_canvas(None, fmt), f"print_{fmt}")
   1556         try:
-> 1557             print_method(io.BytesIO())
   1558         except Done as exc:
   1559             renderer, = figure._cachedRenderer, = exc.args

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backend_bases.py in wrapper(*args, **kwargs)
   1648             kwargs.pop(arg)
   1649 
-> 1650         return func(*args, **kwargs)
   1651 
   1652     return wrapper

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/_api/deprecation.py in wrapper(*inner_args, **inner_kwargs)
    447                          else deprecation_addendum,
    448                 **kwargs)
--> 449         return func(*inner_args, **inner_kwargs)
    450 
    451     return wrapper

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args)
    489             *metadata*, including the default 'Software' key.
    490         """
--> 491         FigureCanvasAgg.draw(self)
    492         mpl.image.imsave(
    493             filename_or_obj, self.buffer_rgba(), format="png", origin="upper",

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_agg.py in draw(self)
    382         self.renderer = self.get_renderer(cleared=True)
    383         # Acquire a lock on the shared font cache.
--> 384         with RendererAgg.lock, \
    385              (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    386               else nullcontext()):

~/mambaforge/envs/mpl-dev/lib/python3.9/contextlib.py in __enter__(self)
    115         del self.args, self.kwds, self.func
    116         try:
--> 117             return next(self.gen)
    118         except StopIteration:
    119             raise RuntimeError("generator didn't yield") from None

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backend_bases.py in _wait_cursor_for_draw_cm(self)
   3013                 yield
   3014             finally:
-> 3015                 self.set_cursor(self._lastCursor)
   3016         else:
   3017             yield

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in set_cursor(self, cursor)
    384                 backend_tools.Cursors.RESIZE_VERTICAL: 'ns-resize',
    385             }[cursor]
--> 386             self.canvas.send_event("cursor", cursor=cursor)
    387         self.cursor = cursor
    388 

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in send_event(self, event_type, **kwargs)
    338     def send_event(self, event_type, **kwargs):
    339         if self.manager:
--> 340             self.manager._send_event(event_type, **kwargs)
    341 
    342 

~/Documents/oss/matplotlib/matplotlib/lib/matplotlib/backends/backend_webagg_core.py in _send_event(self, event_type, **kwargs)
    502         payload = {'type': event_type, **kwargs}
    503         for s in self.web_sockets:
--> 504             s.send_json(payload)
    505 
    506 

~/Documents/oss/matplotlib/ipympl/ipympl/backend_nbagg.py in send_json(self, content)
    182         # Change in the widget state?
    183         if content['type'] == 'cursor':
--> 184             self._cursor = cursors_str[content['cursor']]
    185 
    186         elif content['type'] == 'message':

KeyError: 'default'

Versions

Matplotlib: 3.4.2.post1334+g14b34fd186.d20210712
 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:46) 
[GCC 9.3.0]
ipympl version: 0.7.0
jupyter core     : 4.7.1
jupyter-notebook : 6.3.0
qtconsole        : not installed
ipython          : 7.22.0
ipykernel        : 5.5.3
jupyter client   : 6.1.12
jupyter lab      : 3.0.14
nbconvert        : 6.0.7
ipywidgets       : 7.6.3
nbformat         : 5.1.3
traitlets        : 5.0.5
Known nbextensions:
  config dir: /home/ian/mambaforge/envs/mpl-dev/etc/jupyter/nbconfig
    notebook section
      jupyter-js-widgets/extension  enabled 
      - Validating: OK
JupyterLab v3.0.14
/home/ian/mambaforge/envs/mpl-dev/share/jupyter/labextensions
        jupyter-matplotlib v0.9.0 enabled OK
        @jupyter-widgets/jupyterlab-manager v3.0.0 enabled OK (python, jupyterlab_widgets)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions