From 006b079b8fd1bda1eaedaa96b62aec3791d9f542 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 18 Dec 2020 15:00:23 +0100 Subject: [PATCH 1/3] Add more features to all_features.py example --- examples/all_features.py | 72 +++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/examples/all_features.py b/examples/all_features.py index 8c8997b..c38f652 100644 --- a/examples/all_features.py +++ b/examples/all_features.py @@ -9,6 +9,7 @@ from dash_slicer import VolumeSlicer from dash.dependencies import Input, Output, State, ALL import imageio +from skimage import measure app = dash.Dash(__name__, update_title=None) @@ -67,16 +68,34 @@ dcc.Graph(id="3Dgraph", figure=go.Figure()), ] ), + html.Div( + [ + html.Div("Threshold level"), + dcc.Slider(id="level", max=2000, value=500), + ] + ), dcc.Markdown( """ Take note of: - * Full-res thumbnails for axis 0. - * Very low-res thumbnails for axis 1. - * Default low-res thumbnails for axis 2. - * The `reverse_y` is false for axis 1. - * Elongated voxels for axis 1 and 2. - * An origin in the thousands, visible in the 3D view. - * A custom brighter green for axis 2. + + Axis 0: + * Full-res thumbnails. + + Axis 1: + * Very low-res thumbnails. + * Elongated voxels. + * The `reverse_y` is false. + * Yellow overlay based on threshold. + + Axis 2: + * Default low-res thumbnails. + * Elongated voxels. + * Yellow contour based on threshold.. + * A custom brighter green indicator. + + 3D view: + * An origin in the thousands. + """ ), ], @@ -101,7 +120,9 @@ let s = { type: 'scatter3d', x: xyz[0], y: xyz[1], z: xyz[2], - mode: 'lines', line: {color: state.color} + mode: 'lines', line: {color: state.color}, + hoverinfo: 'skip', + showlegend: false, }; traces.push(s); } @@ -116,6 +137,41 @@ ) +# Callback to add overlay in axis 1 +@app.callback( + Output(slicer1.overlay_data.id, "data"), + [Input("level", "value")], +) +def update_overlay(level): + return slicer1.create_overlay_data(vol > level, "#ffff00") + + +# Callback to add contours in axes 2 +@app.callback( + Output(slicer2.extra_traces.id, "data"), + [Input(slicer2.state.id, "data"), Input("level", "value")], +) +def update_contour(state, level): + if not state: + return dash.no_update + slice = vol[:, :, state["index"]] + contours = measure.find_contours(slice, level) + traces = [] + for contour in contours: + traces.append( + { + "type": "scatter", + "mode": "lines", + "line": {"color": "yellow", "width": 3}, + "x": contour[:, 1] * spacing[1] + ori[1], + "y": contour[:, 0] * spacing[0] + ori[0], + "hoverinfo": "skip", + "showlegend": False, + } + ) + return traces + + if __name__ == "__main__": # Note: dev_tools_props_check negatively affects the performance of VolumeSlicer app.run_server(debug=True, dev_tools_props_check=False) From 434e6103e98534435c7d9dfe1adb2d2287c8f73e Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 18 Dec 2020 15:04:18 +0100 Subject: [PATCH 2/3] add clim feature to all_featues.py example --- examples/all_features.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/examples/all_features.py b/examples/all_features.py index c38f652..7504eb6 100644 --- a/examples/all_features.py +++ b/examples/all_features.py @@ -72,6 +72,8 @@ [ html.Div("Threshold level"), dcc.Slider(id="level", max=2000, value=500), + html.Div("Contrast limits"), + dcc.RangeSlider(id="clim", max=2000, value=(0, 800)), ] ), dcc.Markdown( @@ -172,6 +174,19 @@ def update_contour(state, level): return traces +# Callback to set contrast limits +@app.callback( + [ + Output(slicer0.clim.id, "data"), + Output(slicer1.clim.id, "data"), + Output(slicer2.clim.id, "data"), + ], + [Input("clim", "value")], +) +def update_clim(clim): + return [clim, clim, clim] + + if __name__ == "__main__": # Note: dev_tools_props_check negatively affects the performance of VolumeSlicer app.run_server(debug=True, dev_tools_props_check=False) From 4cced581aff2304481cdb4db43d32c0139e3f06d Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 18 Dec 2020 15:09:01 +0100 Subject: [PATCH 3/3] rename an example --- ...{get_and_set_position.py => set_slicer_position_simple.py} | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename examples/{get_and_set_position.py => set_slicer_position_simple.py} (90%) diff --git a/examples/get_and_set_position.py b/examples/set_slicer_position_simple.py similarity index 90% rename from examples/get_and_set_position.py rename to examples/set_slicer_position_simple.py index 0d5d328..d95a9da 100644 --- a/examples/get_and_set_position.py +++ b/examples/set_slicer_position_simple.py @@ -1,5 +1,7 @@ """ -An example that demonstrates how the slicer's index can be both read and written. +An simple example that demonstrates how the slicer's index can be both read and written. + +See set_slicer_position_interactively.py for a more advanced / realistic example. """ import dash