how to make the mplcursors module only show labels for points plotted on a line graph
Asked Answered
C

2

5

So I have a line graph where the mplcursors module in python shows the coordinates for any point on it.

I want it to only show labels for points that are explicitly plotted, not the ones that are in-between the plotted points and happen to be on the line connecting them.

I am willing to update the question with the code if you want.

Christyna answered 21/8, 2020 at 22:1 Comment(0)
J
6

One approach is to create an invisible scatterplot for the same points, and attach the mplcursor to it.

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

x = np.arange(30)
y = 30 + np.random.randint(-5, 6, x.size).cumsum()

fig, ax = plt.subplots()
ax.plot(x, y)
dots = ax.scatter(x, y, color='none')

mplcursors.cursor(dots, hover=True)

plt.show()

example plot

The functionality could be wrapped into a helper function:

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

def create_mplcursor_for_points_on_line(lines, ax=None, annotation_func=None, **kwargs):
    ax = ax or plt.gca()
    scats = [ax.scatter(x=line.get_xdata(), y=line.get_ydata(), color='none') for line in lines]
    cursor = mplcursors.cursor(scats, **kwargs)
    if annotation_func is not None:
        cursor.connect('add', annotation_func)
    return cursor

x = np.arange(10, 301, 10)
y = 30 + np.random.randint(-5, 6, x.size).cumsum()

fig, ax = plt.subplots()
lines = ax.plot(x, y)
cursor = create_mplcursor_for_points_on_line(lines, ax=ax, hover=True)

plt.show()
Jurassic answered 21/8, 2020 at 23:29 Comment(2)
It can be a bit tedious but it's still an answer nonetheless, so I upvoted itChristyna
What about a helper function which creates the scatter plot(s)?Jurassic
P
1

I cannot show the whole code

I have found a good solution to this problem. You can extract datapoints of linegraph with mplcursor function.

# Label functions 
def show_datapoints(sel):
    xi, yi = sel[0], sel[0]
    xi, yi = xi._xorig.tolist(), yi._yorig.tolist()
    sel.annotation.set_text('x: '+ str(xi[round(sel.target.index)]) +'\n'+ 'y: '+ str(yi[round(sel.target.index)]))

call the show_datapoints function in mplcursor to show datapoints

mplcursors.cursor(self.ax1).connect('add',show_datapoints)
Phytogeography answered 30/7, 2021 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.