Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix single-shot timers in nbagg backend #4892

Merged
merged 4 commits into from Aug 12, 2015

Conversation

joferkington
Copy link
Contributor

Single-shot timers are currently non-functional (raise an error) when using the nbagg backed.

To reproduce the issue, try running the following in an ipython notebook (I can't seem to find a way to set up a fully independent nbagg figure without manually starting a "full" notebook):

import numpy as np
import matplotlib
matplotlib.use('nbAgg')
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

def callback(ax):
    ax.plot(np.random.random((10, 10)))
    ax.figure.canvas.draw()

timer = fig.canvas.new_timer(1000, [(callback, [ax], {})])
timer.single_shot = True
timer.start()

plt.show()

Ideally, you'd get a figure that would update with a plot 1 second after being displayed. Instead, you'll get an AttributeError:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-346b07a4494a> in <module>()
     13 timer = fig.canvas.new_timer(500, [(callback, [ax], {})])
     14 timer.single_shot = True
---> 15 timer.start()
     16 #timer.stop()
     17 

/home/jofer/anaconda/lib/python2.7/site-packages/matplotlib/backend_bases.pyc in start(self, interval)
   1218         if interval is not None:
   1219             self._set_interval(interval)
-> 1220         self._timer_start()
   1221 
   1222     def stop(self):

/home/jofer/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_nbagg.pyc in _timer_start(self)
    186                 self._on_timer,
    187                 self.interval)
--> 188         self._timer.start()
    189 
    190     def _timer_stop(self):

AttributeError: '_Timeout' object has no attribute 'start'

Fully fixing this issue is slightly more complex than it seems at first glance. Basically, single-shot timers need to follow a completely different code path than regular timers when using Tornado.

I've added some additional user acceptance tests to /lib/matplotlib/backends/web_backend/nbagg_uat.ipynb and can vouch that the current changes don't break any of the manual user acceptance tests in the notebook.

@tacaswell tacaswell added this to the next point release milestone Aug 10, 2015
@tacaswell
Copy link
Member

The single-shot time on UAT 17 runs indefinitely for me

"text = ax.text(0.5, 0.5, '', ha='center') \n",
"timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
"\n",
"time.single_shot = True\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be timer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops! I'd fixed that in the notebook I was running but forgot to save it before committing. Thanks for catching that!

@joferkington
Copy link
Contributor Author

@tacaswell - The typo-fix in UAT17 should fix the indefinitely-running problem. I'll verify it tonight when I can test it (at work now). Thanks for catching that!

tacaswell added a commit that referenced this pull request Aug 12, 2015
FIX: single-shot timers in nbagg backend
@tacaswell tacaswell merged commit 7eadf59 into matplotlib:master Aug 12, 2015
@tacaswell
Copy link
Member

@joferkington Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants