Python Plotly Dash实时流媒体

时间:2018-10-07 10:02:41

标签: python plotly plotly-dash

我是Dash的新手。但是我真的很喜欢它的工作方式。

我正在尝试为股票实施某种实时流代码,该代码通过从外部字典变量中读取图表来绘制图表。 我确定我会不断获取数据。但是,此实时流只能在15分钟内完美运行,然后停止工作。我必须重启不感兴趣的应用程序。 请指导我解决这个问题。

此外,如果我在流式传输期间进行缩放,则会由于间隔时间而重置我的缩放比例。我该如何解决?

这是我的代码:

# Import statements
# Importing external python script which is useful in handling the stock data
from StockData import StockData
# dash is an open source graph and dashboard building framework using PlotLy and Flask
import dash
# dcc contains the core graph components
import dash_core_components as dcc
# for javascript and css especially for html components such as id and div
import dash_html_components as html
# for live events
from dash.dependencies import Event
# working with data-frames and datetime series
import pandas as pd


class ChartPlot:
"""
Everything related to plotting chart should be inside this class
Once I initiate the class from the Main.py file, it should start plotting
StockData.data_dictionary has the data
"""

    def __init__(self, title="STOCK CHARTS"):
        """
        Initialising the dash app
        :param title: title of the graph
        """

        # Name of the app - stock-tickers
        app = dash.Dash('stock-tickers')

        # TITLE OF THE APP - THAT WILL BE REFLECTED ON THE TAB
        app.title = title

        external_css = ["https://fonts.googleapis.com/css?family=Product+Sans:400,400i,700,700i",
                    "https://cdn.rawgit.com/plotly/dash-app-stylesheets/2cc54b8c03f4126569a3440aae611bbef1d7a5dd/stylesheet.css"]

        for css in external_css:
            app.css.append_css({"external_url": css,
                            'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False})


    def plot_live(self, stock_symbols=StockData.symbol_list, hostname='127.0.0.1', port=5000):
        app = self.app

        # LAYOUT OF OUR APPLICATION
        app.layout = html.Div([

            # THE FIRST LINE DESIGN
            html.Div([

                html.H2('STOCK CHARTS',
                    # styling can be customised here for title
                    style={'display': 'inline',
                           'float': 'left',
                           'font-size': '2.65em',
                           'margin-left': '7px',
                           'font-weight': 'bolder',
                           'font-family': 'Product Sans',
                           'color': "rgba(117, 117, 117, 0.95)",
                           'margin-top': '20px',
                           'margin-bottom': '0'
                           })
        ]),

            # DROP DOWN FROM THE AVAILABLE TICKERS
            # we are using the stock_symbols from the stock_symbols StockData.symbol_list
            dcc.Dropdown(
                id='stock-ticker-input',
                options=[{'label': s, 'value': s}
                     for s in stock_symbols],
                # DEFAULT VALUE - CAN BE EMPTY AS WELL
                value=[stock_symbols[0]],
                # INDICATES MULTIPLE SELECTION IS POSSIBLE
                multi=True
            ),
            dcc.Checklist(
                id='check-list-input',
                options=[
                    {'label': 'High', 'value': 'High'},
                    {'label': 'Low', 'value': 'Low'}
                ],
                values=['High', 'Low'],
                labelStyle={'display': 'inline-block'}
            ),
            # WHERE THE GRAPHS ARE APPEARED
            html.Div(id='graphs'),

            # INTERVAL FOR UPDATING
            dcc.Interval(
                id='graph-update',
                # 1000 MILLI-SECONDS
                interval=1 * 1000
            ),
        ], className="container")
        # BOOTSTRAP CONTAINER CLASS

        # CALL BACK FUNCTION DECORATOR - DEFAULT
        @app.callback(
            # WHERE THE OUTPUT IS EXPECTED
            dash.dependencies.Output('graphs', 'children'),
            # WHAT IS THE INPUT FOR THE OUTPUT
            [dash.dependencies.Input('stock-ticker-input', 'value'),
             dash.dependencies.Input('check-list-input', 'values')],
            # ANY SPECIFIC EVENTS - HERE UPDATING BASED ON INTERVAL
            events=[Event('graph-update', 'interval')])
        def update_graph(symbols, checkers):
            """
            This plots the graphs based on the symbol selected
            :param symbols: list of available symbols
            :return: graphs with high and low values
            """
            # Total graphs
            graphs = list()
            # where all the data is present
            data = list()
            # running through the selected tickers
            for i, symbol in enumerate(symbols):
                # StockData has data_dictionary with symbols as keys containing time stamp, high and low data for particular key
                data_dictionary = StockData.data_dictionary[symbol]
                # Extracting data out of selected data frame
                if len(checkers) == 2:

                    graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['High'],
                               'type': 'line', 'name': str(symbol) + " High"},
                              {'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['Low'],
                               'type': 'line', 'name': str(symbol) + ' Low'}]

                elif 'High' in checkers:
                    graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
                               'y': data_dictionary['High'],
                               'type': 'line', 'name': str(symbol) + " High"}]
                elif 'Low' in checkers:
                    graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
                               'y': data_dictionary['Low'],
                               'type': 'line', 'name': str(symbol) + ' Low'}]
                else:
                    graph_data = None
                # adding to total data
                data.extend(graph_data)

            # DRAWING THE GRAPH
            graphs = [dcc.Graph(
                figure={
                    'data': data,
                    'layout': {"hovermode": "closest", "spikesnap": "cursor",
                   "xaxis": {"showspikes": True, "spikemode": "across"},
                   "yaxis": {"showspikes": True, "spikemode": "across"}}
                },

                config={'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False}
        )]

            return graphs

        app.run_server(debug=True, host=hostname, port=port)

请告诉我是否在任何地方做错了

1 个答案:

答案 0 :(得分:0)

基于Dash documentation snippet

events=[Event('graph-update', 'interval')])

应为:

events=[Event('graph-update', 'n_intervals')])

这似乎是实时流式传输短代码中的常见问题,希望这会有所帮助!