Je veux que le tracé se mette à jour, une fois que je clique sur le "bouton d'actualisation", avec les nouvelles données. Mais les anciennes données restent dans le tracé, elles continuent également à se déplacer vers le bas et les ticks disparaissent.

Au début, l'intrigue ressemble à ce à quoi je m'attendais (à l'exception des informations sur l'axe X. Comme problème secondaire, j'ai recherché DataSpec() dans les propriétés Bokeh mais je ne sais pas comment passer le accept_datetime=False au x argument dans le tracé de ligne. Mon code ressemble à ceci.)

Le répertoire de données ressemble à

root-|
     |-weeklydata1.pkl
     |-weeklydata2.pkl
     |-datashow.py

Voici les fichiers de données décapés.

from bokeh.layouts import column, row
from bokeh.models.widgets import Button
from bokeh.plotting import figure, show
from pandas import *

# Callbacks
def update_data():
    # Set up plot
    global p
    global f
    # p = figure(title="testing plot")

    # Set up data
    # weeklybdxdata(1)
    print("reading new data")
    df1 = read_pickle('weeklydata2.pkl')
    for j in df1.columns:
        p.line(df1.index,
               df1[j],
               legend=j,
               line_color=f[j])
        p.circle(df1.index,
                 df1[j],
                 size=10,
                 color=f[j])
    return p

# Set up data
df =read_pickle('weeklydata1.pkl')
f = dict(OAT='green', SAT='orange', OAH='red')

# Set up plot
p = figure(title="testing plot")

for i in df.columns:
    p.line(df.index,
           df[i],
           legend=i,
           line_color=f[i])
    p.circle(df.index,
             df[i],
             size=10,
             color=f[i])

# Set up widgets
button = Button(label='Refresh')
button.on_click(update_data)
inputs = column(button)

curdoc().add_root(row(inputs, p, width=800))
curdoc().title = "Test Plot"

J'ai évité d'utiliser bokeh.models.ColumnDataSource car je ne pouvais pas trouver de bons exemples sur la façon de transmettre des trames de données.

Après avoir lancé le code avec bokeh serve datashow.py, le tracé initial ressemble à ceci (petit reproche : mais avec l'axe des x en millisecondes)

enter image description here

Après avoir cliqué sur Actualiser et actualisé successivement plusieurs fois, le tracé continue de se déplacer et l'axe d'information disparaît.

 enter image description here

Je suis sur la dernière version de Bokeh 1.4.0

0
CS101 26 nov. 2019 à 02:50

1 réponse

Meilleure réponse

Par défaut, Bokeh s'étend automatiquement sur tous les glyphes disponibles. Et votre code ci-dessus accumule à l'infini de nouveaux glyphes. Ainsi, le résultat que vous voyez est attendu. Vous pouvez essayer de supprimer activement les glyphes de cercle et de ligne précédents dans votre fonction de mise à jour, mais ce n'est pas ce que je recommanderais. La meilleure façon de mettre à jour les tracés, la façon dont Bokeh est optimisé pour fonctionner efficacement et bien, est de configurer tous vos glyphes une fois, puis plus tard, de mettre à jour uniquement le em>données pour eux.

C'est-à-dire que vous devez utiliser ColumnDataSource directement. Je remarque que tu dis :

J'ai évité d'utiliser bokeh.models.ColumnDataSource car je n'ai pas pu trouver de bons exemples sur la façon de transmettre des trames de données.

Je ne sais pas où vous cherchiez. Il existe de nombreux exemples à la fois dans la documentation et dans le dossier examples du référentiel qui utilisent CDS et Pandas ensemble. Vous pouvez initialiser un CDS en adaptant directement un DataFrame :

source = ColumnDataSource(df)

Ensuite, plus tard, lorsque vous souhaitez mettre à jour le source, vous pouvez le faire ;

source = ColumnDataSource.from_df(new_df)

Voici un exemple prototypique complet :

import pandas as pd
from bokeh.layouts import column
from bokeh.models import Button, ColumnDataSource
from bokeh.plotting import figure
from bokeh.io import curdoc

df = pd.DataFrame(dict(x=[1,2,3], y1=[4,5,6], y2=[2,3,4]))

source = ColumnDataSource(df)

plot = figure()
plot.line('x', 'y1', line_width=3, source=source)
plot.line('x', 'y2', line_width=3, color="red", source=source)

def update():
    new_df = pd.DataFrame(dict(x=[1,2,3], y1=[6,5,4], y2=[4,3,2]))
    source.data = ColumnDataSource.from_df(new_df)

button = Button()
button.on_click(update)

curdoc().add_root(column(button, plot))

petit reproche : mais avec le xaxis en millisecondes

Vous pouvez certainement avoir un axe datetime, si c'est ce que vous recherchez :

https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#datetime-axes

1
bigreddot 26 nov. 2019 à 05:30