joferkington / mpldatacursor

Interactive "data cursors" (a.k.a. annotation pop-ups) for matplotlib
MIT License
194 stars 47 forks source link

mpldatacursor and webagg #43

Open chan-y-park opened 9 years ago

chan-y-park commented 9 years ago

Dear Joe,

First of all, thank you so much for the last feedback about mpldatacursor on Jupyter notebook!

This time I am trying a bit different thing, which is using matplotlib webagg backend. It seems that the backend is a very nice one to build a web UI for matplotlib and I would like to use mpldatacursor with it, but when I naively put mpldatacursor.datacursor() in the source code of https://github.com/matplotlib/matplotlib/blob/master/examples/user_interfaces/embedding_webagg.py, that is,

def create_figure():
    """
    Creates a simple example figure.
    """
    fig = Figure()
    a = fig.add_subplot(111)
    t = np.arange(0.0, 3.0, 0.01)
    s = np.sin(2 * np.pi * t)
    a.plot(t, s)
    mpldatacursor.datacursor()
    return fig

It doesn't complain but nothing happens in the plot. Then I tried something different,

def create_figure():
    """
    Creates a simple example figure.
    """
    fig = Figure()
    a = fig.add_subplot(111)
    t = np.arange(0.0, 3.0, 0.01)
    s = np.sin(2 * np.pi * t)
    a.plot(t, s)
    mpldatacursor.datacursor(
        axes=fig.axes,
    )
    return fig

Then I get the following error:

Traceback (most recent call last):
  File "embedding_webagg.py", line 242, in <module>
    figure = create_figure()
  File "embedding_webagg.py", line 46, in create_figure
    axes=fig.axes, 
  File "/home/chan/anaconda/lib/python2.7/site-packages/mpldatacursor/convenience.py", line 168, in datacursor
    return DataCursor(artists, **kwargs)
  File "/home/chan/anaconda/lib/python2.7/site-packages/mpldatacursor/datacursor.py", line 207, in __init__
    self.ax_timer[ax] = ax.figure.canvas.new_timer(interval=interval,
AttributeError: 'NoneType' object has no attribute 'new_timer'

Will it be a huge work to make mpldatacursor work with webagg? If that can be done then it would be really awesome!

Best, Chan

joferkington commented 9 years ago

Thanks for the bug report, and sorry for my delay in responding!

As for the first problem, any time the pyplot interface isn't used to create the figure, there's no way to detect which figures/axes exist. Therefore, anytime you bypass pyplot (e.g. embedding in a gui), you'll have to explicitly specify which axes or artists mpldatacursor should work with. I should make this more clear in the documentation, though.

For the second part, it looks like timers aren't implemented at all for the webagg backend. This is a bug in matplotlib, but I should be handling it in mpldatacursor regardless. I've added a workaround in 7531fe287eb774bbeaed8a7e1c0371a41bd7d86b that should mask the problem. You'll have slightly worse performance for backends that don't implement timers, but webagg is going to have poor performance regardless.

If you have a chance, try installing from git master and let me know if this fixes your problem (it does for me, but you may hit other issues). I'll probably release another point release soon that will include this fix as well as a couple of others.

chan-y-park commented 9 years ago

Thank you so much for the help! I will try it and get back to you. By the way, could you report to the matplotlib community that there is such a bug in webagg? It would be nice if webagg can grow into one of the standard backends.