связать обновление графика plotly с обновлением dataframe
У меня есть датафрейм, который обновляется в цикле. Изначально он выглядит следующим образом

А затем я активирую скрипт в ячейке юпитера и значения NaN начинают заполняться конкретными числами. По этому фрейму должен строиться heatmap, я решил попробовать для этого plotly:
Фрейм в начальный момент времени
Фрейм начал заполняться
Меня интересует, как сделать так, чтобы plotly автоматически реагировал на изменения в датафрейме и обновлял график, чтобы не пришлось каждый раз останавливать расчет и проверять, как выглядит график в текущий момент.
Как я понимаю, в этой библиотеке должно быть какое то элегантное решение, без нагромождения дополнительных циклов.
Я нашел один метод в документации, но не уверен, что он подойдет для этих целей, так как там очень смутно описан принцип действия:
import plotly.graph_objects as go
import cufflinks as cf
from plotly.offline import init_notebook_mode
init_notebook_mode(connected=True)
cf.go_offline()
fig = go.Figure(data=go.Heatmap(z=df.response,
x=df.currents,
y=df.frequencies))
fig.update_layout(datarevision=???) # вот этот
Хотелось бы узнать, как можно это реализовать наиболее простым способом?
Ответы (1 шт):
Итак, к какому решению пришел я сам:
Здесь логичнее не обновлять plotly график вручную, а доверить это библиотеке Dash. Можно построить простенькое dash приложение непосредственно в ноутбуке, чтобы не приходилось открывать локальный сервер в браузере.
- Если вы хотите обновлять данные по мере их поступления, вам нужен подход, основанный на обработке событий (event). В данном примере этим самым событием является время dash Interval
# initialise dataframe and figure
df = pd.DataFrame({"response":[], "currents":[], "frequencies":[]})
fig = go.Figure(data=go.Heatmap(z=df.response,
x=df.currents,
y=df.frequencies))
# Build App
app = JupyterDash(__name__)
app.layout = html.Div(
[
dcc.Graph(id="heatmap", figure=fig),
dcc.Interval(id="animateInterval", interval=400, n_intervals=0),
],
)
@app.callback(
Output("heatmap", "figure"),
Input("animateInterval", "n_intervals"),
State("heatmap", "figure")
)
def doUpdate(i, fig):
global df
df = pd.concat([df, pd.DataFrame({"response":np.random.uniform(1,5,100), "currents":np.random.randint(1,20,100), "frequencies":np.random.randint(1,50,100)})])
return go.Figure(fig).update_traces(go.Heatmap(z=df.response,
x=df.currents,
y=df.frequencies))
# Run app and display result inline in the notebook
app.run_server(mode="inline")
Более подробно про то, как строятся Dash приложения и как использовать те или иные функции можно прочитать на странице с туториалами от Dash
Вот также неплохое вводное видео по теме
https://www.youtube.com/watch?v=hSPmj7mK6ng