Showing information when mouse over on scatter plot

57 Views Asked by At

I've been struggling on showing correct information on the scatter plot. Here is a example.

import matplotlib.pyplot as plt
import mplcursors

data = [
    ["Name1", 10, 20],
    ["Name2", 30, 40],
    ["Name3", 50, 60]
]

x_values = ["G1", "G2"]
y_values = [(row[1], row[2]) for row in data]
names = [row[0] for row in data]

fig, ax = plt.subplots()

scatter_plots = []

for i in range(len(data)):
    scatter = ax.scatter(x_values, y_values[i])
    scatter_plots.append(scatter)

ax.set_xlabel("X-axis")
ax.set_ylabel("Y-axis")
ax.set_title("Scatter Plot")

cursor = mplcursors.cursor(scatter_plots, hover=True)
cursor.connect("add", lambda sel: sel.annotation.set_text(names[sel.target.index]))

plt.show()

In this case, when my cursor moves on each plot(same color), it should show same name. However, due to sel.target.index which indicates x axis in the plot only, it shows wrong name and even I can't get Name3 displayed. I've been looking for a way to handle double array in mouseover case for row but no luck yet. Any good idea to show correct name on each plot when mouse over by indicating row of the array?

I'd like to have correct name displayed corresponding to the data.

1

There are 1 best solutions below

0
Christian Karcher On

One way to achieve this is to find out the correct sel.artist and associate the correct annotation with it:

enter image description here

import matplotlib.pyplot as plt
import mplcursors

data = [["Name1", 10, 20], ["Name2", 30, 40], ["Name3", 50, 60]]

x = ["G1", "G2"]
names = [row[0] for row in data]

scatter_plots = [plt.scatter(x, y) for y in [(row[1], row[2]) for row in data]]


# function for annotations
def cursor_annotation(sel):
    """Iterate over all plots and names, match it with the current selection."""
    for artist, name in zip(scatter_plots, names):
        if sel.artist == artist:
            sel.annotation.set_text(name)
            break


cursor = mplcursors.cursor(scatter_plots, hover=True)
cursor.connect("add", cursor_annotation)

plt.show()