Skip to content

Commit 91f5547

Browse files
committed
Extend the example to plt.plot and plt.errorbar
1 parent a9b1542 commit 91f5547

File tree

5 files changed

+71
-17
lines changed

5 files changed

+71
-17
lines changed

lib/matplotlib/__init__.py

+25
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ def _forward_ilshift(self, other):
214214
'numpy %s or later is required; you have %s' % (
215215
__version__numpy__, numpy.__version__))
216216

217+
import functools
218+
def _interactive(func):
219+
"""
220+
Decorator for Figure and Axes methods that will be wrapped in pyplot.
221+
222+
Methods so decorated no longer need a call to `draw_if_interactive`
223+
in their pyplot wrappers, and are interactive when invoked as
224+
methods with a gui backend in interactive mode.
225+
226+
Figure and Axes must define the methods `check_interactive`,
227+
`draw_if_interactive`, and `clear_interactive` used in this
228+
decorator.
229+
"""
230+
@functools.wraps(func)
231+
def inner(self, *args, **kw):
232+
outer = self.check_interactive()
233+
drawn = True # default in "finally" clause is to clear.
234+
try:
235+
ret = func(self, *args, **kw)
236+
drawn = self.draw_if_interactive(outer)
237+
finally:
238+
self.clear_interactive(drawn)
239+
return ret
240+
return inner
241+
217242

218243
def _is_writable_dir(p):
219244
"""

lib/matplotlib/axes/_axes.py

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
from matplotlib.axes._base import _AxesBase
4141
from matplotlib.axes._base import _process_plot_format
4242

43+
from matplotlib import _interactive # decorator
44+
45+
4346
iterable = cbook.iterable
4447
is_string_like = cbook.is_string_like
4548
is_sequence_of_strings = cbook.is_sequence_of_strings
@@ -1234,6 +1237,7 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
12341237
return colls
12351238

12361239
#### Basic plotting
1240+
@_interactive
12371241
@docstring.dedent_interpd
12381242
def plot(self, *args, **kwargs):
12391243
"""
@@ -2529,6 +2533,7 @@ def pie(self, x, explode=None, labels=None, colors=None,
25292533
else:
25302534
return slices, texts, autotexts
25312535

2536+
@_interactive
25322537
@docstring.dedent_interpd
25332538
def errorbar(self, x, y, yerr=None, xerr=None,
25342539
fmt='', ecolor=None, elinewidth=None, capsize=3,

lib/matplotlib/axes/_base.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@
3232
import matplotlib.image as mimage
3333
from matplotlib.artist import allow_rasterization
3434

35-
3635
from matplotlib.cbook import iterable
3736

37+
from matplotlib import is_interactive
38+
3839

3940
is_string_like = cbook.is_string_like
4041
is_sequence_of_strings = cbook.is_sequence_of_strings
@@ -442,6 +443,7 @@ def __init__(self, fig, rect,
442443
self.set_cursor_props((1, 'k')) # set the cursor properties for axes
443444

444445
self._cachedRenderer = None
446+
self._in_outer_method = False
445447
self.set_navigate(True)
446448
self.set_navigate_mode(None)
447449

@@ -461,6 +463,40 @@ def __init__(self, fig, rect,
461463
self._ycid = self.yaxis.callbacks.connect('units finalize',
462464
self.relim)
463465

466+
467+
def draw_if_interactive(self, outer=False):
468+
print("entering draw_if_interactive in axes/_base, outer = ", outer)
469+
# Not sure whether this should be public or private...
470+
if not outer or not is_interactive():
471+
return False
472+
# Leave out the following check for now; it probably
473+
# has to be modified so that it does not require importing
474+
# all the available interactive backends just to make
475+
# the list of canvases. Instead, the check could be based
476+
# on the str() or (repr) of self.canvas.
477+
#if not isinstance(self.canvas, interactive_canvases):
478+
# return
479+
self.figure.canvas.draw()
480+
print("drawing complete in axes/_base")
481+
return True
482+
483+
def check_interactive(self):
484+
"""
485+
Return True upon entering an outer method, and set the
486+
flag; return False if already in an outer method.
487+
"""
488+
if not self._in_outer_method:
489+
self._in_outer_method = True
490+
print("checking: toggled _in_outer_method to True")
491+
return True
492+
print("checking: already _in_outer_method; returning False")
493+
return False
494+
495+
def clear_interactive(self, drawn):
496+
if drawn:
497+
self._in_outer_method = False
498+
499+
464500
def __setstate__(self, state):
465501
self.__dict__ = state
466502
# put the _remove_method back on all artists contained within the axes

lib/matplotlib/figure.py

+2-14
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
from matplotlib import rcParams
2525
from matplotlib import docstring
2626
from matplotlib import __version__ as _mpl_version
27+
2728
from matplotlib import is_interactive
29+
from matplotlib import _interactive # decorator
2830

2931
import matplotlib.artist as martist
3032
from matplotlib.artist import Artist, allow_rasterization
@@ -234,20 +236,6 @@ def _update_this(self, s, val):
234236

235237
setattr(self, s, val)
236238

237-
import functools
238-
def _interactive(func):
239-
@functools.wraps(func)
240-
def inner(self, *args, **kw):
241-
outer = self.check_interactive()
242-
drawn = True # default in "finally" clause is to clear.
243-
try:
244-
ret = func(self, *args, **kw)
245-
drawn = self.draw_if_interactive(outer)
246-
finally:
247-
self.clear_interactive(drawn)
248-
return ret
249-
return inner
250-
251239
class Figure(Artist):
252240

253241
"""

lib/matplotlib/pyplot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2761,7 +2761,7 @@ def errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None,
27612761
barsabove=barsabove, lolims=lolims, uplims=uplims,
27622762
xlolims=xlolims, xuplims=xuplims,
27632763
errorevery=errorevery, capthick=capthick, **kwargs)
2764-
draw_if_interactive()
2764+
#draw_if_interactive()
27652765
finally:
27662766
ax.hold(washold)
27672767

@@ -3095,7 +3095,7 @@ def plot(*args, **kwargs):
30953095
ax.hold(hold)
30963096
try:
30973097
ret = ax.plot(*args, **kwargs)
3098-
draw_if_interactive()
3098+
#draw_if_interactive()
30993099
finally:
31003100
ax.hold(washold)
31013101

0 commit comments

Comments
 (0)