2

Below is code for a scatter plot annotated using mplcursors which uses two columns, labeling the points by a third column.

How can two values from two columns from a single dataframe be selected for annotation text in a single text box?

When instead of only "name" in the annotation text box, I would like both "height" and "name" to show in the annotation text box. Using df[['height', 'name']] does not work.

How can this be achieved otherwise?

df = pd.DataFrame(
    [("Alice", 163, 54),
     ("Bob", 174, 67),
     ("Charlie", 177, 73),
     ("Diane", 168, 57)],
    columns=["name", "height", "weight"])

df.plot.scatter("height", "weight")
mplcursors.cursor(multiple = True).connect("add", lambda sel: sel.annotation.set_text((df["name"])[sel.target.index]))
plt.show()
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

1 Answers1

1
  • df.loc[sel.target.index, ["name", 'height']].to_string(): correctly select the columns and row with .loc and then create a string with .to_string()
  • Tested in python 3.8, matplotlib 3.4.2, pandas 1.3.1, and jupyterlab 3.1.4
  • In mplcursors v0.5.1, Selection.target.index is deprecated, use Selection.index instead.
    • df.iloc[x.index, :] instead of df.iloc[x.target.index, :]
from mplcursors import cursor
import matplotlib.pyplot as plt
import pandas as pd

# for interactive plots in Jupyter Lab, use the following magic command, otherwise comment it out
%matplotlib qt 

df = pd.DataFrame([('Alice', 163, 54), ('Bob', 174, 67), ('Charlie', 177, 73), ('Diane', 168, 57)], columns=["name", "height", "weight"])

ax = df.plot(kind='scatter', x="height", y="weight", c='tab:blue')
cr = cursor(ax, hover=True, multiple=True)

cr.connect("add", lambda sel: sel.annotation.set_text((df.loc[sel.index, ["name", 'height']].to_string())))
plt.show()

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158