Skip to content

Commit 4350bbf

Browse files
committed
Extend the example to plt.plot and plt.errorbar
1 parent 8838673 commit 4350bbf

File tree

5 files changed

+68
-18
lines changed

5 files changed

+68
-18
lines changed

lib/matplotlib/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,31 @@ def _forward_ilshift(self, other):
201201
'numpy %s or later is required; you have %s' % (
202202
__version__numpy__, numpy.__version__))
203203

204+
import functools
205+
def _interactive(func):
206+
"""
207+
Decorator for Figure and Axes methods that will be wrapped in pyplot.
208+
209+
Methods so decorated no longer need a call to `draw_if_interactive`
210+
in their pyplot wrappers, and are interactive when invoked as
211+
methods with a gui backend in interactive mode.
212+
213+
Figure and Axes must define the methods `check_interactive`,
214+
`draw_if_interactive`, and `clear_interactive` used in this
215+
decorator.
216+
"""
217+
@functools.wraps(func)
218+
def inner(self, *args, **kw):
219+
outer = self.check_interactive()
220+
drawn = True # default in "finally" clause is to clear.
221+
try:
222+
ret = func(self, *args, **kw)
223+
drawn = self.draw_if_interactive(outer)
224+
finally:
225+
self.clear_interactive(drawn)
226+
return ret
227+
return inner
228+
204229

205230
def _is_writable_dir(p):
206231
"""

lib/matplotlib/axes/_axes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
3939
from matplotlib.axes._base import _AxesBase
4040
from matplotlib.axes._base import _process_plot_format
41+
from matplotlib import _interactive # decorator
4142

4243
rcParams = matplotlib.rcParams
4344

@@ -1235,6 +1236,7 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
12351236
return colls
12361237

12371238
#### Basic plotting
1239+
@_interactive
12381240
@docstring.dedent_interpd
12391241
def plot(self, *args, **kwargs):
12401242
"""
@@ -2530,6 +2532,7 @@ def pie(self, x, explode=None, labels=None, colors=None,
25302532
else:
25312533
return slices, texts, autotexts
25322534

2535+
@_interactive
25332536
@docstring.dedent_interpd
25342537
def errorbar(self, x, y, yerr=None, xerr=None,
25352538
fmt='', ecolor=None, elinewidth=None, capsize=3,

lib/matplotlib/axes/_base.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030
import matplotlib.text as mtext
3131
import matplotlib.image as mimage
3232
from matplotlib.artist import allow_rasterization
33-
34-
3533
from matplotlib.cbook import iterable
34+
from matplotlib import is_interactive
3635

3736
rcParams = matplotlib.rcParams
3837

@@ -442,6 +441,7 @@ def __init__(self, fig, rect,
442441
self.set_cursor_props((1, 'k')) # set the cursor properties for axes
443442

444443
self._cachedRenderer = None
444+
self._in_outer_method = False
445445
self.set_navigate(True)
446446
self.set_navigate_mode(None)
447447

@@ -461,6 +461,40 @@ def __init__(self, fig, rect,
461461
self._ycid = self.yaxis.callbacks.connect('units finalize',
462462
self.relim)
463463

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

lib/matplotlib/figure.py

Lines changed: 2 additions & 14 deletions
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

Lines changed: 2 additions & 2 deletions
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)