diff --git a/CHANGELOG.md b/CHANGELOG.md index 8378fcf347..a650665c87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix `mpl_to_plotly` conversion of matplotlib contour lines and line collections: close contour rings ending with `Z` codes, support dash styles, convert date x-axes, separate disjoint subpaths with `None` separators, hide line collection traces from the legend by default, and group consecutive same-style lines into single traces [[#5770](https://github.com/plotly/plotly.py/pull/5770)], with thanks to @robertoffmoura for the contribution! - Fix `plotly.io.write_images` ignoring `layout.width`/`layout.height` (and the template's) and exporting every figure at the default 700x500 size; it now uses the same width/height priority as `write_image` and `to_image` [[#5784](https://github.com/plotly/plotly.py/pull/5784)], with thanks to @breken-ai for the contribution! - Fix color utilities mutating the list of colors passed to them [[#5836](https://github.com/plotly/plotly.py/pull/5836)], with thanks to @Enesuygurs for the contribution! +- Fix timezone-aware `DatetimeIndex` values being converted to an object array, which made figure creation and `to_json()` much slower than for a timezone-aware Series; their JSON output now matches the Series output, without the UTC offset [[#5870](https://github.com/plotly/plotly.py/pull/5870)], with thanks to @somaz94 for the contribution! ## [7.1.0] - 2026-09-15 diff --git a/_plotly_utils/basevalidators.py b/_plotly_utils/basevalidators.py index 1ffc63e5ad..6b26d0653e 100644 --- a/_plotly_utils/basevalidators.py +++ b/_plotly_utils/basevalidators.py @@ -105,6 +105,11 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False): "O": "object", } + pd = get_module("pandas", should_load=False) + if pd is not None and isinstance(v, pd.Index): + # Narwhals passes an Index through unchanged, so use the Series path for it + v = v.to_series() + # With `pass_through=True`, the original object will be returned if unable to convert # to a Narwhals DataFrame or Series. v = nw.from_native(v, allow_series=True, pass_through=True) diff --git a/tests/test_plotly_utils/validators/test_pandas_series_input.py b/tests/test_plotly_utils/validators/test_pandas_series_input.py index 04e41a722d..5706025117 100644 --- a/tests/test_plotly_utils/validators/test_pandas_series_input.py +++ b/tests/test_plotly_utils/validators/test_pandas_series_input.py @@ -186,6 +186,15 @@ def test_data_array_validator_dates_series( np.testing.assert_array_equal(res, dates_array) +def test_data_array_validator_tz_aware_datetime_index(data_array_validator): + index = pd.date_range("2024-03-30", periods=3, freq="D", tz="Europe/Berlin") + res = data_array_validator.validate_coerce(index) + + assert isinstance(res, np.ndarray) + assert res.dtype.kind == "M" + np.testing.assert_array_equal(res, index.tz_localize(None).to_numpy()) + + def test_data_array_validator_dates_dataframe( data_array_validator, datetime_pandas, dates_array ):