Skip to content

Commit

Permalink
Move draw_if_interactive logic to new_figure_manager_given_figure.
Browse files Browse the repository at this point in the history
Currently, Matplotlib only ever calls draw_if_interactive at the end of
`plt.figure()` (and upon figure unpickling), i.e. this is a mechanism to
further customize handling of newly generated figures.  (Prior to
Matplotlib 1.5, draw_if_interactive was also called at the end of all
pyplot functions to trigger a figure redraw, but this is now handled by
the stale attribute.)

In order to simplify the backend API ("what is the API that a backend
module must/can provide", I am planning to deprecate (on Matplotlib's
side) the ability for backends to provide a draw_if_interactive
function (forcing them to always do `if interactive(): draw_idle()`).
Instead, any relevant new-figure-customization logic can instead go
into `new_figure_manager_given_figure`.  This PR implements this change
for ipympl, and should be fully back-compatible all the way back to
Matplotlib 1.5.  I would like to make these changes first on the side
of the clients (i.e., the third-party backends), to catch any possible
problems with the intended change on Matplotlib's side.
  • Loading branch information
anntzer committed Jun 2, 2022
1 parent 913431e commit 73d1af2
Showing 1 changed file with 15 additions and 26 deletions.
41 changes: 15 additions & 26 deletions ipympl/backend_nbagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,21 @@ def destroy(event):
Gcf.destroy(manager)

cid = canvas.mpl_connect('close_event', destroy)

# Only register figure for showing when in interactive mode (otherwise
# we'll generate duplicate plots, since a user who set ioff() manually
# expects to make separate draw/show calls).
if is_interactive():
# ensure current figure will be drawn.
try:
_Backend_ipympl._to_show.remove(figure)
except ValueError:
# ensure it only appears in the draw list once
pass
# Queue up the figure for drawing in next show() call
_Backend_ipympl._to_show.append(figure)
_Backend_ipympl._draw_called = True

return manager

@staticmethod
Expand Down Expand Up @@ -523,32 +538,6 @@ def show(block=None):
if manager.canvas.figure in _Backend_ipympl._to_show:
_Backend_ipympl._to_show.remove(manager.canvas.figure)

@staticmethod
def draw_if_interactive():
# If matplotlib was manually set to non-interactive mode, this function
# should be a no-op (otherwise we'll generate duplicate plots, since a
# user who set ioff() manually expects to make separate draw/show
# calls).
if not is_interactive():
return

manager = Gcf.get_active()
if manager is None:
return
fig = manager.canvas.figure

# ensure current figure will be drawn, and each subsequent call
# of draw_if_interactive() moves the active figure to ensure it is
# drawn last
try:
_Backend_ipympl._to_show.remove(fig)
except ValueError:
# ensure it only appears in the draw list once
pass
# Queue up the figure for drawing in next show() call
_Backend_ipympl._to_show.append(fig)
_Backend_ipympl._draw_called = True


def flush_figures():
if rcParams['backend'] == 'module://ipympl.backend_nbagg':
Expand Down

0 comments on commit 73d1af2

Please sign in to comment.