diff --git a/CHANGELOG.md b/CHANGELOG.md index c92c3ea6d6..d82248011d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added +- Add the `custom_data` argument to `px.histogram`, so extra columns can be attached to histogram traces for use in Dash callbacks and selection events, as in the other Plotly Express functions [[#3859](https://github.com/plotly/plotly.py/issues/3859)] + ### Fixed - Fix `mpl_to_plotly` tick marker mirroring, axis positioning, and trace visibility for twinned and overlaid subplots (such as `twinx` and `twiny`) [[#5310](https://github.com/plotly/plotly.py/pull/5310)], with thanks to @robertoffmoura for the contribution! - Fix `mpl_to_plotly` losing matplotlib axis line colors by exporting the color of each axis's displayed spine to the plotly x and y axis `linecolor` [[#5311](https://github.com/plotly/plotly.py/pull/5311)], with thanks to @robertoffmoura for the contribution! diff --git a/plotly/express/_chart_types.py b/plotly/express/_chart_types.py index f78a257cab..d9115745cc 100644 --- a/plotly/express/_chart_types.py +++ b/plotly/express/_chart_types.py @@ -462,6 +462,7 @@ def histogram( facet_col_spacing=None, hover_name=None, hover_data=None, + custom_data=None, animation_frame=None, animation_group=None, category_orders=None, diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index d4773de66f..88f20b6fed 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -68,6 +68,28 @@ def test_custom_data_scatter(backend): ) +def test_custom_data_histogram(backend): + tips = nw.from_native(px.data.tips(return_type=backend)) + # No custom data + fig = px.histogram(tips.to_native(), x="total_bill") + assert fig.data[0].customdata is None + # Custom data is carried per row of the input, not per bin + fig = px.histogram(tips.to_native(), x="total_bill", custom_data=["tip", "day"]) + assert fig.data[0].customdata.shape == (len(tips), 2) + assert np.all(fig.data[0].customdata[:, 0] == tips.get_column("tip").to_numpy()) + assert np.all(fig.data[0].customdata[:, 1] == tips.get_column("day").to_numpy()) + # Bins are aggregates, so custom data does not show up in the hover label + assert fig.data[0].hovertemplate == "total_bill=%{x}
count=%{y}" + # Each colored trace carries the custom data of its own rows + fig = px.histogram( + tips.to_native(), x="total_bill", color="sex", custom_data=["tip"] + ) + for trace in fig.data: + group = tips.filter(nw.col("sex") == trace.name) + assert trace.customdata.shape == (len(group), 1) + assert np.all(trace.customdata[:, 0] == group.get_column("tip").to_numpy()) + + def test_labels(backend): tips = nw.from_native(px.data.tips(return_type=backend)) fig = px.scatter(