This is easier with mplcursors. There's a similar example of extracting the data and labels for the annotation from a dataframe to plug into. Implemented with your example it is:
%matplotlib ipympl
# based on https://mplcursors.readthedocs.io/en/stable/examples/dataframe.html
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.patheffects import withSimplePatchShadow
import mplcursors
df = sns.load_dataset('diamonds')[:10]
sbsp = sns.scatterplot(x="carat", y="price", hue="cut", data=df)
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="wheat",
edgecolor="#ddd",
linewidth=0.5,
path_effects=[withSimplePatchShadow(offset=(1.5, -1.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)),
)
return cursor
def on_add(index):
item = df.iloc[index]
parts = [
f"Cut: {item.cut}", # f"Cut: {diamonds.loc[idx, 'cut']}\n"
f"Clarity: {item.clarity}", # f"Clarity: {diamonds.loc[idx, 'clarity']}\n"
f"Color: {item.color}", #f"Color: {diamonds.loc[idx, 'color']}"
]
return "\n".join(parts)
sbsp.figure.canvas.header_visible = False # Hide the Figure name at the top of the figure;based on https://matplotlib.org/ipympl/examples/full-example.html
show_hover_panel(on_add)
plt.show();
That's for running it in JupyterLab where ipympl
has been installed.
For running it in Jupyter Notebook at present, change the first line to %matplotlib notebook
.
I saw it be smoother in JupyterLab.
I'll point to ways to try the code in both interfaces without installing anything on your system below.
(Your approach may be able to work with more incorporation of things here. However, there's already a very similar answer with mplcursors)
(The places and steps to run the code outlined below were worked out primarily for the Matplotlib option here yesterday. Noting that here as there were some quirks to the ipympl offering launching and I worry that I may miss updating each place if something changes.)
Try it in JupyterLab in conjunction with ipympl without touching your system
This will allow you to try the code in JupyterLab without installing anything on your own system.
Go to here. Sadly the link currently goes to a dead end and doesn't seem to build a new image right now. Fortunately, right now this offering works for launching a session where ipympl is already installed.
When that session opens, run in a notebook %pip install mplcursors seaborn
. Let that installation command run to install both mplcursors and seaborn and then restart the kernel.
Make a new cell and paste in the code from above and run it.
Try it Jupyter Notebook classic interface without touching your system
This will allow you to try the code in the present classic Jupyter Notebook interface (soon-to-be more-often-referenced as 'the document-centric interface' as the underlying machinery for Jupyter Notebook 7 will use JupyterLab components) without installing anything on your own system.
Go here and press 'launch binder'. A temporary, remote session will spin up served via MyBinder.
Make a new cell and simply add %matplotlib notebook
at the top of the cell. Then add the code above to the cell, leaving off the first line of the suggested code, so that you effectively substitute %matplotlib notebook
in place of %matplotlib ipympl
.
Run the cell.