Skip to content

Commit 73dba81

Browse files
committed
hover can be a dict for skipping or formatting hover
1 parent 7cf2ad0 commit 73dba81

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

packages/python/plotly/plotly/express/_core.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,10 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref):
290290
go.Histogram2d,
291291
go.Histogram2dContour,
292292
]:
293+
hover_is_dict = isinstance(attr_value, dict)
293294
for col in attr_value:
295+
if hover_is_dict and not attr_value[col]:
296+
continue
294297
try:
295298
position = args["custom_data"].index(col)
296299
except (ValueError, AttributeError, KeyError):
@@ -387,7 +390,20 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref):
387390
go.Parcoords,
388391
go.Parcats,
389392
]:
390-
hover_lines = [k + "=" + v for k, v in mapping_labels.items()]
393+
# Modify mapping_labels according to hover_data keys
394+
# if hover_data is a dict
395+
mapping_labels_copy = OrderedDict(mapping_labels)
396+
if args["hover_data"] and isinstance(args["hover_data"], dict):
397+
for k, v in mapping_labels.items():
398+
if k in args["hover_data"]:
399+
if args["hover_data"][k]:
400+
if isinstance(args["hover_data"][k], str):
401+
mapping_labels_copy[k] = v.replace(
402+
"}", ":%s}" % args["hover_data"][k]
403+
)
404+
else:
405+
_ = mapping_labels_copy.pop(k)
406+
hover_lines = [k + "=" + v for k, v in mapping_labels_copy.items()]
391407
trace_patch["hovertemplate"] = hover_header + "<br>".join(hover_lines)
392408
trace_patch["hovertemplate"] += "<extra></extra>"
393409
return trace_patch, fit_results
@@ -1029,6 +1045,8 @@ def build_dataframe(args, attrables, array_attrables):
10291045
# Finally, update argument with column name now that column exists
10301046
if field_name not in array_attrables:
10311047
args[field_name] = str(col_name)
1048+
elif isinstance(args[field_name], dict):
1049+
pass
10321050
else:
10331051
args[field_name][i] = str(col_name)
10341052

packages/python/plotly/plotly/express/_doc.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,12 @@
180180
"Values from this column or array_like appear in bold in the hover tooltip.",
181181
],
182182
hover_data=[
183-
colref_list_type,
184-
colref_list_desc,
183+
"list of str or int, or Series or array-like, or dict",
184+
"Either a list of names of columns in `data_frame`, or pandas Series,",
185+
"or array_like objects",
186+
"or a dict with column names as keys, with values True (for default formatting)",
187+
"False (in order to remove this column from hover information),",
188+
"or a formatting string, for example '.3f'."
185189
"Values from these columns appear as extra data in the hover tooltip.",
186190
],
187191
custom_data=[
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import plotly.express as px
2+
import numpy as np
3+
import pandas as pd
4+
import pytest
5+
import plotly.graph_objects as go
6+
7+
8+
def test_skip_hover():
9+
df = px.data.iris()
10+
fig = px.scatter(
11+
df,
12+
x="petal_length",
13+
y="petal_width",
14+
size="species_id",
15+
hover_data={"petal_length": None, "petal_width": None},
16+
)
17+
assert fig.data[0].hovertemplate == "species_id=%{marker.size}<extra></extra>"
18+
19+
20+
def test_composite_hover():
21+
df = px.data.tips()
22+
fig = px.scatter(
23+
df,
24+
x="tip",
25+
y="total_bill",
26+
color="day",
27+
facet_row="time",
28+
hover_data={"day": False, "sex": True, "time": False, "total_bill": ".1f"},
29+
)
30+
assert (
31+
fig.data[0].hovertemplate
32+
== "tip=%{x}<br>total_bill=%{customdata[1]:.1f}<br>sex=%{customdata[0]}<extra></extra>"
33+
)

0 commit comments

Comments
 (0)