@@ -108,9 +108,8 @@ def _backend_selection():
108108from matplotlib .backends import pylab_setup
109109_backend_mod , new_figure_manager , draw_if_interactive , _show = pylab_setup ()
110110
111- _BASE_DH = None
112111_IP_REGISTERED = None
113-
112+ _INSTALL_FIG_OBSERVER = False
114113
115114def install_repl_displayhook ():
116115 """
@@ -119,8 +118,8 @@ def install_repl_displayhook():
119118
120119 This works with both IPython terminals and vanilla python shells.
121120 """
122- global _BASE_DH
123121 global _IP_REGISTERED
122+ global _INSTALL_FIG_OBSERVER
124123
125124 class _NotIPython (Exception ):
126125 pass
@@ -136,33 +135,23 @@ class _NotIPython(Exception):
136135 if _IP_REGISTERED :
137136 return
138137
139- def displayhook ():
138+ def post_execute ():
140139 if matplotlib .is_interactive ():
141140 draw_all ()
142141
143142 # IPython >= 2
144143 try :
145- ip .events .register ('post_execute' , displayhook )
144+ ip .events .register ('post_execute' , post_execute )
146145 except AttributeError :
147146 # IPython 1.x
148- ip .register_post_execute (displayhook )
147+ ip .register_post_execute (post_execute )
149148
150- _IP_REGISTERED = displayhook
149+ _IP_REGISTERED = post_execute
150+ _INSTALL_FIG_OBSERVER = False
151151
152152 # import failed or ipython is not running
153153 except (ImportError , _NotIPython ):
154-
155- if _BASE_DH is not None :
156- return
157-
158- dh = _BASE_DH = sys .displayhook
159-
160- def displayhook (* args ):
161- dh (* args )
162- if matplotlib .is_interactive ():
163- draw_all ()
164-
165- sys .displayhook = displayhook
154+ _INSTALL_FIG_OBSERVER = True
166155
167156
168157def uninstall_repl_displayhook ():
@@ -181,8 +170,8 @@ def uninstall_repl_displayhook():
181170 function was there when matplotlib installed it's displayhook,
182171 possibly discarding your changes.
183172 """
184- global _BASE_DH
185173 global _IP_REGISTERED
174+ global _INSTALL_FIG_OBSERVER
186175 if _IP_REGISTERED :
187176 from IPython import get_ipython
188177 ip = get_ipython ()
@@ -193,9 +182,8 @@ def uninstall_repl_displayhook():
193182 "in IPython < 2.0" )
194183 _IP_REGISTERED = None
195184
196- if _BASE_DH :
197- sys .displayhook = _BASE_DH
198- _BASE_DH = None
185+ if _INSTALL_FIG_OBSERVER :
186+ _INSTALL_FIG_OBSERVER = False
199187
200188
201189draw_all = _pylab_helpers .Gcf .draw_all
@@ -288,7 +276,8 @@ def pause(interval):
288276 figManager = _pylab_helpers .Gcf .get_active ()
289277 if figManager is not None :
290278 canvas = figManager .canvas
291- canvas .draw ()
279+ if canvas .figure .stale :
280+ canvas .draw ()
292281 show (block = False )
293282 canvas .start_event_loop (interval )
294283 return
@@ -507,8 +496,7 @@ def figure(num=None, # autoincrement if None, else integer from 1-N
507496 if figManager is None :
508497 max_open_warning = rcParams ['figure.max_open_warning' ]
509498
510- if (max_open_warning >= 1 and
511- len (allnums ) >= max_open_warning ):
499+ if (max_open_warning >= 1 and len (allnums ) >= max_open_warning ):
512500 warnings .warn (
513501 "More than %d figures have been opened. Figures "
514502 "created through the pyplot interface "
@@ -543,9 +531,26 @@ def make_active(event):
543531 _pylab_helpers .Gcf .set_active (figManager )
544532 figManager .canvas .figure .number = num
545533
534+ if _INSTALL_FIG_OBSERVER :
535+ figManager .canvas .figure .add_callback (_auto_draw_if_interactive )
536+
546537 return figManager .canvas .figure
547538
548539
540+ def _auto_draw_if_interactive (fig ):
541+ """
542+ This is an internal helper function for making sure that auto-redrawing
543+ works as intended in the plain python repl.
544+
545+ Parameters
546+ ----------
547+ fig : Figure
548+ A figure object which is assumed to be associated with a canvas
549+ """
550+ if fig .stale and matplotlib .is_interactive ():
551+ fig .canvas .draw_idle ()
552+
553+
549554def gcf ():
550555 "Get a reference to the current figure."
551556
0 commit comments