For context, I'm trying to handle mouse events on instances of Collection
from matplotlib
. matplotlib
handles the mouse events too, the problem is that I'm doing this from networkx
, which uses matplotlib.pyplot.scatter
to plot nodes on a graph. I'm not modifying matplotlib
itself, because I don't think these features would be useful to matplotlib
.
I also want to be able to pick and choose which events are handled and allow users to choose what happens when a mouse event is detected. So, for example, if I want something to be draggable, I would allow it to handle mouse click, motion and unclick events. However, if I want it to just give me information about a node, it just needs to handle the mouse click event.
matplotlib
does have an example here, where they wrap the instance in a Draggable
class, connect to the mouse events and have functions to handle behaviour. In my case, I wouldn't know which events I would want to handle or I might not implement the callback functions for each event.
As I see it at the moment, one option is to create methods that could be bound to the instance:
import types
import matplotlib.pyplot as plt
def on_click(self, mouse_click_event):
'''callback on click event, mouse_click_event is passed
automatically by mpl_connect'''
pass
node_collection = plt.scatter(...) # Has a lot of arguments, returns a PathCollection
node_collection.on_click = types.MethodType(on_click, node_collection)
node_collection.figure.canvas.mpl_connect('button_press_event',
node_collection.on_click)
I think it would be relatively easy to make a series of functions that could connect the mouse events to the collection and add bound methods for the callbacks without everything clashing.
Is there a better way to be doing this? I've read up about class decorators, metaclasses and abstract base classes, but I don't think they are appropriate for my particular problem. Is there something else I haven't heard of (or more likely something that I have heard of and didn't figure to use...)?