Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,29 @@ import dash_html_components as html
from dash_slicer import VolumeSlicer
import imageio

app = dash.Dash(__name__)
app = dash.Dash(__name__, update_title=None)

vol = imageio.volread("imageio:stent.npz")
slicer = VolumeSlicer(app, vol)

app.layout = html.Div([slicer.graph, slicer.slider, *slicer.stores])

if __name__ == "__main__":
app.run_server()
app.run_server(debug=True, dev_tools_props_check=False)
```


## License

This code is distributed under MIT license.
This code is distributed under the MIT license.


## Developers


* Make sure that you have Python with the appropriate dependencies installed, e.g. via `venv`.
* Run `pip install -e .` to do an in-place install of the package.
* Run the examples using e.g. `python examples/slicer_with_1_view.py`
* Run the examples using e.g. `python examples/all_features.py`

* Use `black .` to autoformat.
* Use `flake8 .` to lint.
Expand All @@ -74,26 +75,26 @@ instantiation one can provide the following parameters:
* `volume` (`ndarray`): the 3D numpy array to slice through. The dimensions
are assumed to be in zyx order. If this is not the case, you can
use `np.swapaxes` to make it so.
* `spacing` (tuple of `float`): The distance between voxels for each
dimension (zyx).The spacing and origin are applied to make the slice
* `spacing` (tuple of `float`): the distance between voxels for each
dimension (zyx). The spacing and origin are applied to make the slice
drawn in "scene space" rather than "voxel space".
* `origin` (tuple of `float`): The offset for each dimension (zyx).
* `origin` (tuple of `float`): the offset for each dimension (zyx).
* `axis` (`int`): the dimension to slice in. Default 0.
* `reverse_y` (`bool`): Whether to reverse the y-axis, so that the origin of
* `reverse_y` (`bool`): whether to reverse the y-axis, so that the origin of
the slice is in the top-left, rather than bottom-left. Default True.
Note: setting this to False affects performance, see #12.
Note: setting this to False affects performance, see #12. This has been
fixed, but the fix has not yet been released with Dash.
* `scene_id` (`str`): the scene that this slicer is part of. Slicers
that have the same scene-id show each-other's positions with
line indicators. By default this is derived from `id(volume)`.
* `color` (`str`): the color for this slicer. By default the color is
red, green, or blue, depending on the axis. Set to empty string
for "no color".
* `thumbnail` (`int` or `bool`): preferred size of low-resolution data to be
uploaded to the client. If `False`, the full-resolution data are
uploaded client-side. If `True` (default), a default value of 32 is
used.

Note that this is not a Dash component. The components that make
* `color` (`str`): the color for this slicer. By default the color
is a shade of blue, orange, or green, depending on the axis. Set
to empty string to prevent drawing indicators for this slicer.
* `thumbnail` (`int` or `bool`): the preferred size of low-resolution data
to be uploaded to the client. If `False`, the full-resolution data are
uploaded client-side. If `True` (default), a default value of 32 is used.

Note that this is not a Dash Component. The components that make
up the slicer (and which must be present in the layout) are:
`slicer.graph`, `slicer.slider`, and `slicer.stores`.

Expand All @@ -104,7 +105,7 @@ can be used as output for `slicer.overlay_data`. The color
can be a hex color or an rgb/rgba tuple. Alternatively, color
can be a list of such colors, defining a colormap.

**property `VolumeSlicer.axis`** (`int`): The axis at which the slicer is slicing.
**property `VolumeSlicer.axis`** (`int`): The axis to slice.

**property `VolumeSlicer.graph`**: The `dcc.Graph` for this slicer. Use `graph.figure` to access the
Plotly Figure object.
Expand Down Expand Up @@ -171,8 +172,8 @@ To apply the position for one dimension only, use e.g `(None, None, x)`.
### Performance tips

There tends to be a lot of interaction in an application that contains
slicer objects. Therefore, performance matters to realize a smooth user
experience. Here are some tips to help with that:
slicer objects. To realize a smooth user experience, performance matters.
Here are some tips to help with that:

* Most importantly, when running the server in debug mode, consider setting
`dev_tools_props_check=False`.
Expand Down
34 changes: 17 additions & 17 deletions dash_slicer/slicer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
### Performance tips

There tends to be a lot of interaction in an application that contains
slicer objects. Therefore, performance matters to realize a smooth user
experience. Here are some tips to help with that:
slicer objects. To realize a smooth user experience, performance matters.
Here are some tips to help with that:

* Most importantly, when running the server in debug mode, consider setting
`dev_tools_props_check=False`.
Expand Down Expand Up @@ -69,26 +69,26 @@ class VolumeSlicer:
* `volume` (`ndarray`): the 3D numpy array to slice through. The dimensions
are assumed to be in zyx order. If this is not the case, you can
use `np.swapaxes` to make it so.
* `spacing` (tuple of `float`): The distance between voxels for each
dimension (zyx).The spacing and origin are applied to make the slice
* `spacing` (tuple of `float`): the distance between voxels for each
dimension (zyx). The spacing and origin are applied to make the slice
drawn in "scene space" rather than "voxel space".
* `origin` (tuple of `float`): The offset for each dimension (zyx).
* `origin` (tuple of `float`): the offset for each dimension (zyx).
* `axis` (`int`): the dimension to slice in. Default 0.
* `reverse_y` (`bool`): Whether to reverse the y-axis, so that the origin of
* `reverse_y` (`bool`): whether to reverse the y-axis, so that the origin of
the slice is in the top-left, rather than bottom-left. Default True.
Note: setting this to False affects performance, see #12.
Note: setting this to False affects performance, see #12. This has been
fixed, but the fix has not yet been released with Dash.
* `scene_id` (`str`): the scene that this slicer is part of. Slicers
that have the same scene-id show each-other's positions with
line indicators. By default this is derived from `id(volume)`.
* `color` (`str`): the color for this slicer. By default the color is
red, green, or blue, depending on the axis. Set to empty string
for "no color".
* `thumbnail` (`int` or `bool`): preferred size of low-resolution data to be
uploaded to the client. If `False`, the full-resolution data are
uploaded client-side. If `True` (default), a default value of 32 is
used.

Note that this is not a Dash component. The components that make
* `color` (`str`): the color for this slicer. By default the color
is a shade of blue, orange, or green, depending on the axis. Set
to empty string to prevent drawing indicators for this slicer.
* `thumbnail` (`int` or `bool`): the preferred size of low-resolution data
to be uploaded to the client. If `False`, the full-resolution data are
uploaded client-side. If `True` (default), a default value of 32 is used.

Note that this is not a Dash Component. The components that make
up the slicer (and which must be present in the layout) are:
`slicer.graph`, `slicer.slider`, and `slicer.stores`.
"""
Expand Down Expand Up @@ -189,7 +189,7 @@ def scene_id(self) -> str:

@property
def axis(self) -> int:
"""The axis at which the slicer is slicing."""
"""The axis to slice."""
return self._axis

@property
Expand Down
36 changes: 36 additions & 0 deletions update_docs_in_readme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""
Run this script to update the README.md with tha current reference docs.
"""

import os
from dash_slicer.docs import get_reference_docs


HERE = os.path.dirname(os.path.abspath(__file__))


def write_reference_docs():
"""Write the reference docs to the README."""
# Prepare
header = "## Reference"
filename = os.path.join(HERE, "README.md")
assert os.path.isfile(filename), "README.md not found"
# Load first part of the readme
with open(filename, "rb") as f:
text = f.read().decode()
text1, _, _ = text.partition(header)
text1 = text1.strip()
# Create second part of the readme
text2 = "\n\n\n" + header + "\n\n" + get_reference_docs()
if "\r" in text1:
text2 = text2.replace("\n", "\r\n")
# Wite
with open(filename, "wb") as f:
f.write(text1.encode())
f.write(text2.encode())
print("Updated the reference docs in README.md")


if __name__ == "__main__":
write_reference_docs()