Pracuję nad narzędziem do ręcznej klasyfikacji, które zmienia właściwość określonej kropki (koloru w moim przypadku) wybranej na wykresie punktowym przez bokeh. Zmieniłem dane źródłowe w wywołaniu zwrotnym przez s.data = d2 i s.change.emit (), ale oba zawiodły. Myślałem, że taka operacja zmieni source.data, ale kiedy drukuję source.data, tak naprawdę nic się nie dzieje. Kolor kropek na wykresie zmienia się jednak zgodnie z oczekiwaniami. Oto mój powiązany kod:

DF = pd.read_csv(csv_path)
s = ColumnDataSource(DF_file)
p = figure(plot_width=500, plot_height=500, tooltips=TOOLTIPS,tools="lasso_select, tap", title="manual classification")
circles = p.circle('x', 'y', color='color', size=10, source=s, line_alpha=0.6,fill_alpha=0.6)
s.callback = CustomJS(args=dict(s1=s), code="""
    var inds = cb_obj.selected.indices;
    var d1 = s1.data;

    for (var i = 0; i < inds.length; i++) 
    {d1['color'][inds[i]] = 'green';} 

    s1.change.emit();
""")

Zarówno print (s.data), jak i plik csv zapisany z s.to_csv (xxx) nie wykazują żadnych zmian w oryginalnych danych wejściowych. Zastanawiam się również, jak działa wywołanie zwrotne, aby zmienić dane wykresu, pozostawiając dane w pythonie niezmienione, gdy dane w pythonie są danymi przekazanymi do niego w args=(s1=s).

0
formt 20 grudzień 2019, 06:20
Bokeh można uruchomić w dwóch trybach. Tryb prosty tworzy samodzielną stronę internetową z interaktywnością. Bardziej złożony tryb wymaga działającego serwera zaplecza, który umożliwia wysyłanie poleceń między stroną internetową a zapleczem.
 – 
JohanC
24 grudzień 2019, 19:11

1 odpowiedź

Szukałem kilku możliwych metod i znalazłem tę odpowiedź w https://discourse.bokeh.org/t/getting-selected-glyph-data-properties-via-customjs/4311/5?u=1113

Gdy powstaje instancja obiektu Bokeh JS, używa obiektów Pythona jako źródeł danych, ale następnie jest od nich zasadniczo odłączony – więc aktualizacje modelu JS nie są propagowane z powrotem do jego rodziców w Pythonie.

Podczas dyskusji na tej stronie zaproponowano również obejście przy użyciu IPython.notebook.kernel.execute do utworzenia lub nadpisania zmiennej w Pythonie. Można go używać tylko w nakładce na notebooka (odkryłem, że to obejście działa tylko wtedy, gdy w kodzie użyjesz output_notebook()).

Oto mój nowy kod do zmiany oryginalnych danych w Pythonie:

s.callback = CustomJS(args=dict(s1=s1), code="""
    var inds = s1.selected.indices;
    var d1 = s1.data;

    for (var i = 0; i < inds.length; i++) 
    {
    d1['color'][inds[i]] = 'red';
    var index = inds[i];
    var command = "s1.data['color'][" + index + "] = red";
    var kernel = IPython.notebook.kernel;
    kernel.execute(command);
    } 

    s1.change.emit();;
""")
0
formt 6 styczeń 2020, 06:17