Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 985721e

Browse files
committed
MNT: implement direct calls to draw_idle
This is the result of a phone discussion with @medhoon The idea is to not rely on pyplot knowing to check if the figure needs to be re-drawn, but just have the Figure object directly kick the canvas to draw_idle. This does not currently work with nbagg due to the first draw_idle being fired before it is finished building it's self. There maybe similar race conditions in the other backends.
1 parent aa810b6 commit 985721e

File tree

2 files changed

+11
-91
lines changed

2 files changed

+11
-91
lines changed

lib/matplotlib/figure.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ def _stale_figure_callback(self, val):
5555
self.figure.stale = val
5656

5757

58+
def _stale_canvas_callback(self, val):
59+
if rcParams['interactive'] and self.canvas is not None and val:
60+
self.canvas.draw_idle()
61+
62+
5863
class AxesStack(Stack):
5964
"""
6065
Specialization of the Stack to handle all tracking of Axes in a Figure.
@@ -351,6 +356,11 @@ def __init__(self,
351356
self._axstack = AxesStack() # track all figure axes and current axes
352357
self.clf()
353358
self._cachedRenderer = None
359+
self.stale_callback = Figure._stale_callback
360+
361+
def _stale_callback(self, val):
362+
if val and self.canvas is not None:
363+
self.canvas.stale = val
354364

355365
# TODO: I'd like to dynamically add the _repr_html_ method
356366
# to the figure in the right context, but then IPython doesn't
@@ -559,7 +569,7 @@ def set_canvas(self, canvas):
559569
ACCEPTS: a FigureCanvas instance
560570
"""
561571
self.canvas = canvas
562-
self.stale = True
572+
self.stale_callback = _stale_canvas_callback
563573

564574
def hold(self, b=None):
565575
"""

lib/matplotlib/pyplot.py

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -108,84 +108,6 @@ def _backend_selection():
108108
from matplotlib.backends import pylab_setup
109109
_backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
110110

111-
_IP_REGISTERED = None
112-
_INSTALL_FIG_OBSERVER = False
113-
114-
def install_repl_displayhook():
115-
"""
116-
Install a repl display hook so that any stale figure are automatically
117-
redrawn when control is returned to the repl.
118-
119-
This works with both IPython terminals and vanilla python shells.
120-
"""
121-
global _IP_REGISTERED
122-
global _INSTALL_FIG_OBSERVER
123-
124-
class _NotIPython(Exception):
125-
pass
126-
127-
# see if we have IPython hooks around, if use them
128-
129-
try:
130-
from IPython import get_ipython
131-
ip = get_ipython()
132-
if ip is None:
133-
raise _NotIPython()
134-
135-
if _IP_REGISTERED:
136-
return
137-
138-
def post_execute():
139-
if matplotlib.is_interactive():
140-
draw_all()
141-
142-
# IPython >= 2
143-
try:
144-
ip.events.register('post_execute', post_execute)
145-
except AttributeError:
146-
# IPython 1.x
147-
ip.register_post_execute(post_execute)
148-
149-
_IP_REGISTERED = post_execute
150-
_INSTALL_FIG_OBSERVER = False
151-
152-
# import failed or ipython is not running
153-
except (ImportError, _NotIPython):
154-
_INSTALL_FIG_OBSERVER = True
155-
156-
157-
def uninstall_repl_displayhook():
158-
"""
159-
Uninstalls the matplotlib display hook.
160-
161-
.. warning
162-
163-
Need IPython >= 2 for this to work. For IPython < 2 will raise a
164-
``NotImplementedError``
165-
166-
.. warning
167-
168-
If you are using vanilla python and have installed another
169-
display hook this will reset ``sys.displayhook`` to what ever
170-
function was there when matplotlib installed it's displayhook,
171-
possibly discarding your changes.
172-
"""
173-
global _IP_REGISTERED
174-
global _INSTALL_FIG_OBSERVER
175-
if _IP_REGISTERED:
176-
from IPython import get_ipython
177-
ip = get_ipython()
178-
try:
179-
ip.events.unregister('post_execute', _IP_REGISTERED)
180-
except AttributeError:
181-
raise NotImplementedError("Can not unregister events "
182-
"in IPython < 2.0")
183-
_IP_REGISTERED = None
184-
185-
if _INSTALL_FIG_OBSERVER:
186-
_INSTALL_FIG_OBSERVER = False
187-
188-
189111
draw_all = _pylab_helpers.Gcf.draw_all
190112

191113

@@ -245,13 +167,11 @@ def isinteractive():
245167
def ioff():
246168
'Turn interactive mode off.'
247169
matplotlib.interactive(False)
248-
uninstall_repl_displayhook()
249170

250171

251172
def ion():
252173
'Turn interactive mode on.'
253174
matplotlib.interactive(True)
254-
install_repl_displayhook()
255175

256176

257177
def pause(interval):
@@ -532,9 +452,6 @@ def make_active(event):
532452
fig = figManager.canvas.figure
533453
fig.number = num
534454

535-
if _INSTALL_FIG_OBSERVER:
536-
fig.stale_callback = _auto_draw_if_interactive
537-
538455
return fig
539456

540457

@@ -2483,13 +2400,6 @@ def spy(Z, precision=0, marker=None, markersize=None, aspect='equal', hold=None,
24832400
sci(ret)
24842401
return ret
24852402

2486-
# just to be safe. Interactive mode can be turned on without
2487-
# calling `plt.ion()` so register it again here.
2488-
# This is safe because multiple calls to `install_repl_displayhook`
2489-
# are no-ops and the registered function respect `mpl.is_interactive()`
2490-
# to determine if they should trigger a draw.
2491-
install_repl_displayhook()
2492-
24932403
################# REMAINING CONTENT GENERATED BY boilerplate.py ##############
24942404

24952405

0 commit comments

Comments
 (0)