Skip to content

How to add hover labels to a scatterplot in Plotly (with Code)

The Short Answer (TL;DR)

Pass hover_name to choose a tooltip heading and hover_data to include or format additional columns in a Plotly Express scatterplot. The tooltip displays row-level context while the point coordinates keep their original numeric values.

import pandas as pd, plotly.express as px
data = pd.DataFrame({"sample": ["A01", "A02", "B01"], "duration": [1, 2, 3], "response": [2.123, 3.876, 3.504]})
fig = px.scatter(data, x="duration", y="response", hover_name="sample", hover_data={"response": ":.2f"}); fig.write_html("hover-labels.html", include_plotlyjs=True, auto_open=False)

Detailed Implementation

This example uses synthetic data and does not need a network connection. Install the recorded package versions in a separate Python environment before running it.

python -m pip install pandas==3.0.6 plotly==7.1.0
import pandas as pd
import plotly.express as px

data = pd.DataFrame({
    "sample": ["A01", "A02", "B01", "B02"],
    "duration": [1.0, 2.0, 3.0, 4.0],
    "response": [2.123, 3.876, 3.504, 5.127],
    "batch": ["control", "control", "test", "test"],
})
fig = px.scatter(data, x="duration", y="response", hover_name="sample",
                 hover_data={"duration": ":.1f", "response": ":.2f", "batch": True},
                 labels={"duration": "Duration (minutes)", "response": "Response (units)",
                         "batch": "Batch"}, title="Measurements with sample context")
fig.update_traces(marker={"size": 12})
fig.update_layout(template="plotly_white")
fig.write_html("hover-labels.html", include_plotlyjs=True, full_html=True,
               auto_open=False)
# Open hover-labels.html in a browser and hover over a point.

The HTML chart contains four markers. Hover headings are A01, A02, B01 and B02, with formatted numeric fields and the matching batch; the original response values are preserved.

How are labels matched to points?

Plotly Express takes the coordinates and tooltip fields from the same dataframe rows. Keep sample identifiers alongside their measurements during joins or filtering, so a point cannot accidentally display another sample's identifier.

Does tooltip rounding change the plotted measurements?

The response field is displayed with two decimal places, while the underlying values retain their original precision. Use formatting for readability and keep numerical calculations on the original data; rounding before analysis changes those calculations.

How can the tooltip be inspected?

Open the generated HTML file in a browser and hover over a marker. Each heading identifies a sample, and the tooltip reports duration, response and batch. The export bundles the JavaScript required for this basic scatterplot, so a separate chart server is not required.

Mathematical Context

Each marker represents a coordinate pair (x_i, y_i), and its tooltip adds metadata from row i. Changing hover text does not estimate a trend, calculate a confidence interval or transform those coordinates. For example, the first response remains 2.123 in the figure data even though the tooltip formats that field to two decimal places. If two markers share coordinates, overlap can still make one difficult to select; tooltip content alone does not resolve overplotting.

\[ p_i=(x_i,y_i),\qquad h_i=(\mathrm{sample}_i,\mathrm{batch}_i) \]

Reproducibility

Executed with Python 3.12.14; pandas 3.0.6, plotly 7.1.0. Automated checks confirm the stated output properties.

Primary documentation

Related guides