You're already on the right track with your current code. You're basically just missing a call to plt.draw()
in your onpick
function.
However, in our discussion in the comments, mpldatacursor
came up, and you asked about an example of doing things that way.
The current HighlightingDataCursor
in mpldatacursor
is set up around the idea of highlighting an entire Line2D
artist, not just a particular index of it. (It's deliberately a bit limited, as there's no good way to draw an arbitrary highlight for any artist in matplotlib, so I kept the highlighting parts small.)
However, you could subclass things similar to this (assumes you're using plot
and want the first thing you plot in each axes to be used). I'm also illustrating using point_labels
, in case you want to have different labels for each point shown.:
import numpy as np
import matplotlib.pyplot as plt
from mpldatacursor import HighlightingDataCursor, DataCursor
def main():
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax, marker in zip(axes.flat, ['o', '^', 's', '*']):
x, y = np.random.random((2,20))
ax.plot(x, y, ls='', marker=marker)
IndexedHighlight(axes.flat, point_labels=[str(i) for i in range(20)])
plt.show()
class IndexedHighlight(HighlightingDataCursor):
def __init__(self, axes, **kwargs):
# Use the first plotted Line2D in each axes
artists = [ax.lines[0] for ax in axes]
kwargs['display'] = 'single'
HighlightingDataCursor.__init__(self, artists, **kwargs)
self.highlights = [self.create_highlight(artist) for artist in artists]
plt.setp(self.highlights, visible=False)
def update(self, event, annotation):
# Hide all other annotations
plt.setp(self.highlights, visible=False)
# Highlight everything with the same index.
artist, ind = event.artist, event.ind
for original, highlight in zip(self.artists, self.highlights):
x, y = original.get_data()
highlight.set(visible=True, xdata=x[ind], ydata=y[ind])
DataCursor.update(self, event, annotation)
main()
Again, this assumes you're using plot
and not, say, scatter
. It is possible to do this with scatter
, but you need to change an annoyingly large amount of details. (There's no general way to highlight an arbitrary matplotlib artist, so you have to have a lot of very verbose code to deal with each type of artist individually.)
Hope it's useful, at any rate.