Я бьюсь над этой проблемой очень долго и не могу найти решение. В общем, нужно встраивать сервер bokeh в приложение Django. В документации много примеров по flask, но по django от начала до конца примеров нет. Ситуация следующая: у меня есть форма выпадающего выбора со строками в качестве значений параметров. Например MSFT
, TSLA
, GOOG
, OLOLO
. Я выбираю опцию из выпадающей формы, затем перенаправляю на страницу select/{str: option}
. В views.py
, который обрабатывает страницу, я хочу встроить сервер боке. У меня есть другой файл visualization.py
с классом, который содержит все настройки для графиков.
#visualization.py
import pandas as pd
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, Legend, NumeralTickFormatter
from bokeh.plotting import figure
doc = curdoc()
class BokehPlot:
def __init__(self, data):
self.data = data
self.df = self.collect_dataframe()
self.tools = 'pan,crosshair,wheel_zoom,reset'
self.plot_width = 1000
self.width = 0.5
self.xaxis_dt_format = '%d %b %Y'
if self.df['datetime'][0].hour > 0:
self.xaxis_dt_format = '%d %b %Y %H:%M'
self.major_x_axis = {i: date.strftime(self.xaxis_dt_format) for
i, date in enumerate(pd.to_datetime(self.df["datetime"]))}
self.inc_color = '#15aaba'
self.dec_color = '#7F7F7F'
def collect_dataframe(self):
if self.data is None:
raise Exception
df = pd.DataFrame(self.data)
df['datetime'] = pd.to_datetime(df.begin, format='%Y-%m-%d %H:%M')
df = df[['datetime', 'low', 'high', 'open', 'close', 'volume']]
return df
def plot_ohlc(self):
inc = self.df.close > self.df.open
dec = self.df.open > self.df.close
inc_source = ColumnDataSource(...)
dec_source = ColumnDataSource(...)
...
...
...
ohlc = figure(plot_width=self.plot_width, plot_height=500,
y_axis_location='right',
tools=self.tools,
active_scroll='wheel_zoom')
ohlc.segment(x0='x1', y0='high1', x1='x1', y1='low1', source=inc_source, color=self.inc_color)
...
...
return ohlc
def plot_macd(self):
macd = figure(plot_width=self.plot_width, plot_height=250,
x_range=self.x_range,
y_axis_location="right", tools=self.tools,
active_scroll='wheel_zoom')
ohlc.segment(x0='x1', y0='high1', x1='x1', y1='low1', source=inc_source,
color=self.inc_color)
...
...
return macd
#views.py:
from bokeh.embed import components
from bokeh.layouts import gridplot
from django.shortcuts import render
from .visualization import BokehPlot
def detail(request, security):
if request.method == 'GET':
...
...
plot = BokehPlot(data)
ohlc = plot.plot_ohlc()
macd = plot.plot_macd()
g_plot = gridplot([[ohlc], [macd]])
script, div = components(g_plot)
context = {'script': script, 'div': div}
return render(request, 'shares/detail.html', context)
#urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.select_share, name='select_share'),
path('<str:security>/', views.detail, name='detail'),
]
Теперь все работает с script, div = components()
. Но это не то, что я хочу. Я буду счастлив с любыми примерами кода. Мне нужен именно сервер bokeh, а не script,div = compose(figure)
для сложных обратных вызовов и более интерактивный.