Skip to content

Commit 4954663

Browse files
committed
aspect ratio: pixels are not square by default for xarrays, plus timedate handling
1 parent f449c04 commit 4954663

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

packages/python/plotly/plotly/express/_imshow.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def imshow(
7575
template=None,
7676
width=None,
7777
height=None,
78+
aspect=None
7879
):
7980
"""
8081
Display an image, i.e. data on a 2D regular raster.
@@ -129,6 +130,14 @@ def imshow(
129130
height: number
130131
The figure height in pixels, defaults to 600.
131132
133+
aspect: 'equal', 'auto', or None
134+
- 'equal': Ensures an aspect ratio of 1 or pixels (square pixels)
135+
- 'auto': The axes is kept fixed and the aspect ratio of pixels is
136+
adjusted so that the data fit in the axes. In general, this will
137+
result in non-square pixels.
138+
- if None, 'equal' is used for numpy arrays and 'auto' for xarrays
139+
(which have typically heterogeneous coordinates)
140+
132141
Returns
133142
-------
134143
fig : graph_objects.Figure containing the displayed image
@@ -151,11 +160,19 @@ def imshow(
151160
if xarray_imported:
152161
if isinstance(img, xarray.DataArray):
153162
y_label, x_label = img.dims[0], img.dims[1]
163+
# np.datetime64 is not handled correctly by go.Heatmap
164+
for ax in [x_label, y_label]:
165+
if np.issubdtype(img.coords[ax].dtype, np.datetime64):
166+
img.coords[ax] = img.coords[ax].astype(str)
154167
x = img.coords[x_label]
155168
y = img.coords[y_label]
156-
x_range = (img.coords[x_label][0], img.coords[x_label][-1])
157-
y_range = (img.coords[y_label][0], img.coords[y_label][-1])
158169
img_is_xarray = True
170+
if aspect is None:
171+
aspect = 'auto'
172+
173+
if not img_is_xarray:
174+
if aspect is None:
175+
aspect = 'equal'
159176

160177
img = np.asanyarray(img)
161178

@@ -167,10 +184,10 @@ def imshow(
167184
if img.ndim == 2:
168185
trace = go.Heatmap(z=img, coloraxis="coloraxis1")
169186
autorange = True if origin == "lower" else "reversed"
170-
layout = dict(
171-
xaxis=dict(scaleanchor="y", constrain="domain"),
172-
yaxis=dict(autorange=autorange, constrain="domain"),
173-
)
187+
layout = dict(yaxis=dict(autorange=autorange))
188+
if aspect == 'equal':
189+
layout["xaxis"] = dict(scaleanchor="y", constrain="domain")
190+
layout["yaxis"]["constrain"] = "domain"
174191
colorscale_validator = ColorscaleValidator("colorscale", "imshow")
175192
if zmin is not None and zmax is None:
176193
zmax = img.max()

0 commit comments

Comments
 (0)