4 votes

Comment changer la couleur d'un glyphe en utilisant un callback ?

J'ai fait quelques essais avec Bokeh, et maintenant je veux rechercher un mot et changer la couleur de son glyphe. Mon code ressemble à ça :

import bokeh.plotting as bp
from bokeh.models import HoverTool, CustomJS
from bokeh.models.widgets import TextInput
from bokeh.io import vform

words = ["werner", "herbert", "klaus"]
x=[1,2,3]
y=[1,2,3]
color = ['green', 'blue', 'red']
word_input= TextInput(value="word", title="Point out a word")

source = bp.ColumnDataSource(data= dict(x=x,y=y,words=words, color='color'))
hover= HoverTool(tooltips=[("word", "@words")])

# output to static HTML file (with CDN resources)
bp.output_file("plot.html", mode="cdn")

# create a new plot with the tools above, and explicit ranges
p = bp.figure(plot_height = 600, plot_width = 800, title="word2vec", tools=[hover], logo =None)
# add a circle renderer with vectorized colors and sizes
p.circle('x','y', radius= 0.1, color = color, source=source, line_color=None)
callback= CustomJS(args=dict(source=source), code ="""
    var data = source.get('data');
    var glyph = cb_obj.get('value')
    words = data['words']
    colors=data['color']
    for (i=0; i< words.length;i++){
        if(glyph==words[i]){colors[i]='yellow'}        
    }
    source.trigger('change');
""")
layout = vform(word_input, p)
# show the results
bp.show(layout)

Ce code ne fonctionne pas, et je n'arrive pas à comprendre pourquoi.

Qu'est-ce que je fais de mal ? J'ai posté une autre question plus tôt ce jour-là et c'est une sorte de première étape pour le résoudre.

5voto

bigreddot Points 15929

Il y a quelques problèmes que vous avez :

  • vous créez le CallbackJS mais ne le définissent jamais comme la propriété de rappel de la fonction TextInput

  • vous définissez le color clé du dict de données à la chaîne "color" pas à la liste des couleurs

  • vous avez transmis la liste des couleurs réelles en tant que color argument pour figure (il doit s'agir de la chaîne de caractères du nom de la colonne de la source de données que vous souhaitez utiliser, par ex. "color" )


Voici une version qui fonctionne :

from bokeh.io import vform
from bokeh.models import HoverTool, CustomJS
from bokeh.models.widgets import TextInput
from bokeh.plotting import output_file, figure, show, ColumnDataSource

output_file("plot.html")

words = ["werner", "herbert", "klaus"]
x, y = [1,2,3], [1,2,3]
color = ['green', 'blue', 'red']

source = ColumnDataSource(data=dict(x=x, y=y, words=words, color=color))

hover = HoverTool(tooltips=[("word", "@words")])

p = figure(plot_height=600, plot_width=800, title="word2vec", tools=[hover])
p.circle('x','y', radius=0.1, fill_color='color', source=source, line_color=None)

callback = CustomJS(args=dict(source=source), code="""
    var data = source.get('data')
    var value = cb_obj.get('value')
    var words = data['words']
    for (i=0; i < words.length; i++) {
        if ( words[i]==value ) { data.color[i]='yellow' }
    }
    source.trigger('change')
""")

word_input = TextInput(value="word", title="Point out a word", callback=callback)

layout = vform(word_input, p)

show(layout)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X