examples - python bokeh download
MĂșltiples preguntas con Bokeh orientado a objetos (1)
Estoy buscando las mismas respuestas (la falta de documentación lo dificulta).
En respuesta, a la pregunta # 1, ¿cuál es la utilidad de "extra_generated_classes":
tl; dr extra_generated_classes define un nombre de módulo, nombre de clase y nombre principal utilizado en la plantilla que genera código js / html, y amplía la clase padre pasada a la clase de aplicación (generalmente HBox o VBox en los ejemplos).
Respuesta más larga. Mire el código fuente en bokeh / server / utils / plugins.py, este es el código que se ejecuta en el código pasado a bokeh-server usando el argumento de línea de comandos --script. Al final de plugins.py, puede ver que extra_generated_classes se pasa al método de matraz render_template , que representa una plantilla de Jinja2 . Mirando dentro de la plantilla, oneobj.html, extra_generated_classes es una matriz de matrices de tres cosas: modulename, classname y parentname, que se pasan a bokeh.server.generatejs:
{% block extra_scripts %}
{% for modulename, classname, parentname in extra_generated_classes %}
<script
src="{{ url_for(''bokeh.server.generatejs'', modulename=modulename, classname=classname, parentname=parentname) }}"
></script>
{% endfor %}
{% endblock %}
bokeh.server.generatejs es un código Python en bokeh / server / views / plugins.py, y solo llama a render_template para una plantilla app.js, que puedes encontrar en bokeh / server / templates. Esta plantilla toma el nombre de módulo, nombre de clase y nombre principal, y básicamente crea el código js que extiende el nombre principal (por ejemplo, HBox o VBox) al nombre de clase (su aplicación).
NOTA : Esta pregunta se refiere al servidor Bokeh de "primera generación", que ha quedado obsoleto y eliminado durante varios años. Nada en esta pregunta o sus respuestas es relevante para cualquier versión de Bokeh> = 0.11
Bokeh entender Bokeh para una aplicación interactiva que estoy construyendo. Estoy viendo los ejemplos de Bokeh , y veo que la mayoría de los ejemplos están escritos en el espacio de nombres global, pero los que están en el subdirectorio "aplicación" están escritos en un estilo agradable orientado a objetos, donde la clase principal está dentro de una clase de propiedad como HBox.
Esto va a ser una mezcolanza de preguntas porque no creo que esta forma de programar Bokeh estuviera muy bien documentada. Lo primero que encontré fue que la trama no se dibujó a menos que incluyera extra_generated_classes
.
¿Qué hace extra_generated_classes?
En segundo lugar, parece que el ciclo de eventos
setup_events
se llama al inicio antes decreate
y, posteriormente, cada vez que el gráfico desencadena un evento.¿Por qué setup_events necesita registrar devoluciones de llamadas cada vez que se desencadena un evento? ¿Y por qué no espera a que termine la creación antes de intentar registrarlos la primera vez?
Lo último que no estoy seguro es cómo forzar un rediseño de un glifo aquí. La demostración del control deslizante funciona para mí, y estoy tratando de hacer básicamente lo mismo, excepto con un diagrama de dispersión en lugar de una línea.
Establecí un rastreo pdb al final de mi
update_data
, y puedo garantizar queself.source
coincida conself.plot.renderers[-1].data_source
y que ambos hayan sido modificados desde el principio. Sin embargo,self.plot
sí mismo no cambia.¿Cuál es el enfoque orientado a objetos equivalente a llamar a store_objects para actualizar el diagrama?
Estoy especialmente confundido por este tercero, porque no parece que el ejemplo de sliders_app necesite algo así. Para aclarar, intento hacer una cantidad variable de widgets / controles deslizantes, así que este es el aspecto de mi código:
atributos de clase:
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)
método de inicialización
@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
actualizar datos
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()
Tenga en cuenta que estoy seguro de que el controlador de eventos se configura y se desencadena correctamente. Simplemente no sé cómo hacer que los datos fuente cambiados se reflejen en el diagrama de dispersión.