Skip to content

remove plt.close() from animations#120

Merged
JoelLucaAdams merged 5 commits intomainfrom
fix-early-animation-closing
Apr 16, 2026
Merged

remove plt.close() from animations#120
JoelLucaAdams merged 5 commits intomainfrom
fix-early-animation-closing

Conversation

@JoelLucaAdams
Copy link
Copy Markdown
Collaborator

@JoelLucaAdams JoelLucaAdams commented Apr 15, 2026

  • Removed closing of figure in animations
  • Updated documentation to close figures explicitly

Closing the figure early so that it would not display the first frame in a jupyter notebook or on the documentation is bad practice and I shouldn't have let it through in the first place. This causes a bug when using Tkinter as seen below.

To reproduce this bug using the dataarray.epoch.animate:

import matplotlib
# Force the Tkinter interactive backend
matplotlib.use('TkAgg') 

ds = sdfxr.open_mfdataset("docs/tutorial_dataset_2d")
anim = ds["Derived_Number_Density_Electron"].epoch.animate()

Alternatively if you're more interested in the general bug then you can reproduce this using this simple script:

import matplotlib
# Force the Tkinter interactive backend
matplotlib.use('TkAgg') 
import matplotlib.pyplot as plt
import numpy as np

def trigger_colorbar_crash():
    print("Creating figure...")
    fig, ax = plt.subplots()

    print("Creating dummy 2D data...")
    data = np.random.rand(10, 10)
    plot = ax.pcolormesh(data)

    print("Closing figure prematurely (simulating the bug)...")
    plt.close(fig)

    print("Attempting to add colorbar to the closed figure...")
    # Matplotlib tries to resize the axes for the colorbar,
    # which tells the Tkinter toolbar to update its "Undo/Back" history state.
    # Since plt.close() destroyed the toolbar, it throws a TclError.
    fig.colorbar(plot, ax=ax)

trigger_colorbar_crash()

@JoelLucaAdams JoelLucaAdams changed the title defer plot close until end defer plot close until end of animation building Apr 15, 2026
Copy link
Copy Markdown
Collaborator

@LiamPattinson LiamPattinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay, but just to be sure, has this been fully tested in Jupyter notebooks and from the terminal? Closing a fig but then returning something that uses it feels a bit sketchy.

@JoelLucaAdams JoelLucaAdams changed the title defer plot close until end of animation building remove plt.close() from animations Apr 15, 2026
@JoelLucaAdams
Copy link
Copy Markdown
Collaborator Author

Changed it now. We could actually simplify this even more on the documentation by simply calling plt.close() which will close all figs. This would remove the plt.subplots() line and the ax=ax from the animation calls but I think it's better to be explicit here. Thoughts on this @LiamPattinson ?

Copy link
Copy Markdown
Collaborator

@LiamPattinson LiamPattinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, even if I'm still not 100% clear on what's going on. Is it that Jupyter notebooks keep inserting an implicit plt.show() (or equivalent), which messes up the rendering in the docs?

Comment thread docs/animation.md
# Matplotlib will attempt to display the first frame of the video
# and since we don't want that on the documentation we run in
# notebook mode
%matplotlib notebook
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat, today I learned something

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay!! I helped :D

@JoelLucaAdams
Copy link
Copy Markdown
Collaborator Author

Looks good, even if I'm still not 100% clear on what's going on. Is it that Jupyter notebooks keep inserting an implicit plt.show() (or equivalent), which messes up the rendering in the docs?

So from my understanding what happens is that Jupyter will always attempt to render a figure at the end of each code cell but using certain backends such as notebook stops this from happening until you exclusively call plt.show(). https://matplotlib.org/stable/users/explain/figure/figure_intro.html#notebooks-and-ides

@JoelLucaAdams JoelLucaAdams merged commit 8009194 into main Apr 16, 2026
15 checks passed
@JoelLucaAdams JoelLucaAdams deleted the fix-early-animation-closing branch April 16, 2026 13:43
@LiamPattinson
Copy link
Copy Markdown
Collaborator

Good to know! I've seen %matplotlib inline so many times, I had no idea there were any alternatives.

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

Successfully merging this pull request may close these issues.

2 participants