I'm trying to plot a multi-dimensional scatterplot across several visual properties (facets, hue, shape, x, y). I'm also trying to get a tooltip on cursor hover to show additional properties of the point. (I'm using seaborn + mplcursors, but I'm not married to this solution.) The problem is that the hover has the wrong index in the dataset and displays the wrong information. You can see the same in the following toy example assembled from two examples from the seaborn and mplcursors websites.
I believe I've diagnosed the issue to the cursor.connect() not returning the proper index in the dataframe. I can get this example to work if I reduce the number of modifiers (hue, col, row, etc), but it doesn't work with all of these included.
import seaborn as sns
import matplotlib.pyplot as plt
import mplcursors
df = sns.load_dataset("tips")
sns.relplot(data=df, x="total_bill", y="tip", hue="day", col="time", row="sex")
def show_hover_panel(get_text_func=None):
cursor = mplcursors.cursor(
hover=2, # Transient
annotation_kwargs=dict(
bbox=dict(
boxstyle="square,pad=0.5",
facecolor="white",
edgecolor="#ddd",
linewidth=0.5,
),
linespacing=1.5,
arrowprops=None,
),
highlight=True,
highlight_kwargs=dict(linewidth=2),
)
if get_text_func:
cursor.connect(
event="add",
func=lambda sel: sel.annotation.set_text(get_text_func(sel.index)), # <- this doesn't appear to return the correct integer index in the dataframe
)
return cursor
def on_add(index):
item = df.iloc[index]
parts = [
f"total_bill: {item.total_bill}",
f"tip: {item.tip}",
f"day: ${item.day}",
f"time: ${item.time}",
f"sex: ${item.sex}",
]
return "\n".join(parts)
show_hover_panel(on_add)
plt.show()
What I tried:
- minimum viable example
- removing modifiers = works
- traced back the correct point locations based on the data BUT when I pass the index to the tooltip I notice that the index doesn't correspond to the proper index in he dataframe.