Skip to content

Commit

Permalink
ENH: Add vmin / vmax traitlet support
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Sep 9, 2019
1 parent 843d9a9 commit cd3fcef
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 12 deletions.
19 changes: 7 additions & 12 deletions examples/3DImage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,19 @@
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a5b13f18c2034ab68e1558c7c5e6a705",
"model_id": "0e3e868d39df4a38a9a8570080deaca4",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Viewer(geometries=[], gradient_opacity=0.22, point_sets=[], rendered_image=<itkImagePython.itkImageSS3; proxy …"
"Viewer(geometries=[], gradient_opacity=0.4, point_sets=[], rendered_image=<itkImagePython.itkImageSS3; proxy o"
]
},
"metadata": {},
Expand All @@ -64,15 +66,8 @@
],
"source": [
"image = itk.imread(file_name)\n",
"view(image, rotate=True)"
"view(image, rotate=True, vmin=4000, vmax=17000, gradient_opacity=0.4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand All @@ -91,7 +86,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
"version": "3.6.8"
}
},
"nbformat": 4,
Expand Down
10 changes: 10 additions & 0 deletions itkwidgets/widget_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ class Viewer(ViewerParent):
help="Region of interest: ((lower_x, lower_y, lower_z), (upper_x, upper_y, upper_z))")\
.tag(sync=True, **array_serialization)\
.valid(shape_constraints(2, 3))
vmin = CFloat(default_value=None, allow_none=True, help="Value that maps to the minimum of image colormap.").tag(sync=True)
vmax = CFloat(default_value=None, allow_none=True, help="Value that maps to the maximum of image colormap.").tag(sync=True)
_largest_roi = NDArray(dtype=np.float64, default_value=np.zeros((2, 3), dtype=np.float64),
help="Largest possible region of interest: ((lower_x, lower_y, lower_z), (upper_x, upper_y, upper_z))")\
.tag(sync=True, **array_serialization)\
Expand Down Expand Up @@ -545,6 +547,14 @@ def view(image=None,
shadow: bool, optional, default: True
Use shadowing in the volume rendering.
vmin: float, optional, default: None
Value that maps to the minimum of image colormap. Defaults to minimum of
the image pixel buffer.
vmax: float, optional, default: None
Value that maps to the minimum of image colormap. Defaults to maximum of
the image pixel buffer.
Point Sets
^^^^^^^^^^
Expand Down
39 changes: 39 additions & 0 deletions js/lib/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import IntTypes from 'itk/IntTypes'
import FloatTypes from 'itk/FloatTypes'
import IOTypes from 'itk/IOTypes'
import runPipelineBrowser from 'itk/runPipelineBrowser'
import macro from 'vtk.js/Sources/macro'

const ANNOTATION_DEFAULT = '<table style="margin-left: 0;"><tr><td style="margin-left: auto; margin-right: 0;">Index:</td><td>${iIndex},</td><td>${jIndex},</td><td>${kIndex}</td></tr><tr><td style="margin-left: auto; margin-right: 0;">Position:</td><td>${xPosition},</td><td>${yPosition},</td><td>${zPosition}</td></tr><tr><td style="margin-left: auto; margin-right: 0;"">Value:</td><td>${value}</td></tr></table>'
const ANNOTATION_CUSTOM_PREFIX = '<table style="margin-left: 0;"><tr><td style="margin-left: auto; margin-right: 0;">Scale/Index:</td>'
Expand Down Expand Up @@ -65,6 +66,8 @@ const ViewerModel = widgets.DOMWidgetModel.extend({
_rendering_image: false,
interpolation: true,
cmap: 'Viridis (matplotlib)',
vmin: null,
vmax: null,
shadow: true,
slicing_planes: false,
gradient_opacity: 0.2,
Expand Down Expand Up @@ -466,6 +469,8 @@ const ViewerView = widgets.DOMWidgetView.extend({
if (rendered_image) {
this.interpolation_changed()
this.cmap_changed()
this.vmin_changed()
this.vmax_changed()
}
this.mode_changed()
if (rendered_image) {
Expand Down Expand Up @@ -520,6 +525,20 @@ const ViewerView = widgets.DOMWidgetView.extend({
}
this.model.itkVtkViewer.subscribeSelectColorMap(onSelectColorMap)

const onChangeColorRange = (colorRange) => {
const vmin = this.model.get('vmin')
if (colorRange[0] !== vmin) {
this.model.set('vmin', colorRange[0])
this.model.save_changes()
}
const vmax = this.model.get('vmax')
if (colorRange[1] !== vmax) {
this.model.set('vmax', colorRange[1])
this.model.save_changes()
}
}
this.model.itkVtkViewer.subscribeChangeColorRange(onChangeColorRange);

const onCroppingPlanesChanged = (planes, bboxCorners) => {
if (!this.model.get('_rendering_image') && !this.model.skipOnCroppingPlanesChanged) {
this.model.skipOnCroppingPlanesChanged = true
Expand Down Expand Up @@ -613,6 +632,8 @@ const ViewerView = widgets.DOMWidgetView.extend({
render: function() {
this.model.on('change:rendered_image', this.rendered_image_changed, this)
this.model.on('change:cmap', this.cmap_changed, this)
this.model.on('change:vmin', this.vmin_changed, this)
this.model.on('change:vmax', this.vmax_changed, this)
this.model.on('change:shadow', this.shadow_changed, this)
this.model.on('change:slicing_planes', this.slicing_planes_changed, this)
this.model.on('change:gradient_opacity', this.gradient_opacity_changed, this)
Expand Down Expand Up @@ -851,6 +872,24 @@ const ViewerView = widgets.DOMWidgetView.extend({
}
},

vmin_changed: function() {
const vmin = this.model.get('vmin')
if (vmin !== null && this.model.hasOwnProperty('itkVtkViewer')) {
let colorRange = this.model.itkVtkViewer.getColorRange().slice()
colorRange[0] = vmin
this.model.itkVtkViewer.setColorRange(colorRange)
}
},

vmax_changed: function() {
const vmax = this.model.get('vmax')
if (vmax !== null && this.model.hasOwnProperty('itkVtkViewer')) {
let colorRange = this.model.itkVtkViewer.getColorRange().slice()
colorRange[1] = vmax
this.model.itkVtkViewer.setColorRange(colorRange)
}
},

shadow_changed: function() {
const shadow = this.model.get('shadow')
if (this.model.hasOwnProperty('itkVtkViewer') && !this.model.use2D) {
Expand Down

0 comments on commit cd3fcef

Please sign in to comment.