-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
xarray support in imshow #2166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
xarray support in imshow #2166
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
10a7b8e
xarray and imshow
emmanuelle f449c04
add xarray support in imshow
emmanuelle 4954663
aspect ratio: pixels are not square by default for xarrays, plus time…
emmanuelle b2ee809
imshow tutorial: add xarray example
emmanuelle 7563750
Merge branch 'master' into imshow-xarray
emmanuelle 8282e0a
update tutorials + use long_name
emmanuelle 568d1c1
change for CI
emmanuelle e9531df
Merge branch 'master' into imshow-xarray
emmanuelle d63a76a
comment
emmanuelle c107581
Merge branch 'imshow-xarray' of https://github.com/plotly/plotly.py i…
emmanuelle 70def8e
try to regenerate cache
emmanuelle 4e3717e
Merge branch 'master' into imshow-xarray
emmanuelle 1621271
tmp
emmanuelle ae984b0
added labels to imshow
emmanuelle 503e962
blacken
emmanuelle 11414e0
pinning orca
emmanuelle e64b05a
label
emmanuelle 33890df
removed colorbar key
emmanuelle e3ec430
corrected bug
emmanuelle d70fe14
datashader example
emmanuelle b051468
Update packages/python/plotly/plotly/express/_imshow.py
emmanuelle e8302d1
hover
emmanuelle 67dd774
Merge branch 'imshow-xarray' of https://github.com/plotly/plotly.py i…
emmanuelle 941779c
generalizing imshow(labels, x, y)
nicolaskruchten 21df030
docs and tests for imshow changes
nicolaskruchten File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,13 @@ | |
from ._core import apply_default_cascade | ||
import numpy as np | ||
|
||
try: | ||
import xarray | ||
|
||
xarray_imported = True | ||
except ImportError: | ||
xarray_imported = False | ||
|
||
_float_types = [] | ||
|
||
# Adapted from skimage.util.dtype | ||
|
@@ -61,21 +68,23 @@ def imshow( | |
zmin=None, | ||
zmax=None, | ||
origin=None, | ||
labels={}, | ||
color_continuous_scale=None, | ||
color_continuous_midpoint=None, | ||
range_color=None, | ||
title=None, | ||
template=None, | ||
width=None, | ||
height=None, | ||
aspect=None, | ||
): | ||
""" | ||
Display an image, i.e. data on a 2D regular raster. | ||
|
||
Parameters | ||
---------- | ||
|
||
img: array-like image | ||
img: array-like image, or xarray | ||
The image data. Supported array shapes are | ||
|
||
- (M, N): an image with scalar data. The data is visualized | ||
|
@@ -95,6 +104,13 @@ def imshow( | |
position of the [0, 0] pixel of the image array, in the upper left or lower left | ||
corner. The convention 'upper' is typically used for matrices and images. | ||
|
||
labels : dict with str keys and str values (default `{}`) | ||
Overrides names used in the figure for axis titles (keys ``x`` and ``y``), | ||
colorbar title and hover (key ``color``). The values should correspond | ||
to the desired label to be displayed. If ``img`` is an xarray, dimension | ||
names are used for axis titles, and long name for the colorbar title | ||
(unless overridden in ``labels``). Possible keys are: x, y, and color. | ||
|
||
color_continuous_scale : str or list of str | ||
colormap used to map scalar data to colors (for a 2D image). This parameter is | ||
not used for RGB or RGBA images. If a string is provided, it should be the name | ||
|
@@ -122,6 +138,14 @@ def imshow( | |
height: number | ||
The figure height in pixels, defaults to 600. | ||
|
||
aspect: 'equal', 'auto', or None | ||
- 'equal': Ensures an aspect ratio of 1 or pixels (square pixels) | ||
- 'auto': The axes is kept fixed and the aspect ratio of pixels is | ||
adjusted so that the data fit in the axes. In general, this will | ||
result in non-square pixels. | ||
- if None, 'equal' is used for numpy arrays and 'auto' for xarrays | ||
(which have typically heterogeneous coordinates) | ||
|
||
Returns | ||
------- | ||
fig : graph_objects.Figure containing the displayed image | ||
|
@@ -137,11 +161,41 @@ def imshow( | |
|
||
In order to update and customize the returned figure, use | ||
`go.Figure.update_traces` or `go.Figure.update_layout`. | ||
|
||
If an xarray is passed, dimensions names and coordinates are used for | ||
axes labels and ticks. | ||
""" | ||
args = locals() | ||
apply_default_cascade(args) | ||
img_is_xarray = False | ||
if xarray_imported: | ||
if isinstance(img, xarray.DataArray): | ||
y_label, x_label = img.dims[0], img.dims[1] | ||
nicolaskruchten marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# np.datetime64 is not handled correctly by go.Heatmap | ||
for ax in [x_label, y_label]: | ||
if np.issubdtype(img.coords[ax].dtype, np.datetime64): | ||
img.coords[ax] = img.coords[ax].astype(str) | ||
x = img.coords[x_label] | ||
y = img.coords[y_label] | ||
img_is_xarray = True | ||
if aspect is None: | ||
aspect = "auto" | ||
z_name = xarray.plot.utils.label_from_attrs(img).replace("\n", "<br>") | ||
|
||
if labels is not None: | ||
if "x" in labels: | ||
y_label = labels["x"] | ||
emmanuelle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if "y" in labels: | ||
y_label = labels["y"] | ||
if "color" in labels: | ||
z_name = labels["color"] | ||
|
||
if not img_is_xarray: | ||
if aspect is None: | ||
aspect = "equal" | ||
|
||
img = np.asanyarray(img) | ||
|
||
# Cast bools to uint8 (also one byte) | ||
if img.dtype == np.bool: | ||
img = 255 * img.astype(np.uint8) | ||
|
@@ -150,10 +204,10 @@ def imshow( | |
if img.ndim == 2: | ||
trace = go.Heatmap(z=img, coloraxis="coloraxis1") | ||
autorange = True if origin == "lower" else "reversed" | ||
layout = dict( | ||
xaxis=dict(scaleanchor="y", constrain="domain"), | ||
yaxis=dict(autorange=autorange, constrain="domain"), | ||
) | ||
layout = dict(yaxis=dict(autorange=autorange)) | ||
if aspect == "equal": | ||
layout["xaxis"] = dict(scaleanchor="y", constrain="domain") | ||
layout["yaxis"]["constrain"] = "domain" | ||
colorscale_validator = ColorscaleValidator("colorscale", "imshow") | ||
if zmin is not None and zmax is None: | ||
zmax = img.max() | ||
|
@@ -167,6 +221,7 @@ def imshow( | |
cmid=color_continuous_midpoint, | ||
cmin=range_color[0], | ||
cmax=range_color[1], | ||
colorbar=dict(title=z_name), | ||
) | ||
|
||
# For 2D+RGB data, use Image trace | ||
|
@@ -185,12 +240,25 @@ def imshow( | |
) | ||
|
||
layout_patch = dict() | ||
for v in ["title", "height", "width"]: | ||
if args[v]: | ||
layout_patch[v] = args[v] | ||
for attr_name in ["title", "height", "width"]: | ||
if args[attr_name]: | ||
layout_patch[attr_name] = args[attr_name] | ||
if "title" not in layout_patch and args["template"].layout.margin.t is None: | ||
layout_patch["margin"] = {"t": 60} | ||
fig = go.Figure(data=trace, layout=layout) | ||
fig.update_layout(layout_patch) | ||
if img_is_xarray: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually think we can do this for |
||
if img.ndim <= 2: | ||
hovertemplate = ( | ||
x_label | ||
+ ": %{x} <br>" | ||
+ y_label | ||
+ ": %{y} <br>" | ||
+ z_name | ||
+ " : %{z}<extra></extra>" | ||
) | ||
fig.update_traces(x=x, y=y, hovertemplate=hovertemplate) | ||
fig.update_xaxes(title_text=x_label) | ||
fig.update_yaxes(title_text=y_label) | ||
fig.update_layout(template=args["template"], overwrite=True) | ||
return fig |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.