11

I have a graph with some line segments (LineCollection) and some points. These lines and points have some values associated with them that are not graphed. I would like to be able to add a mouse-over tool-tip or other method of easily finding the associated value for the points and line. Is this possible for either points or lines segments?

John Salvatier
  • 3,077
  • 4
  • 26
  • 31
  • 3
    [Here's one example from matplotlib](http://matplotlib.sourceforge.net/examples/pylab_examples/cursor_demo.html), which I found on Google. [Then here's another popular SO answer.](http://stackoverflow.com/a/4674445/1020470) [Well, and this one too, that also points to the matplotlib example.](http://stackoverflow.com/a/7909589/1020470) – Mark Mikofski Aug 11 '12 at 03:10

3 Answers3

6

For points, I have found a way, but you have to use the WX backend

"""Example of how to use wx tooltips on a matplotlib figure window.
Adapted from http://osdir.com/ml/python.matplotlib.devel/2006-09/msg00048.html"""

import matplotlib as mpl
mpl.use('WXAgg')
mpl.interactive(False)

import pylab as pl
from pylab import get_current_fig_manager as gcfm
import wx
import numpy as np
import random


class wxToolTipExample(object):
    def __init__(self):
        self.figure = pl.figure()
        self.axis = self.figure.add_subplot(111)

        # create a long tooltip with newline to get around wx bug (in v2.6.3.3)
        # where newlines aren't recognized on subsequent self.tooltip.SetTip() calls
        self.tooltip = wx.ToolTip(tip='tip with a long %s line and a newline\n' % (' '*100))
        gcfm().canvas.SetToolTip(self.tooltip)
        self.tooltip.Enable(False)
        self.tooltip.SetDelay(0)
        self.figure.canvas.mpl_connect('motion_notify_event', self._onMotion)

        self.dataX = np.arange(0, 100)
        self.dataY = [random.random()*100.0 for x in xrange(len(self.dataX))]
        self.axis.plot(self.dataX, self.dataY, linestyle='-', marker='o', markersize=10, label='myplot')

    def _onMotion(self, event):
        collisionFound = False
        if event.xdata != None and event.ydata != None: # mouse is inside the axes
            for i in xrange(len(self.dataX)):
                radius = 1
                if abs(event.xdata - self.dataX[i]) < radius and abs(event.ydata - self.dataY[i]) < radius:
                    top = tip='x=%f\ny=%f' % (event.xdata, event.ydata)
                    self.tooltip.SetTip(tip) 
                    self.tooltip.Enable(True)
                    collisionFound = True
                    break
        if not collisionFound:
            self.tooltip.Enable(False)



example = wxToolTipExample()
pl.show()
idrinkpabst
  • 1,838
  • 23
  • 25
  • 1
    It would be extremely nice if enthought supported a feature like this for components more generally... – aestrivex May 08 '13 at 20:28
2

It's an old thread, but in case anyone is looking for how to add tooltips to lines, this works:

import matplotlib.pyplot as plt
import numpy as np
import mpld3

f, ax = plt.subplots()
x1 = np.array([0,100], int)
x2 = np.array([10,110], int)
y = np.array([0,100], int)

line = ax.plot(x1, y)
mpld3.plugins.connect(f, mpld3.plugins.LineLabelTooltip(line[0], label='label 1'))

line = ax.plot(x2, y)
mpld3.plugins.connect(f, mpld3.plugins.LineLabelTooltip(line[0], label='label 2'))

mpld3.show()
Ivan Chaer
  • 6,980
  • 1
  • 38
  • 48
1

Perhaps a variation on this recipe would do what you want for points? At least it isn't restricted to wx backend.

MartyMacGyver
  • 9,483
  • 11
  • 47
  • 67
RuiDC
  • 8,403
  • 7
  • 26
  • 21