Trazar gráficos en vivo usando Python Dash y Plotly

Dash es un marco de Python construido sobre ReactJS, Plotly y Flask. Se utiliza para crear paneles web interactivos usando solo python. Los gráficos en vivo son particularmente necesarios para ciertas aplicaciones, como pruebas médicas, datos de stock o, básicamente, para cualquier tipo de datos que cambien en un período de tiempo muy corto donde no es viable recargar cada vez que se actualizan los datos. Esto se puede hacer usando una función llamada «recarga en caliente», que no debe confundirse con «recarga en vivo». La recarga en vivo recarga o actualiza toda la aplicación cuando se actualizan los datos, mientras que la recarga en caliente solo actualiza los datos que se actualizaron sin cambiar el estado de la aplicación. Dash incluye automáticamente la recarga en caliente, lo que la convierte en la mejor opción para este tipo de visualización. 

Ahora, construyamos un tablero que genere datos aleatorios, los agregue a un búfer a intervalos regulares y los visualice. 

Instale el módulo Dash y los módulos Plotly. 

pip install dash
pip install plotly

Primero, importemos todos los módulos y dependencias requeridos. Importar salida y entrada para devoluciones de llamadas, dash_core_components para gráficos y otros componentes básicos ofrecidos por Dash. Importar dash_html_components ofrece componentes HTML básicos. Además, importe dash y plotly . Importe graph_objs desde plotly para características de gráficos. Importe deque (cola de doble terminación) de las colecciones .

import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import random
import plotly.graph_objs as go
from collections import deque

Inicialicemos dos deques para los componentes X e Y del gráfico. Agregue datos únicos a él, estos serán nuestros primeros puntos en el gráfico. 

X = deque(maxlen = 20)
X.append(1)

Y = deque(maxlen = 20)
Y.append(1)

Inicializa la aplicación de tablero.

app = dash.Dash(__name__)

Ahora especifiquemos el diseño del tablero que queremos construir. Es importante tener en cuenta que no hay necesidad de escribir páginas HTML para el diseño y podemos usar los componentes HTML de dash para hacer diseños simples. Construyamos un diseño simple con solo un componente gráfico. En el código a continuación, configuremos animate en True, esto manejará fácilmente las animaciones de desplazamiento para el gráfico que se vería mejor que un cambio abrupto en los valores después de la actualización. Asignemos una identificación al componente del gráfico. Tenemos otro componente llamado Interval , que tiene propiedades como id que especifica una ID única para este componente. El intervalo de propiedad especifica el tiempo transcurrido entre dos actualizaciones de datos. n_intervalose refiere al número de intervalos completados desde el inicio del servidor.

app.layout = html.Div(
    [    
        dcc.Graph(id = 'live-graph',
                  animate = True),
        dcc.Interval(
            id = 'graph-update',
            interval = 1000,
            n_intervals = 0
        ),
    ]
)

Ahora llamemos a los decoradores de devolución de llamada.

@app.callback(
    Output('live-graph', 'figure'),
    [ Input('graph-update', 'n_intervals') ]
)

Ahora hagamos el método update_graph que toma n_intervals como parámetro. Actualicemos los valores de X secuencialmente, es decir, de 1 a 2 a 3 y así sucesivamente. Actualicemos los valores de Y a valores aleatorios. Ahora hagamos una nueva variable de datos y asignémosla a un gráfico plotly. Los gráficos de Plotly, de forma predeterminada, requieren que establezca los valores X e Y con una lista. Especifiquemos el modo en «líneas + marcadores» , lo que esencialmente significa que Plotly trazará los marcadores primero y luego dibujará líneas.

def update_graph_scatter(n):
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1] * random.uniform(-0.1,0.1))

    data = plotly.graph_objs.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines+markers'
    )

    return {'data': [data],
            'layout' : go.Layout(xaxis=dict(
                    range=[min(X),max(X)]),yaxis = 
                    dict(range = [min(Y),max(Y)]),
                    )}

Finalmente, ejecute el servidor.

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

Código completo:

Python3

import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import random
import plotly.graph_objs as go
from collections import deque
  
X = deque(maxlen = 20)
X.append(1)
  
Y = deque(maxlen = 20)
Y.append(1)
  
app = dash.Dash(__name__)
  
app.layout = html.Div(
    [
        dcc.Graph(id = 'live-graph', animate = True),
        dcc.Interval(
            id = 'graph-update',
            interval = 1000,
            n_intervals = 0
        ),
    ]
)
  
@app.callback(
    Output('live-graph', 'figure'),
    [ Input('graph-update', 'n_intervals') ]
)
  
def update_graph_scatter(n):
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1] * random.uniform(-0.1,0.1))
  
    data = plotly.graph_objs.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines+markers'
    )
  
    return {'data': [data],
            'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),yaxis = dict(range = [min(Y),max(Y)]),)}
  
if __name__ == '__main__':
    app.run_server()

Abra el navegador y ejecute la aplicación en el host local y el puerto 8050

http://localhost:8050/

Producción:

Así es como se puede usar dash para visualizaciones de gráficos en vivo. En este artículo, lo hemos usado con valores aleatorios generados por la computadora. Sin embargo, se puede hacer lo mismo con los datos extraídos de las API o una base de datos. 

Publicación traducida automáticamente

Artículo escrito por rahulhegde97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *