diff --git a/CHANGELOG.md b/CHANGELOG.md index d8ed24c064e..85c4e05bacb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.14.3] - UNRELEASED + +### Fixed + +- `px.timeline()` now allows `hover_data` formatting of start and end times [3018](https://github.com/plotly/plotly.py/pull/3018) + + ## [4.14.2] - 2021-01-11 ### Updated diff --git a/packages/python/plotly/plotly/express/_core.py b/packages/python/plotly/plotly/express/_core.py index d29b90b46c3..fe362c7e1a1 100644 --- a/packages/python/plotly/plotly/express/_core.py +++ b/packages/python/plotly/plotly/express/_core.py @@ -375,9 +375,10 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref): trace_patch[error_xy] = {} trace_patch[error_xy][arr] = trace_data[attr_value] elif attr_name == "custom_data": - # here we store a data frame in customdata, and it's serialized - # as a list of row lists, which is what we want - trace_patch["customdata"] = trace_data[attr_value] + if len(attr_value) > 0: + # here we store a data frame in customdata, and it's serialized + # as a list of row lists, which is what we want + trace_patch["customdata"] = trace_data[attr_value] elif attr_name == "hover_name": if trace_spec.constructor not in [ go.Histogram, @@ -398,6 +399,13 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref): for col in attr_value: if hover_is_dict and not attr_value[col]: continue + if col in [ + args.get("x", None), + args.get("y", None), + args.get("z", None), + args.get("base", None), + ]: + continue try: position = args["custom_data"].index(col) except (ValueError, AttributeError, KeyError): @@ -408,9 +416,10 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref): position ) - # here we store a data frame in customdata, and it's serialized - # as a list of row lists, which is what we want - trace_patch["customdata"] = trace_data[customdata_cols] + if len(customdata_cols) > 0: + # here we store a data frame in customdata, and it's serialized + # as a list of row lists, which is what we want + trace_patch["customdata"] = trace_data[customdata_cols] elif attr_name == "color": if trace_spec.constructor in [go.Choropleth, go.Choroplethmapbox]: trace_patch["z"] = trace_data[attr_value] diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_px_input.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_px_input.py index eeb28283649..477e7dbcb04 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_px/test_px_input.py +++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_px_input.py @@ -309,7 +309,8 @@ def test_pass_df_columns(): marginal="rug", hover_data=tips.columns, ) - assert fig.data[1].hovertemplate.count("customdata") == len(tips.columns) + # the "- 2" is because we re-use x and y in the hovertemplate where possible + assert fig.data[1].hovertemplate.count("customdata") == len(tips.columns) - 2 tips_copy = px.data.tips() assert tips_copy.columns.equals(tips.columns)