Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plot is duplicated with repeated calls to plt.show() #585

Open
keatonb opened this issue Jan 9, 2025 · 6 comments
Open

Plot is duplicated with repeated calls to plt.show() #585

keatonb opened this issue Jan 9, 2025 · 6 comments

Comments

@keatonb
Copy link

keatonb commented Jan 9, 2025

Describe the issue

When I use the "%matplotlib ipympl" backend and display a plot with plt.show(), it works fine, but that plot is displayed again for every future call to plt.show(). The expected behavior is for show() to not repeat the plot output. This occurs with a fresh Anaconda (2024.10-1) installation of Python (3.12.7). This does not happen with default backend.

Versions

 3.12.7 | packaged by Anaconda, Inc. | (main, Oct  4 2024, 08:22:19) [Clang 14.0.6 ]
ipympl version: 0.9.6
Selected Jupyter core packages...
IPython          : 8.30.0
ipykernel        : 6.29.5
ipywidgets       : 8.1.5
jupyter_client   : 8.6.0
jupyter_core     : 5.7.2
jupyter_server   : 2.14.1
jupyterlab       : 4.2.5
nbclient         : 0.8.0
nbconvert        : 7.16.4
nbformat         : 5.10.4
notebook         : 7.2.2
qtconsole        : 5.6.0
traitlets        : 5.14.3
usage: jupyter [-h] [--version] [--config-dir] [--data-dir] [--runtime-dir]
               [--paths] [--json] [--debug]
               [subcommand]

Jupyter: Interactive Computing

positional arguments:
  subcommand     the subcommand to launch

options:
  -h, --help     show this help message and exit
  --version      show the versions of core jupyter packages and exit
  --config-dir   show Jupyter config dir
  --data-dir     show Jupyter data dir
  --runtime-dir  show Jupyter runtime dir
  --paths        show all Jupyter paths. Add --json for machine-readable
                 format.
  --json         output paths as machine-readable json
  --debug        output debug information about paths

Available subcommands: console dejavu events execute kernel kernelspec lab
labextension labhub migrate nbconvert notebook qtconsole run server
troubleshoot trust

Jupyter command `jupyter-nbextension` not found.

I believe that last error is expected for notebook>7, but I'm not certain.

@ianthomas23
Copy link
Member

You should not need to call plt.show() when using ipympl. Each Matplotlib Figure that you create (via plt.subplots() or plt.figure() or whatever) is displayed after the code cell in which it is created. Is there a particular reason you are using plt.show()?

@keatonb
Copy link
Author

keatonb commented Jan 9, 2025

It may not be needed, but it shouldn't hurt. All matplotlib gallery examples end with plt.show(). I can imagine calling imported functions that call show. Expected behavior is for already displayed to no longer be in the show queue, at least to my understanding, and imported function may expect repeated calls to not duplicate already displayed plots? I haven't downgraded things to check, but I don't think this used to happen with ipympl plots in notebook.

@ianthomas23
Copy link
Member

I cannot reproduce this, see screenshot:

Screenshot 2025-01-09 at 16 43 45

This is using the same package versions:

Python 3.12.8 | packaged by conda-forge | (main, Dec  5 2024, 14:19:53) [Clang 18.1.8 ] on darwin
ipympl 0.9.6
Selected Jupyter core packages...
IPython          : 8.30.0
ipykernel        : 6.29.5
ipywidgets       : 8.1.5
jupyter_client   : 8.6.0
jupyter_core     : 5.7.2
jupyter_server   : 2.14.1
jupyterlab       : 4.2.5
nbclient         : 0.8.0
nbconvert        : 7.16.4
nbformat         : 5.10.4
notebook         : 7.2.2
qtconsole        : 5.6.0
traitlets        : 5.14.3

and any of matplotlib 3.8.4, 3.9.4 or 3.10.

@keatonb
Copy link
Author

keatonb commented Jan 9, 2025

There you made a second figure. Here's a screenshot showing what I mean. Without the ipympl magic, no plot would be displayed after the second call to show.
image

@ianhi
Copy link
Collaborator

ianhi commented Jan 15, 2025

The expected behavior is for show() to not repeat the plot output

I'm not entirely what the expected behavior is. The notebook introduces a new paradigm where the same figure can be displayed multiple times as an output to different cells. In that case it seems intuitive to me that plt.show() should again display the current figure. Although in terminal ipython repeated calls to show does indeed not show the figure multiple times, even if the figure has been closed it will not be shown again.

I think @timhoffm is the right person to ask about resolving what is the right thing for api consistency, do you have an opinion on the correct behavior?


I'm pretty sure that the cause of this behavior is that this display in show is not wrapped in an if statement like this one:

if manager.canvas.figure in _Backend_ipympl._to_show:

try:
display(manager.canvas)
# metadata=_fetch_figure_metadata(manager.canvas.figure)

Wrapping that display with the if would likely give the @keatonb their desired behavior.

@timhoffm
Copy link
Member

timhoffm commented Jan 16, 2025

I think @timhoffm is the right person to ask about resolving what is the right thing for api consistency, do you have an opinion on the correct behavior?

My first question is on "The notebook introduces a new paradigm where the same figure can be displayed multiple times as an output to different cells." Is there documentation on this?

How is that supposed to work? A simple plt.show() should not trigger this. Because one typically doesn't close figures explicitly that would re-show all the figures you've shown anywhere before in the notebook. That's not a reasonable behavior. Or should this only re-show the last figure?

Either way, what is the use case? If I regard a notebook as a continuous document, having the same figure twice is unneeded duplication. If I want to have an update of the figure, I can re-execute the original cell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants