Вложение сюжета на сайт с Python/bokeh
Я пытаюсь статически встраивать сюжет bokeh в личный сайт, и я сталкиваюсь с каким-то поведением, которого я не понимаю. В принципе, я создаю сюжет, используя bokeh следующим образом:
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/')
Пока все хорошо. Это создает файл, который выглядит как (random garbage).embed.js
, и строка print, содержащая синтаксис html, который я вручную копирую в html файл, который я вызываю testembed.html
, который я воспроизвел ниже:
<html>
<body>
<h2>Simple Embed Example</h2>
<p>This is where my plot should be:</p>
<p>
<!--The next 4 lines are the output of the print statement from the python code-->
<script src="ccbd451a-6995-4dd2-b99c-e4140b362997.embed.js"
bokeh_plottype="embeddata"
bokeh_modelid="ccbd451a-6995-4dd2-b99c-e4140b362997"
bokeh_modeltype="Plot" async="true"></script>
</p>
</body>
</html>
Если у меня есть ссылка на код python, моя локальная установка python и копирование сгенерированных файлов (.html и .embed.js) на мой локальный компьютер, я может видеть график в html файле.
Однако, что я действительно хочу сделать, это запустить этот запуск на удаленном компьютере и иметь html файл, доступный через Интернет на моем личном сайте.
Когда я static_path
ссылаюсь на установку python моего удаленного компьютера (как показано выше, закомментирован), я не вижу график на странице html, когда я обращаюсь к нему через Интернет (т.е. переход на http://mywebsite.com/testembed.html). Я понятия не имею, почему это происходит.
Для справки, вот код, в котором определена функция html snippet:
https://github.com/ContinuumIO/bokeh/blob/master/bokeh/objects.py#L309
и я отмечаю, что есть вариант, который я не передаю в create_html_snippet
, т.е. embed_base_url
, что может иметь какое-то отношение к этому.
Спасибо заранее!
Mike
ИЗМЕНИТЬ
Я принял совет bigreddot
, который решил проблему. Фактическая проблема, с которой я столкнулся, заключалась в том, что используемый мной веб-сервер был для целей безопасности доступ к вещам только в моем каталоге public_html
. Обходной путь состоял в rsync
каталоге bokeh/static
в моем public_html
и указывал на следующее:
rsync -ax /opt/anaconda/lib/python2.7/site-packages/bokeh/server/static/ /home/myusername/public_html/bokeh-static/
а затем измените мой код следующим образом:
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')
а затем, очевидно, скопируйте сгенерированный html в testembed.html
.
Ответы
Ответ 1
ОБНОВЛЕНИЕ: функция create_html_snippet
упомянутая в исходном вопросе, устарела и удалена много лет назад. Теперь в модуле bokeh.embed
доступны различные новые способы встраивания содержимого Bokeh. Этот ответ обобщит некоторые из них.
Автономный контент
Автономный контент Bokeh - это чистый HTML/JS/CSS, который не поддерживается работающим сервером Bokeh. Тем не менее, автономный контент Bokeh может быть очень интерактивным, с инструментами построения графиков (например, панорамированием, масштабированием, выделением), связанными чистками и виджетами, которые запускают действия CustomJS. Есть несколько способов встроить автономный контент:
json_item
Если вы хотите создать чистое JSON-представление контента, который может быть загружен функциями JS, вы можете использовать функцию json_item
. Например, вы могли бы сервировать JSON с конечной точки Flask:
@app.route('/plot')
def plot():
p = make_plot('petal_width', 'petal_length')
return json.dumps(json_item(p, "myplot"))
Затем страница может загружать и отображать содержимое с помощью кода JavaScript, например:
<div id="myplot"></div>
<script>
fetch('/plot')
.then(function(response) { return response.json(); })
.then(function(item) { Bokeh.embed.embed_item(item); })
</script>
Предполагается, что вы загрузили библиотеку BokehJS на страницу, например, с помощью CDN.render()
в <head>
страницы. Смотрите полный минимальный пример здесь.
components
Если вы хотите сгенерировать простой <script>
и <div>
которые можно шаблонизировать на страницу, вы можете использовать функцию components
:
from bokeh.plotting import figure
from bokeh.embed import components
plot = figure()
plot.circle([1,2], [3,4])
script, div = components(plot)
Возвращенный script
и div
(или divs, в котором вы передаете несколько элементов) можно вставить на страницу:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bokeh Scatter Plots</title>
<!-- COPY/PASTE BOKEHJS RESOURCES HERE -->
<!-- COPY/PASTE SCRIPT HERE -->
</head>
<body>
<!-- INSERT DIVS HERE -->
</body>
</html>
Как и выше, вам нужно жестко кодировать или шаблонировать ресурсы BokehJS JS и CSS в заголовке страницы, например, с помощью CDN.render()
file_html
Если вы хотите сгенерировать все полные HTML-страницы (например, <head></head><body></body>
), вы можете использовать функцию 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")
Это создает базовую страницу, которую можно сохранить или обслуживать и т.д. При желании вы также можете предоставить свой собственный шаблон Jinja (подробности см. В документации).
Серверные приложения Bokeh
Серверные приложения Bokeh могут подключать графики и виджеты Bokeh к действующему процессу Python, так что такие события, как взаимодействие с пользовательским интерфейсом, выбор или манипуляции виджетами, могут запускать реальный код Python (например, Pandas или scikit-learn).
Чтобы встроить базовое приложение Bokeh в шаблон страницы, наиболее распространенным методом является использование server_document
:
from bokeh.embed import server_document
script = server_document("https://demo.bokehplots.com/apps/slider")
Возвращенный script
может быть шаблонизирован в любом месте HTML-страницы, и там появится приложение Bokeh. Существует много других возможностей, например, индивидуальное встраивание компонентов приложения, настройка сеансов для пользователей или запуск за прокси-серверами/балансировщиками нагрузки. Сервер Bokeh также может быть необходимо настроить, чтобы разрешить доступ к странице встраивания. Для получения полной информации см. Главу " Запуск сервера Bokeh" в Руководстве пользователя.
Другой, возможно, более простой способ "встраивания" серверного приложения Bokeh - это использование IFrames, указывающих на общедоступный URL-адрес запущенного приложения Bokeh.
Ответ 2
Похоже, вы хотите сделать "не-серверное", что на самом деле означает, что описание сюжета и все данные для сюжета содержатся в файле foo.embed.js
вместо того, чтобы вытащить его из "сервера Bokeh" ". В этом случае вы хотите установить embed_base_url
в местоположение (на вашем сервере), где будет доступен файл embed.js. В принципе, embed_base_url
влияет на атрибут src
тега script:
In [11]: print plot.create_html_snippet(embed_base_url="/some/location/")
<script src="/some/location/c6aa5f66-4136-403f-a307-ce0e2a64f6b4.embed.js"
bokeh_plottype="embeddata"
bokeh_modelid="c6aa5f66-4136-403f-a307-ce0e2a64f6b4"
bokeh_modeltype="Plot" async="true"></script>
В противоположность этому, static_path
указывает код построения, где (на вашем сервере, или CDN, или где-либо) найдите bokeh.js
.
Просто примечание, которое может немного измениться в будущих выпусках, будет немного более гибким. Сейчас он всегда ищет {{static_root}}/js/bokeh.js
Ответ 3
Изменение: информация в этом ответе относится к очень старым версиям Bokeh и больше не имеет отношения к любому использованию
embed_base_url
контролирует путь URL (он может быть абсолютным или относительным), в котором javascript будет искать файл для встраивания.
embed_save_loc
контролирует каталог, в который python запишет файл для встраивания. embed_save_loc не требуется, когда server = True
static_path
контролирует путь URL-адреса (он может быть абсолютным или относительным), который JavaScript будет использовать для создания URL-адресов для bokeh.js и bokeh.css. По умолчанию это http://localhost:5006/static/
, но он также может указывать на CDN.
При запуске сервера bokeh перейдите по http://localhost:5006/bokeh/generate_embed/static
. Я думаю, что это требует, чтобы вы работали на мастере из-за ошибки.
РЕДАКТИРОВАТЬ: CDN - это "Сеть доставки контента", это просто модный термин для файлового сервера. Например, мы размещаем bokeh.js по адресу http://cdn.pydata.org/bokeh-0.4.2.js (или http://cdn.pydata.org/bokeh-0.4.2.min.js) для всех использовать.