Перезагрузите статический HTML-график в Bokeh 3.4.1.Python

Программы на Python
Anonymous
Перезагрузите статический HTML-график в Bokeh 3.4.1.

Сообщение Anonymous »

Я создаю график, а затем обновляю фрейм данных каждый раз, когда от брокера извлекается новый бар. На самом деле я заменяю кадр данных новыми 400 столбцами (на самом деле в конец следует добавить только 1), чтобы график всегда имел длину 400 столбцов. У меня возникли проблемы с обновлением перезагрузки моего статического графика HTML. Как я могу добавить обратный вызов или функцию для перезагрузки окна всякий раз, когда я сохраняю новый рисунок в документе?
Эта функция построения графика вызывается из другого модуля, который фактически извлекает данные нового бара из маклер. Я подумываю о том, чтобы просто снова запустить эту функцию ниже с новым фреймом данных и вместо этого вызвать save(fig) вместо show(fig), но опять же, как я могу сообщить документу, что доступна новая сохраненная версия, и перезагрузить текущую страницу . Я не хочу, чтобы каждый раз при обновлении фрейма данных открывался новый экземпляр браузера.
РЕДАКТИРОВАТЬ: Код обновлен для работы, извините!

Код: Выделить всё

import numpy as np
import os

from functools import partial
from itertools import cycle

from typing import Dict
# from data_objects import Indicator

from bokeh.palettes import Category10
from bokeh.layouts import gridplot
from bokeh.transform import factor_cmap
from bokeh.models import (
Range1d,
ColumnDataSource,
CustomJSTickFormatter,
DatetimeTickFormatter,
HoverTool,
NumeralTickFormatter,
CrosshairTool,
WheelZoomTool,
Span,
CustomJS
)
from bokeh.plotting import figure, show, curdoc, save
from bokeh.io.state import curstate
from bokeh.io import output_file
from bokeh.colors.named import (
lime as BULL_COLOR,
tomato as BEAR_COLOR
)
OHLCV_LIST = ['Open', 'High', 'Low', 'Close', 'Volume']

def _bokeh_reset(filename=None):
curstate().reset()
if filename:
if not filename.endswith('.html'):
filename += '.html'
output_file(filename, title=filename)
else:
output_file('default.html', title='')

def plot(df: pd.DataFrame, indicators: Dict[str, str]=None, update_plot=False):

# reset the current state and create an html output
_bokeh_reset('test_plot')

COLORS = [BEAR_COLOR, BULL_COLOR]
BAR_WIDTH = .8

is_datetime_index = isinstance(df.index, pd.DatetimeIndex)

# copy dataframe without indicators
plot_df = df[list(OHLCV_LIST)].copy(deep=False)

# get indicators for plot
indicator_columns = df.columns.difference(plot_df.columns)

plot_df.index.name = None  # Provides source name @index
plot_df['datetime'] = plot_df.index  # Save original, maybe datetime index
plot_df = plot_df.reset_index(drop=True)
index = plot_df.index

# Initialize Bokeh figure function
new_bokeh_figure = partial(
figure,
x_axis_type='linear',
width=500,
height=400,
tools="xpan,xwheel_zoom,box_zoom,undo,redo,reset,save",
active_drag='xpan',
sizing_mode='stretch_both',
active_scroll='xwheel_zoom')

pad = (index[-1] - index[0]) / 20
_kwargs = dict(x_range=Range1d(index[0], index[-1],
min_interval=10,
bounds=(index[0] - pad,
index[-1] + pad))) if index.size >  1 else {}
# create bokeh figure instance
fig_ohlc = new_bokeh_figure(**_kwargs)
# used for volume and can be extended in the future
figs_below_ohlc = []

# create source object
source = ColumnDataSource(plot_df)
source.add((plot_df.Close >= plot_df.Open).values.astype(np.uint8).astype(str), 'inc')
# map colors
inc_cmap = factor_cmap('inc', COLORS, ['0', '1'])

def new_indicator_figure(**kwargs):
kwargs.setdefault('height', 150)
fig = new_bokeh_figure(x_range=fig_ohlc.x_range,
active_scroll='xwheel_zoom',
active_drag='xpan',
sizing_mode='stretch_width',
**kwargs)
fig.xaxis.visible = False
fig.yaxis.minor_tick_line_color = None
return fig

# create function to add candlesticks for OHLC
def _plot_ohlc():
"""Main OHLC bars"""
fig_ohlc.segment('index', 'High', 'index', 'Low', source=source, color="black")
fig_ohlc.vbar('index', BAR_WIDTH, 'Open', 'Close', source=source,
line_color="black", fill_color=inc_cmap)

def _plot_volume_section():
"""Volume section"""
fig = new_indicator_figure(y_axis_label="Volume")
fig.xaxis.formatter = fig_ohlc.xaxis[0].formatter
fig.xaxis.visible = True
fig_ohlc.xaxis.visible = False  # Show only Volume's xaxis
fig.vbar('index', BAR_WIDTH, 'Volume', source=source, color='red')
return fig

fig_volume = _plot_volume_section()
figs_below_ohlc.append(fig_volume)
ohlc_bars = _plot_ohlc()
plots = [fig_ohlc] + figs_below_ohlc # where figs_below holds the volume figure

fig = gridplot(
plots,
ncols=1,
toolbar_location='right',
toolbar_options=dict(logo=None),
merge_tools=True,
sizing_mode='stretch_both'
)
show(fig)
return fig
РЕДАКТИРОВАТЬ 2: при повторном вызове этой функции и сохранении рисунка вместо отображения его после обновления я могу просто обновить окно браузера и создать новый диаграмма заполняется. В конце моего файла я добавил это

Код: Выделить всё

    if (update_plot):
save(fig)
else:
show(fig)
return fig
Но я спрашиваю, как автоматически обновить это окно браузера, а не делать это вручную

Подробнее здесь: https://stackoverflow.com/questions/788 ... okeh-3-4-1

Вернуться в «Python»