2015-08-13 12 views
5

Sono interessato all'utilizzo di Bokeh per inserire immagini all'interno dei notebook IPython. In particolare, un tipo di dati con cui spesso interagisco è un array NumPy multidimensionale con 3 o più dimensioni. Prendi l'esempio di un array tridimensionale. Un esempio spesso incontrato sono le immagini RGB. Le tre dimensioni sono x, y, e colorDispositivo di scorrimento interattivo per variare la fetta utilizzata nella trama dell'immagine Bokeh

Mi interessa utilizzando Bokeh per tracciare un singolo canale immagine in un notebook IPython. Mi piacerebbe fornire un dispositivo di scorrimento interattivo che consente all'utente del notebook IPython di fare clic su ogni indice della terza dimensione, in questo esempio, colore.

Il mio codice di seguito (quando eseguito in un notebook IPython) mostra correttamente la trama del primo canale di colore. Ma non riesco a capire cosa stia causando l'errore nella mia chiamata a interact. Il mio ColumnDataSource è stato definito correttamente e referenziato correttamente nella costruzione del diagramma Bokeh?

# 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)) 

L'errore Javascript è:

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. 

io non sono sicuro di come questo possa essere. Ho provato a forzare RGB_Image in un float eseguendo RGB_Image = RGB_Image.astype(float) immediatamente dopo averlo definito, ma ho ottenuto lo stesso errore.

+1

Anche se non sono in grado di riprodurre esattamente il problema, visto che non riesco a far funzionare la console IPython come il tuo notebook IPython, ho riscontrato un potenziale problema con il tuo codice. Hai verificato se la funzione di aggiornamento utilizza idx come numero singolo? L'elenco di matrici RGB_image [:,:, idx] accetterà perfettamente idx per essere una tupla, che causerà una mancata corrispondenza del formato dei dati tra source.data ['image'] e il resto della sorgente. – Uvar

risposta

5

In sostanza, il formato dei dati non è coerente tra l'immagine predefinita e ciò che si sta tentando di aggiornare.

Una soluzione che funziona:

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)) 

io riconosco che definisce l'immagine più e più volte, non è il modo migliore di fare questo, ma dovrebbe almeno dare una maniglia su dove guardare.

Problemi correlati