web-dev-qa-db-fra.com

Quel est un moyen rapide et approprié d'actualiser / mettre à jour des tracés dans l'application serveur Bokeh (0.11)?

J'ai une application de service bokeh (v0.11) qui produit un nuage de points en utilisant les coordonnées (x, y) à partir d'une trame de données. Je souhaite ajouter des interactions telles que lorsqu'un utilisateur sélectionne des points sur le graphique ou entre le nom de points séparés par des virgules dans la zone de texte (par exemple, "p55, p1234"), ces points deviennent rouges sur le nuage de points.

J'ai trouvé un moyen d'y parvenir (stratégie n ° 3, ci-dessous) mais c'est terriblement lent pour les grandes trames de données. Je pense qu'il existe une meilleure méthode. Quelqu'un peut m'aider? Suis-je en train de manquer un appel de fonction évident?

  • La stratégie 1 (<1 ms pour 100 points) explore les données ColumnDataSource pour le tracé existant et tente de modifier les points sélectionnés.
  • La stratégie 2 (~ 70 ms pour 100 points) remplace le ColumnDataSource existant du tracé par un ColumnDataSource nouvellement créé.
  • La stratégie 3 (~ 400 ms pour 100 points) est la stratégie 2, puis elle recrée la figure.

Le code est déposé sur Pastebin: http://Pastebin.com/JvQ1UpzY La partie la plus pertinente est copiée ci-dessous.

def refresh_graph(self, selected_points=None, old_idxs=None, new_idxs=None):
    # Strategy 1: Cherry pick current plot's source.
    # Compute time for 100 points: < 1ms.
    if self.strategy == 1:
        t1 = datetime.now()
        for idx in old_idxs:
            self.graph_plot.data_source.data['color'][idx] = 'steelblue'
        for idx in new_idxs:
            self.graph_plot.data_source.data['color'][idx] = 'red'
        print('Strategy #1 completed in {}'.format(datetime.now() - t1))
    else:
        t3 = datetime.now()
        self.coords['color'] = 'steelblue'
        self.coords.loc[selected_points, 'color'] = 'red'
        new_source = bkmodels.ColumnDataSource(self.coords)
        self.graph_plot = self.graph_fig.scatter('x', 'y', source=new_source, color='color', alpha=0.6)
        print('Strategy #3 completed in {}'.format(datetime.now() - t3))
    return

Idéalement, j'aimerais pouvoir utiliser la stratégie n ° 1 , mais cela ne semble pas permettre aux points de se rafraîchir dans le navigateur client.

Merci pour toute aide!

Pour info: j'utilise RHEL 6.X

18
user2700854

Si vous êtes streaming données, alors il y a une réponse connexe ici: Timeseries streaming en bokeh

Si vous avez besoin de tout mettre à jour en même temps, vous pouvez le faire, et ma suggestion est votre stratégie 1 , qui est démontrée, par exemple ici:

https://github.com/bokeh/bokeh/blob/master/examples/app/sliders.py

La chose particulière à noter est que vous devez vraiment mettre à jour tout source.data en une fois. L'une des hypothèses est que toutes les colonnes d'une source de données de colonne ont toujours la même longueur. La mise à jour de colonnes individuelles risque de briser cette hypothèse, ce qui peut entraîner des problèmes. Vous voulez donc mettre à jour tout à la fois, avec quelque chose comme:

# Generate the new curve
x = np.linspace(0, 4*np.pi, N)
y = a*np.sin(k*x + w) + b

source.data = dict(x=x, y=y)
9
bigreddot