2016-04-14 4 views
0

Ich möchte das Ergebnis eines Isomap-Algorithmus darstellen. Aber ich möchte auch, dass der Benutzer die Anzahl der Komponenten wählt, die er behalten möchte. Ich erstelle ein Slider-Objekt dafür aber die Sache ist, dass die Callback-Funktion in Javascript ist. Deshalb kann ich scikit learn nicht zum Aktualisieren meiner Daten verwenden. Das ist mein Code, könnte jemand ein paar Ideen geben? DankeDynamische Visualisierung Bokeh

import numpy as np 
from bokeh.io import vform 
from bokeh.models import CustomJS, ColumnDataSource 
from bokeh.plotting import figure, output_file, show 
from bokeh.models.widgets import Slider 
from sklearn import manifold 

output_file("test.html") 


X = np.random.randn(1000,20) 

Y = np.random.randn(1000,20) 

X_isomap = manifold.Isomap(n_neighbors=10, n_components=2).fit_transform(X) 

X1 = X_isomap[:,0] 
X2 = X_isomap[:,1] 

IsoSource = ColumnDataSource(data=dict(x=X1, y=X2,DATA=X)) 

plot1 = figure(plot_width=400, plot_height=400,tools = "pan,wheel_zoom,box_zoom,reset,resize") 
plot1.circle('x', 'y',source=IsoSource,size=7, color="navy") 


#sliderCompMDS = Slider(title="n_components MDS",value=2,start=2,end=20,step=1) 


callback = CustomJS(args=dict(source=IsoSource),code=""" 
    var data = source.get('data'); 
    var f = cb_obj.get('value') 
    x = data['x'] 
    y =data['y'] 
    X = data['DATA'] 
    donnees = manifold.Isomap(n_neighbors=10, n_components=f).fit_transform(X) 
    x = donnees[:,0] 
    y = donnees[:,1] 
    source.trigger('change'); 

    """) 

sliderCompIso = Slider(title="n_components Isomap",value=2,start=1,end=20,step=1,callback=callback) 



layout = vform(sliderCompIso, plot1) 

show(layout) 
+0

Wenn Sie * Python * -Code von Benutzerinteraktionen auslösen möchten, müssen Sie eine Bokeh-Server-App erstellen. Wie Sie bereits angemerkt haben, können 'CustomJS'-Callbacks nur JavaScript ausführen, nicht Python. Sie können hier einige Beispiele sehen: https://github.com/bokeh/bokeh/tree/master/examples/app (klicken Sie auf ein Bild, um zu einer Live-Version der App zu gelangen) und finden Sie hier eine Menge Dokumentation : http://bokeh.pydata.org/en/latest/docs/user_guide/server.html – bigreddot

+0

Vielen Dank für Ihre Links. Es half mir, mein Problem zu lösen –

Antwort

0

Erstens ist es immer besser, die gesamte .data dict auf einmal zu aktualisieren. Also, nicht dies tun:

source2.data['y1'] = Y_MDS[:,0] 
source2.data['y2'] = Y_MDS[:,1] 

Statt ein newdict mit den Daten zuerst machen, dann tun

source2.data = newdata 

Darüber hinaus, ist es schwer zu sagen. Sieht so aus, als würden Sie bei jedem Update ~ 1000 x-y Punkte senden? Das ist keine unangemessene Zahl, und viele Beispiele zeigen mehr als das. Sind Sie sicher, dass die Berechnung selbst keine nennenswerte Zeit in Anspruch nimmt? Wie lange:

manifold.Isomap(n_components=w).fit_transform(X) 

und

manifold.MDS(n_components=u).fit_transform(Y) 

nehmen zu beenden, auf eigene Faust?

Meine Vermutung ist, dass diese einfach einige Zeit brauchen, um zu berechnen. Wenn das der Fall ist, kann Bokeh nichts tun. In 0.12 sollte dem Protokoll eine Meldung "busy" hinzugefügt werden, damit die App visuell anzeigen kann, dass eine teure Berechnung stattfindet.

+0

Ich überprüfte die Berechnungszeit des MDS und erkannte, dass alle meine Probleme daraus kamen. (Ich brauchte 36 Sekunden, um die Webseite zu generieren und das MDS benötigte 34 Sekunden) Danke für Ihre Hilfe –

+0

Großartig! Wie bereits erwähnt, sollte '0.12' einige neue visuelle Indikatoren haben, die Benutzern helfen, wenn die Dinge "beschäftigt" sind. – bigreddot