Slice on VTK Volume are unusable


I’m using Bokeh with Dash to render 3D Data using VTKVolume.

The bokeh server executed :

import os
import sys
import time
import panel as pn

def make_vtk_vol(meta, volume_datas):
    DX = float(meta["dx"])
    DY = float(meta["dy"])
    DT = float(meta["dt"])
    vol = pn.pane.VTKVolume(
        spacing=(DX, DY, DT),
        colormap="Rainbow Blended White",
    return vol
def app3d():
    meta, datas = getVisuData() # datas is 3D Numpy array, metas is a dictionnary of property
    vol = make_vtk_vol(meta, datas)
    controls = vol.controls(jslink=True)
    #  print(controls)
    # Select index of interesting controls widget
    good_index = [7, 8, 10, 11, 12, 13, 15, 18, 21, 22, 23]
    subcontrols = [controls[0][i] for i in good_index]
    controls[0] = pn.WidgetBox(name='Controls')
    for (i, x) in enumerate(subcontrols):
    html_title = pn.pane.HTML(
                <h3>Visualization <h3/>
    controls[0].insert(0, html_title)
    row = pn.Row(controls[0], vol, sizing_mode="stretch_both", scroll=False)


Now the volume rendering works fine, but there is an issue with viewing slices.

Whenever I interact with the Slider to change slice it has a buggy behaviour and jump to numbers that have nothing to do with the range I clicked at on the slider.

If I click on the middle of the slider it will either go down to a very small number or increase to numbers outside volume range. Using slice is simply unusable because I can’t select a correct index on a slider.

What could cause this behaviour ? How can I fix it ?

Your data size must exceed the max_data_size parameter and the data are dowsampled before being sent to javascript side.

Then synchronization between slice on javascript side and python side is wrong since both data on python side and javscript have not the same sampling size.

If you are in a bokeh server don’t use jslink=True for the slices

or you can increase the max_data_size to avoid the downsampling of the datas volume on javascript but depending on your volume size you can hit other limits (transfer through websocket, out of memory because of duplication, transfer time…)

Even if it’s rendered in a browser ?

To start the application I do panel serve --allow-websocket-origin=, so since it was in a browser I assumed I needed the jslink = True.

EDIT : Just tested it, it worked without jslink = True. Thanks !

1 Like