Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 由和间隔组件更新的全局变量_Python_Plotly Dash - Fatal编程技术网

Python 由和间隔组件更新的全局变量

Python 由和间隔组件更新的全局变量,python,plotly-dash,Python,Plotly Dash,当我的dash应用程序启动时,一个计算复杂的函数会创建一个全局变量(dat)。我希望dat定期更新,但不是通过任何用户操作。我知道由于内存共享的方式,普通的python全局变量不适合在dash中使用,因此我使用一个隐藏的div来存储定期更新的数据 我不希望在每个用户启动应用程序时更新数据,而是希望在后台进行更新,最好使用更新的数据更新所有用户的应用程序。如果应用程序必须更新页面刷新,也可以,但更新的数据将可供所有用户使用 我在下面举了一个例子,它执行我想做的任务,问题是如果数据是字符串或nump

当我的dash应用程序启动时,一个计算复杂的函数会创建一个全局变量(dat)。我希望dat定期更新,但不是通过任何用户操作。我知道由于内存共享的方式,普通的python全局变量不适合在dash中使用,因此我使用一个隐藏的div来存储定期更新的数据

我不希望在每个用户启动应用程序时更新数据,而是希望在后台进行更新,最好使用更新的数据更新所有用户的应用程序。如果应用程序必须更新页面刷新,也可以,但更新的数据将可供所有用户使用

我在下面举了一个例子,它执行我想做的任务,问题是如果数据是字符串或numpy数组,那么将数据存储在div中就可以了,但是如果数据结构更复杂,比如pandas数据帧(参见注释的代码行)或pandas数据帧字典,那么应用程序将运行,但该页面不会加载到浏览器中(加载布局时出错)。也许记忆是解决办法,尽管我所看到的所有例子都与此有细微的不同,以至于我看不出如何使用它。使用隐藏的div对我来说似乎有点像是一种黑客,但在绘图图腾的帮助页面中推荐使用

所以我的问题是,如何使用比字符串或数组更复杂的数据结构在dash中创建和更新全局变量

import dash
from dash.dependencies import Input, Output, Event
import dash_html_components as html
import dash_core_components as dcc
from datetime import datetime
import numpy as np
import pandas as pd


app = dash.Dash(__name__)

def compute_expensive_data():
    t=datetime.now()
    dat = np.array([t.minute, t.second])
    #d = {'time' : pd.Series(np.array([t.minute, t.second]), index=['minute', 'second'])}
    #dat = pd.DataFrame(d)

    return  dat

dat = compute_expensive_data()
print(dat)

app.layout = html.Div([
        html.H3('Original Time: Minute = ' + str(dat[0]) + ': Second = ' + str(dat[1])),
        #html.H3('Original Time: Minute = ' + str(dat['time']['minute']) + ': Second = ' + str(dat['time']['second'])),
        html.Div(id='title-line-children'),
        dcc.RadioItems(
            id='time-dropdown',
            options=[
                {'label': 'Minute', 'value': 'minute'}, {'label': 'Second', 'value': 'second'},
            ],
            value='minute'
        ), 

        # Hidden div inside the app that stores the intermediate value
        html.Div(id='intermediate-value', style={'display': 'none'}, children = dat),

        dcc.Interval(
            id='interval-component',
            interval=20*1000 # 20 seconds in milliseconds
        )

    ])

@app.callback(
    Output('title-line-children', 'children'),
    [Input('time-dropdown', 'value'), Input('intermediate-value', 'children')])
def render(value,dat1):
    if value == 'minute':
        printStr = str(dat1[0])
        #printStr = str(dat1['time']['minute'])
        outStr = 'Minute = ' + printStr
    elif value == 'second':
        printStr = str(dat1[1])
        #printStr = str(dat1['time']['second'])
        outStr = 'Second = ' + str(dat1[1])

    return outStr

@app.callback(Output('intermediate-value', 'children'),
              events=[Event('interval-component', 'interval')])
def update_global_var():
    return compute_expensive_data()

if __name__ == '__main__':
    app.run_server(debug=True)

