-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add facet_col and animation_frame argument to imshow #2746
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
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
afb5c4d
use init_figure from main px core
emmanuelle 8be8ca0
WIP: add facet_col arg to imshow
emmanuelle d236bc2
animations work for grayscale images, with or without binary string
emmanuelle c8e852e
animations now work + tests
emmanuelle 12cec34
docs on facets and animations + add subplots titles
emmanuelle ab427ae
Merge branch 'master' into imshow-animation
emmanuelle 7a3a9f4
solved old unnoticed conflict
emmanuelle b689a2f
attempt to use imshow with binary strings and xarrays
emmanuelle fbb3f65
added test
emmanuelle 882810f
animation work for xarrays, still need to fix slider label
emmanuelle ba65990
added test with xarray and animations
emmanuelle cf644e5
added doc
emmanuelle 72674b7
added pooch to doc requirements
emmanuelle bd42385
Update packages/python/plotly/plotly/express/_imshow.py
emmanuelle fc2375b
Update doc/python/imshow.md
emmanuelle a431fad
remove commented-out code
emmanuelle b652039
animation + facet kinda working now, but it broke labels
emmanuelle 59c6622
added test
emmanuelle c7285a3
simplified code
emmanuelle 91c066e
simplified code
emmanuelle ac5aa1f
polished code and added doc example
emmanuelle 36b9f98
Merge branch 'imshow-animation' of https://github.com/plotly/plotly.p…
emmanuelle 8cdc6af
updated doc
emmanuelle cf1c2b9
Merge branch 'master' into imshow-animation
emmanuelle 5d1d8d8
add facet_col_spacing and facet_row_spacing
emmanuelle c27f88a
modify error message + animation_frame label
emmanuelle 502fdfd
improve code readibility
emmanuelle 135b01b
added example with sequence of images
emmanuelle 6ac3e36
typoe
emmanuelle a5a2252
label names
emmanuelle 77cb5cd
label name
emmanuelle 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
animations work for grayscale images, with or without binary string
- Loading branch information
commit d236bc227c1ef058fcd646b6df0d872396b8f44f
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import plotly.graph_objs as go | ||
| from _plotly_utils.basevalidators import ColorscaleValidator | ||
| from ._core import apply_default_cascade, init_figure | ||
| from ._core import apply_default_cascade, init_figure, configure_animation_controls | ||
| from io import BytesIO | ||
| import base64 | ||
| from .imshow_utils import rescale_intensity, _integer_ranges, _integer_types | ||
|
|
@@ -133,7 +133,7 @@ def imshow( | |
| labels={}, | ||
| x=None, | ||
| y=None, | ||
| animation_frame=False, | ||
| animation_frame=None, | ||
| facet_col=None, | ||
| facet_col_wrap=None, | ||
| color_continuous_scale=None, | ||
|
|
@@ -353,13 +353,21 @@ def imshow( | |
|
|
||
| # --------------- Starting from here img is always a numpy array -------- | ||
| img = np.asanyarray(img) | ||
| slice_through = False | ||
| if facet_col is not None: | ||
| img = np.moveaxis(img, facet_col, 0) | ||
| facet_col = True | ||
|
|
||
| slice_through = True | ||
| if animation_frame is not None: | ||
| img = np.moveaxis(img, animation_frame, 0) | ||
| animation_frame = True | ||
| args["animation_frame"] = "plane" | ||
| slice_through = True | ||
|
|
||
| print("slice_through", slice_through) | ||
| # Default behaviour of binary_string: True for RGB images, False for 2D | ||
| if binary_string is None: | ||
| if facet_col: | ||
| if slice_through: | ||
| binary_string = img.ndim >= 4 and not is_dataframe | ||
| else: | ||
| binary_string = img.ndim >= 3 and not is_dataframe | ||
|
|
@@ -391,7 +399,7 @@ def imshow( | |
| zmin = 0 | ||
|
|
||
| # For 2d data, use Heatmap trace, unless binary_string is True | ||
| if (img.ndim == 2 or (img.ndim == 3 and facet_col)) and not binary_string: | ||
| if (img.ndim == 2 or (img.ndim == 3 and slice_through)) and not binary_string: | ||
| if y is not None and img.shape[0] != len(y): | ||
| raise ValueError( | ||
| "The length of the y vector must match the length of the first " | ||
|
|
@@ -402,10 +410,10 @@ def imshow( | |
| "The length of the x vector must match the length of the second " | ||
| + "dimension of the img matrix." | ||
| ) | ||
| if facet_col: | ||
| if slice_through: | ||
| traces = [ | ||
| go.Heatmap(x=x, y=y, z=img_slice, coloraxis="coloraxis1") | ||
| for img_slice in img | ||
| go.Heatmap(x=x, y=y, z=img_slice, coloraxis="coloraxis1", name=str(i)) | ||
| for i, img_slice in enumerate(img) | ||
| ] | ||
| else: | ||
| traces = [go.Heatmap(x=x, y=y, z=img, coloraxis="coloraxis1")] | ||
|
|
@@ -429,7 +437,7 @@ def imshow( | |
| # For 2D+RGB data, use Image trace | ||
| elif ( | ||
| img.ndim == 3 | ||
| and (img.shape[-1] in [3, 4] or (facet_col and binary_string)) | ||
| and (img.shape[-1] in [3, 4] or (slice_through and binary_string)) | ||
| or (img.ndim == 2 and binary_string) | ||
| ): | ||
| rescale_image = True # to check whether image has been modified | ||
|
|
@@ -442,7 +450,7 @@ def imshow( | |
| if zmin is None and zmax is None: # no rescaling, faster | ||
| img_rescaled = img | ||
| rescale_image = False | ||
| elif img.ndim == 2 or (img.ndim == 3 and facet_col): | ||
| elif img.ndim == 2 or (img.ndim == 3 and slice_through): | ||
| img_rescaled = rescale_intensity( | ||
| img, in_range=(zmin[0], zmax[0]), out_range=np.uint8 | ||
| ) | ||
|
|
@@ -457,7 +465,7 @@ def imshow( | |
| for ch in range(img.shape[-1]) | ||
| ] | ||
| ) | ||
| if facet_col: | ||
| if slice_through: | ||
| img_str = [ | ||
| _array_to_b64str( | ||
| img_rescaled_slice, | ||
|
|
@@ -477,7 +485,7 @@ def imshow( | |
| ext=binary_format, | ||
| ) | ||
| ] | ||
| traces = [go.Image(source=img_str_slice) for img_str_slice in img_str] | ||
| traces = [go.Image(source=img_str_slice, name=str(i)) for i, img_str_slice in enumerate(img_str)] | ||
| else: | ||
| colormodel = "rgb" if img.shape[-1] == 3 else "rgba256" | ||
| traces = [go.Image(z=img, zmin=zmin, zmax=zmax, colormodel=colormodel)] | ||
|
|
@@ -498,8 +506,15 @@ def imshow( | |
| layout_patch["title_text"] = args["title"] | ||
| elif args["template"].layout.margin.t is None: | ||
| layout_patch["margin"] = {"t": 60} | ||
|
|
||
| frame_list = [] | ||
| for index, trace in enumerate(traces): | ||
| fig.add_trace(trace, row=nrows - index // ncols, col=index % ncols + 1) | ||
| if facet_col or index == 0: | ||
| fig.add_trace(trace, row=nrows - index // ncols, col=index % ncols + 1) | ||
| if animation_frame: | ||
| frame_list.append(dict(data=trace, layout=layout, name=str(index))) | ||
| if animation_frame: | ||
| fig.frames = frame_list | ||
| fig.update_layout(layout) | ||
|
Contributor
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. it's a bit odd to have |
||
| fig.update_layout(layout_patch) | ||
| # Hover name, z or color | ||
|
|
@@ -530,5 +545,6 @@ def imshow( | |
| fig.update_xaxes(title_text=labels["x"]) | ||
| if labels["y"]: | ||
| fig.update_yaxes(title_text=labels["y"]) | ||
| fig.update_layout(template=args["template"], overwrite=True) | ||
| configure_animation_controls(args, go.Image, fig) | ||
| #fig.update_layout(template=args["template"], overwrite=True) | ||
| return fig | ||
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.