NOTA: questa domanda riguarda il server Bokeh di "prima generazione", che è stato deprecato e rimosso per diversi anni. Nessuna disposizione della presente domanda o sue risposte è rilevante per qualsiasi versione di Bokeh> = 0,11Domande multiple con Bokeh orientato agli oggetti
sto cercando di capire Bokeh per un app interattiva che sto costruendo. Sto guardando il Bokeh examples, e vedo che la maggior parte degli esempi sono scritti tutti nello spazio dei nomi globale, ma quelli nella sottodirectory "app" sono scritti in uno stile piacevole, orientato agli oggetti, in cui la classe principale è rimossa da una classe di proprietà come HBox.
Questo sarà un miscuglio di domande perché non penso che questo modo di programmare Bokeh sia stato ben documentato. La prima cosa che ho riscontrato è che la trama non è stata disegnata a meno che non includessi lo extra_generated_classes
.
cosa fa extra_generated_classes fanno?
In secondo luogo, sembra che il ciclo degli eventi
setup_events
viene chiamato all'avvio primacreate
e successivamente ogni volta che la trama attiva un evento.Perché setup_events deve registrare i callback ogni volta che viene attivato un evento? E perché non aspetta che la creazione finisca prima di tentare di registrarli la prima volta?
L'ultima cosa di cui non sono sicuro è come forzare un ridisegno di un glifo qui. La demo del dispositivo di scorrimento funziona per me, e sto cercando di fare praticamente la stessa cosa, tranne che con uno scatterplot invece di una linea.
ho impostato una traccia PPB alla fine del mio
update_data
, e posso garantire cheself.source
corrispondeself.plot.renderers[-1].data_source
e che entrambi sono stati ottimizzati fin dall'inizio. Tuttavia, lo stessoself.plot
non cambia.Qual è l'equivalente del approccio orientato agli oggetti a chiamare store_objects per aggiornare la trama?
Sono particolarmente confuso da questo terzo, perché non sembra che l'esempio sliders_app abbia bisogno di qualcosa del genere.Per chiarimenti, sto cercando di fare un numero variabile di widgets/cursori, quindi questo è ciò che il mio codice è simile:
attributi di classe:
extra_generated_classes = [['ScatterBias', 'ScatterBias', 'HBox']]
maxval = 100.0
inputs = Instance(bkw.VBoxForm)
outputs = Instance(bkw.VBoxForm)
plots = Dict(String, Instance(Plot))
source = Instance(ColumnDataSource)
cols = Dict(String, String)
widgets = Dict(String, Instance(bkw.Slider))
# unmodified source
df0 = Instance(ColumnDataSource)
metodo initialize
@classmethod
def create(cls):
obj = cls()
##############################
## load DataFrame
##############################
df = pd.read_csv('data/crime2013_tagged_clean.csv', index_col='full_name')
obj.cols = {'x': 'Robbery',
'y': 'Violent crime total',
'pop': 'Population'
}
cols = obj.cols
# only keep interested values
df2= df.ix[:, cols.values()]
# drop empty rows
df2.dropna(axis=0, inplace=True)
df0 = df2.copy()
df0.reset_index(inplace=True)
# keep copy of original data
obj.source = ColumnDataSource(df2)
obj.df0 = ColumnDataSource(df0)
##############################
## draw scatterplot
##############################
obj.plots = {
'robbery': scatter(x=cols['x'],
y=cols['y'],
source=obj.source,
x_axis_label=cols['x'],
y_axis_label=cols['y']),
'pop': scatter(x=cols['pop'],
y=cols['y'],
source=obj.source,
x_axis_label=cols['pop'],
y_axis_label=cols['y'],
title='%s by %s, Adjusted by by %s'%(cols['y'],
cols['pop'], cols['pop'])),
}
obj.update_data()
##############################
## draw inputs
##############################
# bokeh.plotting.scatter
## TODO: refactor so that any number of control variables are created
# automatically. This involves subsuming c['pop'] into c['ctrls'], which
# would be a dictionary mapping column names to their widget titles
pop_slider = obj.make_widget(bkw.Slider, dict(
start=-obj.maxval,
end=obj.maxval,
value=0,
step=1,
title='Population'),
cols['pop'])
##############################
## make layout
##############################
obj.inputs = bkw.VBoxForm(
children=[pop_slider]
)
obj.outputs = bkw.VBoxForm(
children=[obj.plots['robbery']]
)
obj.children.append(obj.inputs)
obj.children.append(obj.outputs)
return obj
update_data
def update_data(self):
"""Update y by the amount designated by each slider"""
logging.debug('update_data')
c = self.cols
## TODO:: make this check for bad input; especially with text boxes
betas = {
varname: getattr(widget, 'value')/self.maxval
for varname, widget in self.widgets.iteritems()
}
df0 = pd.DataFrame(self.df0.data)
adj_y = []
for ix, row in df0.iterrows():
## perform calculations and generate new y's
adj_y.append(self.debias(row))
self.source.data[c['y']] = adj_y
assert len(adj_y) == len(self.source.data[c['x']])
logging.debug('self.source["y"] now contains debiased data')
import pdb; pdb.set_trace()
Nota che sono sicuro che il gestore eventi viene configurato e attivato correttamente. Semplicemente non so come far riflettere i dati sorgente modificati nel grafico a dispersione.
Hai trovato una soluzione a questo problema, in particolare per il re-rendering di dispersione? Sto indagando su Bokeh per qualcosa di simile. –
Prova a dividere le tue domande in blocchi più piccoli se vuoi delle risposte. – sorin