ipympl icon indicating copy to clipboard operation
ipympl copied to clipboard

Error raised on mouse cursor hover with matplotlib>=3.10

Open nvaytet opened this issue 7 months ago • 21 comments

Describe the issue

Using matplotlib>=3.10.*, making any plot with ipympl raises an error when hovering the mouse over the axes.

Example:

import matplotlib.pyplot as plt
%matplotlib widget

fig, ax = plt.subplots()

Hovering the mouse over the plot raises

KeyError                                  Traceback (most recent call last)
File [~/miniforge3/lib/python3.12/site-packages/ipympl/backend_nbagg.py:278](http://localhost:8888/home/nvaytet/miniforge3/lib/python3.12/site-packages/ipympl/backend_nbagg.py#line=277), in Canvas._handle_message(self, object, content, buffers)
    275     self.manager.handle_json(content)
    277 else:
--> 278     self.manager.handle_json(content)

File [~/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py:474](http://localhost:8888/home/nvaytet/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py#line=473), in FigureManagerWebAgg.handle_json(self, content)
    473 def handle_json(self, content):
--> 474     self.canvas.handle_event(content)

File [~/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py:264](http://localhost:8888/home/nvaytet/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py#line=263), in FigureCanvasWebAggCore.handle_event(self, event)
    261 e_type = event['type']
    262 handler = getattr(self, f'handle_{e_type}',
    263                   self.handle_unknown_event)
--> 264 return handler(event)

File [~/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py:295](http://localhost:8888/home/nvaytet/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_webagg_core.py#line=294), in FigureCanvasWebAggCore._handle_mouse(self, event)
    286 e_type = event['type']
    287 button = event['button'] + 1  # JS numbers off by 1 compared to mpl.
    288 buttons = {  # JS ordering different compared to mpl.
    289     button for button, mask in [
    290         (MouseButton.LEFT, 1),
    291         (MouseButton.RIGHT, 2),
    292         (MouseButton.MIDDLE, 4),
    293         (MouseButton.BACK, 8),
    294         (MouseButton.FORWARD, 16),
--> 295     ] if event['buttons'] & mask  # State *after* press[/release.](http://localhost:8888/release.)
    296 }
    297 modifiers = event['modifiers']
    298 guiEvent = event.get('guiEvent')

KeyError: 'buttons'

Note: need to set level to 'Debug' in log console to see it.

The figure is basically inactive.

Could be related to #592 but I did install 0.9.7 and it did not fix the issue.

Downgrading to matplotlib=3.9.4 fixes the issue.

Versions

 3.12.7 | packaged by conda-forge | (main, Oct  4 2024, 16:05:46) [GCC 13.3.0]
ipympl version: 0.9.7
Selected Jupyter core packages...
IPython          : 8.30.0
ipykernel        : 6.29.5
ipywidgets       : 8.1.5
jupyter_client   : 8.6.3
jupyter_core     : 5.7.2
jupyter_server   : 2.14.2
jupyterlab       : 4.3.1
nbclient         : 0.10.1
nbconvert        : 7.16.4
nbformat         : 5.10.4
notebook         : not installed
qtconsole        : not installed
traitlets        : 5.14.3

nvaytet avatar Apr 28 '25 22:04 nvaytet

The symptoms are indeed the same as #592, and this has been fixed. I cannot reproduce with the same packages in a new environment:

ipympl                         0.9.7           pyhd8ed1ab_1          conda-forge
matplotlib                     3.10.1          py312h1f38498_0       conda-forge
Selected Jupyter core packages...
IPython          : 8.30.0
ipykernel        : 6.29.5
ipywidgets       : 8.1.5
jupyter_client   : 8.6.3
jupyter_core     : 5.7.2
jupyter_server   : 2.14.2
jupyterlab       : 4.3.1
nbclient         : 0.10.1
nbconvert        : 7.16.4
nbformat         : 5.10.4
notebook         : not installed
qtconsole        : not installed
traitlets        : 5.14.3

It looks you aren't actually using ipympl 0.9.7 at runtime, even though that version is installed.

One report of this issue at matplotlib/matplotlib#29654 was that it was a caching issue which was solved by restarting the kernel a number of times. Please can you try that?

ianthomas23 avatar Apr 29 '25 19:04 ianthomas23

Getting the same issue with matplotlib 3.10.1, and ipympl 0.9.7, also setting the following behind the scenes to handle interactive figures:

matplotlib.use("module://ipympl.backend_nbagg")
plt.ion()

tried restarting a number of times, and reinstalling ipympl with --no-cache-dir, but no luck there.

No interactive features of interactive plots work with the error. Fixed again by downgrading matplotlib to 3.9.4 for now

T-Wainwright avatar May 01 '25 15:05 T-Wainwright

It looks you aren't actually using ipympl 0.9.7 at runtime, even though that version is installed.

Doing

import ipympl

ipympl.__version__

in the same notebook does yield 0.9.7... 🤔

nvaytet avatar May 01 '25 21:05 nvaytet

I cannot reproduce with the same packages in a new environment:

Can it be the Python version that is different? I can't think of anything else...

nvaytet avatar May 02 '25 06:05 nvaytet

I have now tried this on a different system and I am still getting the same issue: ipympl==0.9.7 continues to raise the error about buttons with matplotlib==3.10.3.

nvaytet avatar Jun 02 '25 09:06 nvaytet

Reporting the same issue. Python 3.12.6, matplotlib 3.10.1, and ipympl 0.9.7 from conda-forge, linux; x86-64. Downgrading matplotlib and matplotlib-base to 3.9.4 without changing other packages did resolve the issue.

Older environment with Python 3.12.8, matplotlib 3.9.3, and ipympl 0.9.4 do not experience this issue.

HojinCho avatar Jun 02 '25 18:06 HojinCho

@nvaytet what OS were you on? And did you also install via conda?

@HojinCho can you please try a debugging step for me by installing with pip instead of conda

ianhi avatar Jun 06 '25 17:06 ianhi

I tried to replicate your envinronment with conda on macos and was unable to replicate

ianhi avatar Jun 06 '25 17:06 ianhi

@nvaytet what OS were you on? And did you also install via conda?

@HojinCho can you please try a debugging step for me by installing with pip instead of conda

Can confirm, matplotlib 3.10.1 and ipympl 0.9.7 installed from pip, under Python 3.12.6 from conda-forge, works without the error (linux x86-64). Seems like the conda-forge distribution has a bug.

HojinCho avatar Jun 06 '25 17:06 HojinCho

Thank you @HojinCho! I another debugging request. Could you try installing directly from the tar.gz on pypi (which is how the conda forge build does it).

 pip install https://files.pythonhosted.org/packages/39/1b/acd3d481869d614a7acbb831bd9304411eae47b05d7607db989613028788/ipympl-0.9.7.tar.gz

and let me know if that works?

I want to determine if its an issue with the uploaded source, or with the actual build process

ianhi avatar Jun 06 '25 19:06 ianhi

Thank you @HojinCho! I another debugging request. Could you try installing directly from the tar.gz on pypi (which is how the conda forge build does it).

 pip install https://files.pythonhosted.org/packages/39/1b/acd3d481869d614a7acbb831bd9304411eae47b05d7607db989613028788/ipympl-0.9.7.tar.gz

and let me know if that works?

I want to determine if its an issue with the uploaded source, or with the actual build process

I did following. From the same environment I tested previously, I ran pip uninstall ipympl, which removed (obscured the system path with ${ENV} just to be safe)

${ENV}/etc/jupyter/nbconfig/notebook.d/jupyter-matplotlib.json
${ENV}/lib/python3.12/site-packages/ipympl-0.9.7.dist-info/*
${ENV}/lib/python3.12/site-packages/ipympl/*
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/package.json
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/480.61003b90daa033903fc2.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/486.73b0487516c94a05d0c2.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/486.73b0487516c94a05d0c2.js.LICENSE.txt
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/643.9489cdb90c0b68743dc8.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/688.89f91b958e83eda58752.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/remoteEntry.1cd74fa323152bfea195.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/style.js
${ENV}/share/jupyter/labextensions/jupyter-matplotlib/static/third-party-licenses.json
${ENV}/share/jupyter/nbextensions/jupyter-matplotlib/extension.js
${ENV}/share/jupyter/nbextensions/jupyter-matplotlib/index.js
${ENV}/share/jupyter/nbextensions/jupyter-matplotlib/index.js.LICENSE.txt
${ENV}/share/jupyter/nbextensions/jupyter-matplotlib/index.js.map

and then I ran the command you posted. It produced following output regarding Node.js and npm.

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [43 lines of output]
      INFO:hatch_jupyter_builder.utils:Running jupyter-builder
      INFO:hatch_jupyter_builder.utils:Building with hatch_jupyter_builder.npm_builder
      INFO:hatch_jupyter_builder.utils:With kwargs: {'path': '.', 'build_cmd': 'build:prod', 'npm': ['jlpm']}
      INFO:hatch_jupyter_builder.utils:Installing build dependencies with npm.  This may take a while...
      INFO:hatch_jupyter_builder.utils:> /tmp/pip-build-env-n6eovjgp/overlay/bin/jlpm install
      Traceback (most recent call last):
        File "/tmp/pip-build-env-n6eovjgp/overlay/bin/jlpm", line 8, in <module>
          sys.exit(main())
                   ^^^^^^
        File "/tmp/pip-build-env-n6eovjgp/overlay/lib/python3.12/site-packages/jupyterlab/jlpmapp.py", line 43, in main
          execvp("node", ["node", YARN_PATH, *argv])
        File "/tmp/pip-build-env-n6eovjgp/overlay/lib/python3.12/site-packages/jupyterlab/jlpmapp.py", line 24, in execvp
          cmd = which(cmd)
                ^^^^^^^^^^
        File "/tmp/pip-build-env-n6eovjgp/overlay/lib/python3.12/site-packages/jupyterlab_server/process.py", line 61, in which
          raise ValueError(msg)
      ValueError: Please install Node.js and npm before continuing installation. You may be able to install Node.js from your package manager, from conda, or directly from the Node.js website (https://nodejs.org).
      Traceback (most recent call last):
        File "${ENV}/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 389, in <module>
          main()
        File "${ENV}/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 373, in main
          json_out["return_val"] = hook(**hook_input["kwargs"])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "${ENV}/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 178, in prepare_metadata_for_build_wheel
          whl_basename = backend.build_wheel(metadata_directory, config_settings)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-n6eovjgp/overlay/lib/python3.12/site-packages/hatchling/build.py", line 58, in build_wheel
          return os.path.basename(next(builder.build(directory=wheel_directory, versions=['standard'])))
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-n6eovjgp/overlay/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 147, in build
          build_hook.initialize(version, build_data)
        File "/tmp/pip-build-env-n6eovjgp/normal/lib/python3.12/site-packages/hatch_jupyter_builder/plugin.py", line 94, in initialize
          raise e
        File "/tmp/pip-build-env-n6eovjgp/normal/lib/python3.12/site-packages/hatch_jupyter_builder/plugin.py", line 89, in initialize
          build_func(self.target_name, version, **build_kwargs)
        File "/tmp/pip-build-env-n6eovjgp/normal/lib/python3.12/site-packages/hatch_jupyter_builder/utils.py", line 115, in npm_builder
          run([*npm_cmd, "install"], cwd=str(abs_path))
        File "/tmp/pip-build-env-n6eovjgp/normal/lib/python3.12/site-packages/hatch_jupyter_builder/utils.py", line 231, in run
          return subprocess.check_call(cmd, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "${ENV}/lib/python3.12/subprocess.py", line 413, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '['/tmp/pip-build-env-n6eovjgp/overlay/bin/jlpm', 'install']' returned non-zero exit status 1.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

I've never seen this output, so I did not try any further and post it here. Should I try to install additional dependencies and proceed?

HojinCho avatar Jun 06 '25 19:06 HojinCho

Additionally, I tested with another clean environment, with Python 3.12.6 from conda-forge and matplotlib 3.10.1 from PyPI. Running

pip install https://files.pythonhosted.org/packages/39/1b/acd3d481869d614a7acbb831bd9304411eae47b05d7607db989613028788/ipympl-0.9.7.tar.gz

produced the same error with Node.js and npm.

HojinCho avatar Jun 06 '25 19:06 HojinCho

I'm running kubuntu 24.04 and installed everything via conda forge

nvaytet avatar Jun 06 '25 21:06 nvaytet

Ok! Thank you both for the info. I think it seems that the conda forge build is broken (at least for Linux) I can't test that easily while traveling. But I'll leave myself a reminder to check this on my linux computer when I'm home in a few weeks. In the meantime it seems installing from pip is a workaround, and hopefully anyone with the power to regenerate a conda build (@martinRenou ?) might be able to fix this

ianhi avatar Jun 09 '25 01:06 ianhi

I could reproduce this with matplotlib=3.10.6

ameraner avatar Sep 19 '25 22:09 ameraner

But I'll leave myself a reminder to check this on my linux computer when I'm home in a few weeks. In the meantime it seems installing from pip is a workaround,

I did not check :( and while I am once again travelling. this time I do have my linux laptop.

@ameraner is the issue only with conda for you?

ianhi avatar Sep 19 '25 22:09 ianhi

yes, pure conda

ameraner avatar Sep 19 '25 22:09 ameraner

This was confirmed to be a problem with VSCode in matplotlib/matplotlib#29654 and matplotlib/matplotlib#30337.

ianthomas23 avatar Sep 22 '25 06:09 ianthomas23

I encountered the issue while using Jupyterlab though...

ameraner avatar Sep 29 '25 09:09 ameraner

I encountered the same issue. Downgrading to matplotlib==3.9.6 worked.

ej159 avatar Sep 30 '25 22:09 ej159

Hi there, is there any news on this? Thanks 🙂

nvaytet avatar Nov 03 '25 09:11 nvaytet