Incrustar una ttwig en un sitio web con Python / bokeh

Estoy tratando de incrustar estáticamente una ttwig de bokeh en un sitio web personal, y me encuentro con un comportamiento que no entiendo. Básicamente, estoy generando una ttwig utilizando bokeh de la siguiente manera:

import bokeh.plotting as bplt import numpy as np x=np.random.random(100) y=np.random.random(100) bplt.output_file("t.html") plot=bplt.line(x,y) ##the following line refers to the bokeh installed on my home computer print plot.create_html_snippet( static_path='/usr/local/lib/python2.7/site-packages/bokeh/server/static/') ##the following line refers to the bokeh installed on my remote computer #print plot.create_html_snippet( # static_path='/opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/') 

Hasta ahora tan bueno. Esto produce un archivo que se parece a (random garbage).embed.js , y una cadena de impresión que contiene la syntax html que copio manualmente en un archivo html que estoy llamando testembed.html , que he reproducido a continuación:

   

Simple Embed Example

This is where my plot should be:

Si el código de Python hace referencia a mi instalación de python local y copio los archivos generados (.html y .embed.js) en mi computadora local, puedo ver el gráfico en el archivo html.

Sin embargo, lo que realmente quiero hacer es que esto se ejecute en una computadora remota, y que el archivo html sea accesible a través de la web en mi sitio personal.

Cuando tengo static_path refiérase a la instalación de Python de mi computadora remota (como se muestra arriba, comenté), no puedo ver el gráfico en la página html cuando static_path a través de la web (es decir, en http://mywebsite.com /testembed.html ). No tengo idea de por qué esto está sucediendo.

Para referencia, aquí está el código donde se define la función de fragmento de código html: https://github.com/ContinuumIO/bokeh/blob/master/bokeh/objects.py#L309 y observo que hay una opción que no estoy pasando create_html_snippet , es decir, embed_base_url , que podría tener algo que ver con esto.

¡Gracias por adelantado! Micro

EDITAR bigreddot el consejo de bigreddot , que resolvió el problema. El problema real que había tenido era que el servidor web que estaba usando, por razones de seguridad, solo podía acceder a las cosas en mi directorio public_html . La solución fue rsync el directorio bokeh/static en mi public_html y señalarlo:

 rsync -ax /opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/ /home/myusername/public_html/bokeh-static/ 

y luego modificar mi código de la siguiente manera:

 import bokeh.plotting as bplt import numpy as np x=np.random.random(100) y=np.random.random(100) bplt.output_file("t.html") plot=bplt.line(x,y) #the following line refers to the bokeh rsynced to my directory print plot.create_html_snippet( static_path='http://www.my_server_website/~myusername/bokeh-static/', embed_base_url = 'http://www.my_server_website/~myusername/where_.js_file_is_located') 

y luego, obviamente, copie el html generado en el testembed.html .

ACTUALIZACIÓN: la función create_html_snippet mencionada en la pregunta original fue obsoleta y eliminada hace años. Ahora hay varias formas nuevas de incorporar contenido de Bokeh disponible en el módulo bokeh.embed . Esta respuesta resumirá algunos de ellos.

Contenido independiente

El contenido de Bokeh independiente es HTML / JS / CSS puro que no está respaldado por un servidor Bokeh en ejecución. Sin embargo, el contenido de Bokeh independiente aún puede ser altamente interactivo, con herramientas de trazado (p. Ej. Paneo, zoom, selección), cepillado vinculado y widgets que activan acciones de CustomJS. Hay varias formas de incrustar contenido independiente:

json_item

Si desea crear una representación JSON pura del contenido que pueden cargar las funciones JS, puede usar la función json_item . A modo de ejemplo, puede servir el JSON desde un punto final de Flask:

 @app.route('/plot') def plot(): p = make_plot('petal_width', 'petal_length') return json.dumps(json_item(p, "myplot")) 

Entonces la página puede cargar y renderizar el contenido con código JavaScript como este:

 

Esto supone que ha cargado la biblioteca BokehJS en la página, por ejemplo, al CDN.render() plantilla de CDN.render() en el de la página. Vea un ejemplo mínimo completo aquí .

components

Si desea generar una etiqueta simple y

que se puede crear en una página, puede usar la función de components :

 from bokeh.plotting import figure from bokeh.embed import components plot = figure() plot.circle([1,2], [3,4]) script, div = components(plot) 

La script y div devueltos (o divs si pasa varios elementos) se pueden insertar en la página:

     Bokeh Scatter Plots        

Como se mencionó anteriormente, necesitará codificar o crear una plantilla de los recursos BokehJS JS y CSS en el encabezado de la página, por ejemplo, con CDN.render()

file_html

Si desea generar páginas HTML completas completas (es decir, incluyendo ), puede usar la función file_html :

 from bokeh.plotting import figure from bokeh.resources import CDN from bokeh.embed import file_html plot = figure() plot.circle([1,2], [3,4]) html = file_html(plot, CDN, "my plot") 

Esto genera una página básica que se puede guardar o servir, etc. Si lo desea, también puede suministrar su propia plantilla Jinja (consulte la documentación para obtener más información).

Aplicaciones de Servidor Bokeh

Las aplicaciones de servidor de Bokeh pueden conectar gráficos y widgets de Bokeh a un proceso de Python que se ejecuta en vivo, de modo que eventos como las interacciones de la IU, las selecciones o las manipulaciones de widgets pueden desencadenar códigos Python reales (por ejemplo, Pandas o scikit-learn).

Para incrustar una aplicación Bokeh básica en una plantilla de página, el método más común es usar server_document :

 from bokeh.embed import server_document script = server_document("https://demo.bokehplots.com/apps/slider") 

La script devuelta puede tener una plantilla en cualquier lugar de una página HTML, y la aplicación Bokeh aparecerá allí. Hay muchas otras posibilidades, por ejemplo, incrustar componentes de aplicaciones individualmente, personalizar sesiones para usuarios o ejecutar detrás de proxies / balanceadores de carga. Es posible que el servidor Bokeh también deba configurarse para permitir el acceso a la página de incrustación. Para obtener todos los detalles, consulte el capítulo Ejecución de un servidor Bokeh de la Guía del usuario.

Otra forma, posiblemente más sencilla de "incrustar" una aplicación de servidor Bokeh, es usar IFrames que apunta a la URL pública de una aplicación Bokeh en ejecución.

Edición: la información en esta respuesta pertenece a versiones extremadamente antiguas de Bokeh y ya no es relevante para ningún uso


embed_base_url controla la ruta de la URL (puede ser absoluta o relativa) en la que el javascript buscará el archivo incrustado.

embed_save_loc controla el directorio en el que Python escribirá el archivo incrustado. embed_save_loc no es necesario cuando server = True

static_path controla la ruta url (puede ser absoluta o relativa) que javascript usará para construir URLS para bokeh.js y bokeh.css. El valor predeterminado es http://localhost:5006/static/ , pero podría apuntar fácilmente a un CDN

Cuando ejecute el servidor bokeh, navegue a http://localhost:5006/bokeh/generate_embed/static . Creo que esto requiere que se ejecute en master debido a un error.

EDITAR: un CDN es una “Red de entrega de contenido”, es solo un término elegante para el servidor de archivos. Por ejemplo, alojamos bokeh.js en http://cdn.pydata.org/bokeh-0.4.2.js (o http://cdn.pydata.org/bokeh-0.4.2.min.js ) para cualquier persona usar.