Interactive slider to change the fragment used in the graphics of the Bokeh image

I am interested in using Bokeh to place images inside IPython laptops. In particular, the data type with which I often interact is a multidimensional NumPy array with 3 or more dimensions. Take an example of a three-dimensional array. A common example is RGB images. Three dimensions: x , y and color

I am interested in using Bokeh to build a single image channel in an IPython laptop. I would like to provide an interactive slider that allows an IPython laptop user to click on each 3rd dimension index, in this example, color.

My code below (when running on an IPython laptop) successfully shows the graph of the first color channel. But I can’t understand what causes the error when I call interact . Have I correctly defined my ColumnDataSource correctly and correctly pointed to the construction of the Bokeh section?

 # imports import numpy as np from scipy.misc import imread from bokeh.plotting import figure, show from bokeh.io import output_notebook from bokeh.models import ColumnDataSource from bokeh.palettes import Greys9 from IPython.html.widgets import interact 

 # enable Bokeh to plot to the notebook output_notebook() # Make the Bokeh plot of the "first" layer of the 3D data ## This part works TOOLS="pan, box_zoom, reset, save" # The image from https://windycitizensports.files.wordpress.com/2011/10/baboon.jpg?w=595 RGB_image = imread('/Users/curt/Downloads/BaboonRGB.jpg') nx, ny, n_colors = RGB_image.shape source = ColumnDataSource(data={'image': RGB_image[:, :, 0]}) p = figure(title="ColorChannel", tools=TOOLS, x_range=[0, nx], y_range=[0, ny], ) p.image([source.data['image'][::-1, :]-1], x=0, y=0, dh=[ny], dw=[nx], palette=Greys9, source=source, ) show(p) 

 # try to add interactive slider ## This part does not work & gives a JavaScript error def update(idx=0): global RGB_image source.data['image'] = RGB_image[:, :, idx] source.push_notebook() interact(update, idx=(0, 2)) 

Javascript error:

 Javascript error adding output! TypeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The provided float value is non-finite. See your browser Javascript console for more details. 

I'm not sure how this can be. I tried to force RGB_Image for the float by doing RGB_Image = RGB_Image.astype(float) right after defining it, but got the same error.

+5
source share
1 answer

Essentially, the data format is incompatible between your predefined image and what you are trying to update.

Workaround that works:

 def update(idx=0): global RGB_image source.data['image'] = RGB_image[:, :, idx] p.image([source.data['image'][::-1, :]-1], x=0, y=0, dh=[ny], dw=[nx], palette=Greys9, source=source, ) show(p) interact(update, idx=(0, 2)) 

I admit that defining an image over and over is not the preferred way to do this, but it should at least give you an idea of ​​where to look.

+5
source

All Articles