好的,所以答案很直截了当。我只需要jsonify我的数据帧。然后它基本上只是一个可以保存在隐藏div中的字符串

import dash
from dash.dependencies import Input, Output, Event
import dash_html_components as html
import dash_core_components as dcc
from datetime import datetime
import numpy as np
import pandas as pd


app = dash.Dash(__name__)

def compute_expensive_data():
    t=datetime.now()
    d = {'time' : pd.Series(np.array([t.minute, t.second]), index=['minute', 'second'])}
    dat = pd.DataFrame(d).to_json()

    return  dat

dat = compute_expensive_data()
print(dat)

app.layout = html.Div([
        html.H3('Original Time: Minute = ' + str(pd.read_json(dat)['time']['minute']) + ': Second = ' + str(pd.read_json(dat)['time']['second'])),
        html.Div(id='title-line-children'),
        dcc.RadioItems(
            id='time-dropdown',
            options=[
                {'label': 'Minute', 'value': 'minute'}, {'label': 'Second', 'value': 'second'},
            ],
            value='minute'
        ), 

        # Hidden div inside the app that stores the intermediate value
        html.Div(id='intermediate-value', style={'display': 'none'}, children = dat),

        dcc.Interval(
            id='interval-component',
            interval=20*1000 # 20 seconds in milliseconds
        )

    ])

@app.callback(
    Output('title-line-children', 'children'),
    [Input('time-dropdown', 'value'), Input('intermediate-value', 'children')])
def render(value,dat1):
    if value == 'minute':
        printStr = str(pd.read_json(dat1)['time']['minute'])
        outStr = 'Minute = ' + printStr
    elif value == 'second':
        printStr = str(pd.read_json(dat1)['time']['second'])
        outStr = 'Second = ' + printStr

    return outStr

@app.callback(Output('intermediate-value', 'children'),
              events=[Event('interval-component', 'interval')])
def update_global_var():
    return compute_expensive_data()

if __name__ == '__main__':
    app.run_server(debug=True)

更新至破折号1.8的答案:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
from datetime import datetime
import numpy as np
import pandas as pd

app = dash.Dash(__name__)

def compute_expensive_data():
    t=datetime.now()
    d = {'time' : pd.Series(np.array([t.minute, t.second]), index=['minute', 'second'])}
    dat = pd.DataFrame(d).to_json()
    return  dat

dat = compute_expensive_data()
print(dat)

app.layout = html.Div([
        html.H3('Original Time: Minute = ' + str(pd.read_json(dat)['time']['minute']) + ': Second = ' + str(pd.read_json(dat)['time']['second'])),
        html.Div(id='title-line-children'),
        dcc.RadioItems(
            id='time-dropdown',
            options=[
                {'label': 'Minute', 'value': 'minute'}, {'label': 'Second', 'value': 'second'},
            ],
            value='minute'
        ), 
        # Hidden div inside the app that stores the intermediate value
        html.Div(id='intermediate-value', style={'display': 'none'}, children = dat),
        dcc.Interval(
            id='interval-component',
            interval=2*1000, # 20 seconds in milliseconds
            n_intervals=0
        )
    ])

@app.callback(
    Output('title-line-children', 'children'),
    [Input('time-dropdown', 'value'), Input('intermediate-value', 'children')])
def render(value,dat1):
    if value == 'minute':
        printStr = str(pd.read_json(dat1)['time']['minute'])
        outStr = 'Minute = ' + printStr
    elif value == 'second':
        printStr = str(pd.read_json(dat1)['time']['second'])
        outStr = 'Second = ' + printStr
    return outStr

@app.callback(Output('intermediate-value', 'children'),
              [Input('interval-component', 'n_intervals')])
def update_global_var(n):
    return compute_expensive_data()

if __name__ == '__main__':
    app.run_server(debug=False)

那么这会在页面重新加载时重新更新全局变量吗?我基本上有一个更新的JSON,我希望dash应用程序在每次重新加载页面时都重新加载最新版本。。。。