Skip to content

Missing Events in NbAgg Backend #3963

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

Closed
blink1073 opened this issue Jan 3, 2015 · 29 comments · Fixed by #3965
Closed

Missing Events in NbAgg Backend #3963

blink1073 opened this issue Jan 3, 2015 · 29 comments · Fixed by #3965
Assignees
Milestone

Comments

@blink1073
Copy link
Member

Perhaps I am missing something, but it appears that some events are not implement for the nbagg backend? Using the script below, I have seen the following work: motion_notify_event, axes_enter_event, button_press_event. The following have not worked: figure_enter_event, resize_event, key_press_event, scroll_event. The only one I'm really missing is key_press_event.

import matplotlib
matplotlib.use('nbagg')
from matplotlib import pyplot as plt
plt.plot(range(3))
evt = None
def on_event(event):
    global evt
    evt = event
plt.gcf().canvas.mpl_connect('button_press_event', on_event)
plt.show()

I then check the value of evt in another cell to make sure it is getting updated. I am using matplotlib ab549ac and IPython 2.3.1.

@blink1073
Copy link
Member Author

I added a console.log print here, and the function is getting called for keyboard events when using the webagg backend but not the nbagg backend. I tried the same here and it is called by both backends. The 'scroll_event' works on webagg but not nbagg.

@blink1073
Copy link
Member Author

Just to pile on, the following picker demo did not work either:

import numpy as np
x, y, c, s = np.random.rand(4, 100)
ind = 0

def onpick3(event):
    global ind
    ind = event.ind

fig, ax = plt.subplots()
col = ax.scatter(x, y, 100*s, c, picker=True)
fig.canvas.mpl_connect('pick_event', onpick3)
plt.show()

The picker demo also does not work in the webagg backend (I used print(event) in the callback).

@tacaswell
Copy link
Member

Your going to make me learn javascript aren't you .....

@blink1073
Copy link
Member Author

I'm with you brother, I had resisted until this week...

@blink1073
Copy link
Member Author

I think somehow the IPython KeyboardManager needs to be prevented from stealing all the events for the document.

@blink1073
Copy link
Member Author

Its in IPython/html/static/notebook/js/keyboardmanager.js

@tacaswell
Copy link
Member

Ah, I was trying to figure out what was different between webagg/nbagg that was eating keyboard events. It makes a good deal of sense that IPython is what is eating the keystrokes....

Presumably they have a way of getting around this when entering code into cells.

@blink1073
Copy link
Member Author

Yes and maybe we should ask the the IPython devs about scroll events since they seem to eat those as well.

@tacaswell
Copy link
Member

@minrk Any advice?

The problem seems to be that the notebook keyboard handler is snarfing all of the keystrokes before they get to the <div> tag that mpl has keydown event listeners on.

@tacaswell
Copy link
Member

attn @pelson

@minrk
Copy link
Contributor

minrk commented Jan 3, 2015

To avoid IPython handling keyboard events on a particular element, you will want to call

IPython.notebook.keyboard_manager.register_events($element);

Generally, you would call this once on your outermost div when you create it.

@pelson
Copy link
Member

pelson commented Jan 3, 2015

Thanks @minrk - that is the kind of knowledge that would take a good while to figure out. @blink1073 - how do you want to proceed? Do you want to take a look at this?

@eyurtsev
Copy link
Contributor

eyurtsev commented Jan 3, 2015

Not related to the fix. But if you guys are modifying mpl.js it won't hurt to fix a typo in line $43.

- this.focus_on_mousover = false;
+ this.focus_on_mouseover = false;

https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/web_backend/mpl.js#L43

@blink1073
Copy link
Member Author

I'll give it a shot.

@blink1073
Copy link
Member Author

I fear I may be out of my depth. Here's what I tried (note that the keyboard_manager has moved between IPython 2.3 and 3.0):

diff --git a/lib/matplotlib/backends/web_backend/nbagg_mpl.js b/lib/matplotlib/backends/web_backend/nbagg_mpl.js
index 71c52f9..3dd7844 100644
--- a/lib/matplotlib/backends/web_backend/nbagg_mpl.js
+++ b/lib/matplotlib/backends/web_backend/nbagg_mpl.js
@@ -49,6 +49,7 @@ mpl.mpl_figure_comm = function(comm, msg) {
         return false;
     });

+    IPython.keyboard_manager.register_events($(fig.root));
 };

 mpl.figure.prototype.handle_close = function(fig, msg) {

Keyboard events are still getting eaten. I tried a few syntax variations on fig.root, but I'm just stabbing in the dark.

@tacaswell
Copy link
Member

@blink1073 I am also whacking at this (but keep getting side tracked).

@tacaswell
Copy link
Member

@minrk The problem seems to be that the relevant are never getting focus which I think might be a problem on our end.

@tacaswell
Copy link
Member

Ha! I have it working, PR on the way.

@minrk
Copy link
Contributor

minrk commented Jan 4, 2015

The problem seems to be that the relevant are never getting focus

Ah, yes. focus is a constant source of headaches for us.

@blink1073
Copy link
Member Author

Update: the picker is working (in master), with this demo:

import matplotlib
import itertools
import numpy as np
matplotlib.use('nbagg')
import matplotlib.pyplot as plt
plt.close('all')
fig, ax = plt.subplots()
x = np.linspace(0,10,100)
y = np.sin(x)
ln, = ax.plot(x,y, 'o', picker=5)
evt = []
colors = iter(itertools.cycle(['r', 'g', 'b', 'k', 'c']))
def on_event(event):
    evt.append(event)
    ln.set_color(next(colors))
    fig.canvas.draw()
    fig.canvas.draw_idle()
fig.canvas.mpl_connect('key_press_event', on_event)
fig.canvas.mpl_connect('pick_event', on_event)
plt.show()

@pelson
Copy link
Member

pelson commented Jan 6, 2015

Woo. Thanks for working on this @blink1073 & @tacaswell. We should really get around to adding nbagg to the %matplotlib% magic in IPython.

@tacaswell
Copy link
Member

The magic has been set up on their side already

On Tue, Jan 6, 2015, 02:05 Phil Elson notifications@github.com wrote:

Woo. Thanks for working on this @blink1073 https://github.com/blink1073
& @tacaswell https://github.com/tacaswell. We should really get around
to adding nbagg to the %matplotlib% magic in IPython.


Reply to this email directly or view it on GitHub
#3963 (comment)
.

@blink1073
Copy link
Member Author

This isn't technically closed until #3968 is merged.

@tacaswell
Copy link
Member

It probably got auto-magic closed via one of my commit messages.

@blink1073
Copy link
Member Author

I think it was from the first line in your PR description.

@tacaswell
Copy link
Member

Both are now merged and backported.

@tacaswell
Copy link
Member

And the UAT all passes on the cherry-picked 1.4.x branch, hurray!

@blink1073
Copy link
Member Author

Well that what easy, it only took two us learning a new language. 😄

@pelson
Copy link
Member

pelson commented Jan 12, 2015

Well that what easy, it only took two us learning a new language.

And tripling the nbagg backend bus factor!

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

Successfully merging a pull request may close this issue.

5 participants