diff --git a/CHANGELOG.md b/CHANGELOG.md index ea837e3d0b..6cd388d0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix concurrent first access to lazily initialized graph object properties, which could raise `ValueError("Invalid value")` [[#5691](https://github.com/plotly/plotly.py/pull/5691)], with thanks to @hb1915 for the contribution! - Fix `mpl_to_plotly` crashing on touching bars (such as `plt.hist`) due to floating-point noise producing negative `bargap` values by clamping `bargap` to `[0, 1]` [[#5696](https://github.com/plotly/plotly.py/pull/5696)], with thanks to @robertoffmoura for the contribution! - Fix `px.sunburst`, `px.treemap` and `px.icicle` listing sectors in a different order on every run when `path` is used with a Polars DataFrame; sectors now follow their order of first appearance for all dataframe backends [[#5766](https://github.com/plotly/plotly.py/pull/5766)], with thanks to @Irahan2 for the contribution! +- Fix `px.imshow` ignoring `aspect="auto"` for RGB and RGBA images, which kept their pixels square instead of stretching the image to fill the axes [[#5788](https://github.com/plotly/plotly.py/pull/5788)], with thanks to @jayzhou2309 for the contribution! ## [7.1.0] - 2026-09-15 diff --git a/plotly/express/_imshow.py b/plotly/express/_imshow.py index 576b114d51..c0229b0cc2 100644 --- a/plotly/express/_imshow.py +++ b/plotly/express/_imshow.py @@ -631,6 +631,9 @@ def imshow( if animation_frame: fig.frames = frame_list fig.update_layout(layout) + if trace["type"] == "image" and aspect == "auto": + # plotly.js anchors the y axis of an image trace to its x axis by default + fig.update_yaxes(scaleanchor=False) # Hover name, z or color if binary_string and rescale_image and not np.all(img == img_rescaled): # we rescaled the image, hence z is not displayed in hover since it does diff --git a/tests/test_optional/test_px/test_imshow.py b/tests/test_optional/test_px/test_imshow.py index 3a0e230eb9..79618310c5 100644 --- a/tests/test_optional/test_px/test_imshow.py +++ b/tests/test_optional/test_px/test_imshow.py @@ -414,6 +414,15 @@ def test_imshow_hovertemplate(binary_string): ) +@pytest.mark.parametrize("binary_string", [False, True]) +def test_image_trace_aspect(binary_string): + img = np.zeros((2, 10, 10, 3), dtype=np.uint8) + fig = px.imshow(img, facet_col=0, aspect="auto", binary_string=binary_string) + assert [ax.scaleanchor for ax in fig.select_yaxes()] == [False, False] + fig = px.imshow(img, facet_col=0, binary_string=binary_string) + assert [ax.scaleanchor for ax in fig.select_yaxes()] == [None, None] + + @pytest.mark.parametrize("facet_col", [0, 1, 2, -1]) @pytest.mark.parametrize("binary_string", [False, True]) def test_facet_col(facet_col, binary_string):