Saltar al contenido

¿Cómo usar el tablero en un cuaderno Jupyter o JupyterLab?

Solución:

(Descargo de responsabilidad, ayudo a mantener Dash)

Consulte https://github.com/plotly/jupyterlab-dash. Esta es una extensión de JupyterLab que incorpora Dash dentro de Jupyter.

Aplicación Dash dentro de Jupyter

También vea soluciones alternativas en el Foro de la comunidad de Dash, como el tema ¿Puedo ejecutar la aplicación Dash en jupyter?

Ya existe una gran respuesta a esta pregunta, pero esta contribución se centrará directamente en:

1. Cómo usar Dash dentro de Jupyterlab, y

2. cómo seleccione la entrada gráfica colocando el cursor sobre sobre otro gráfico


Si sigue estos pasos, se lanzará Plotly Dash directamente en JupyterLab:

1. Instale la última versión de Plotly

2. Instale JupyterLab Dash con conda install -c plotly jupyterlab-dash

3. Usando el fragmento proporcionado un poco más abajo, inicie una aplicación Dash que contiene una animación construida en un marco de datos de pandas que se expande cada segundo.

Captura de pantalla de Dash en JupyterLab (código en el fragmento a continuación)

ingrese la descripción de la imagen aquí

Esta imagen muestra Dash literalmente encendido dentro de JupyterLab. Las cuatro secciones resaltadas son:

1 – Celda. Una celda en un .ipynb con el que probablemente ya estés muy familiarizado

2 – Dash. Una aplicación de tablero “en vivo” que expande los tres trazos con un número aleatorio y muestra la figura actualizada cada segundo.

3 – Consola. Una consola donde puede inspeccionar los elementos disponibles en su script usando, por ejemplo, fig.show

4 – mode. Esto muestra dónde reside la verdadera magia:

app.run_server(mode="jupyterlab", port = 8090, dev_tools_ui=True, #debug=True,
              dev_tools_hot_reload =True, threaded=True)

Puede optar por iniciar la aplicación del tablero en:

  1. Jupyterlab, como en la captura de pantalla con mode="jupyterlab",
  2. o en una celda, usando mode="inline":

ingrese la descripción de la imagen aquí

  1. o en su navegador predeterminado usando mode="external"

ingrese la descripción de la imagen aquí

Codigo 1:

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

# code and plot setup
# settings
pd.options.plotting.backend = "plotly"

# sample dataframe of a wide format
np.random.seed(4); cols = list('abc')
X = np.random.randn(50,len(cols))  
df=pd.DataFrame(X, columns=cols)
df.iloc[0]=0;

# plotly figure
fig = df.plot(template="plotly_dark")

app = JupyterDash(__name__)
app.layout = html.Div([
    html.H1("Random datastream"),
            dcc.Interval(
            id='interval-component',
            interval=1*1000, # in milliseconds
            n_intervals=0
        ),
    dcc.Graph(id='graph'),
])

# Define callback to update graph
@app.callback(
    Output('graph', 'figure'),
    [Input('interval-component', "n_intervals")]
)
def streamFig(value):
    
    global df
    
    Y = np.random.randn(1,len(cols))  
    df2 = pd.DataFrame(Y, columns = cols)
    df = df.append(df2, ignore_index=True)#.reset_index()
    df.tail()
    df3=df.copy()
    df3 = df3.cumsum()
    fig = df3.plot(template="plotly_dark")
    #fig.show()
    return(fig)

app.run_server(mode="jupyterlab", port = 8090, dev_tools_ui=True, #debug=True,
              dev_tools_hot_reload =True, threaded=True)

Pero la buena noticia no termina ahí, en cuanto a:

Mi intención es vincular gráficos dentro de un cuaderno de Jupyter para que al pasar el cursor sobre un gráfico se genere la entrada requerida para otro gráfico.

Hay un ejemplo perfecto en dash.plotly.com que hará exactamente eso por ti debajo del párrafo Update Graphs on Hover:

ingrese la descripción de la imagen aquí

Hice los pocos cambios necesarios en la configuración original para que sea posible ejecutarlo en JupyterLab.

Fragmento de código 2: seleccione la fuente del gráfico colocando el cursor sobre:

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash.dependencies

# code and plot setup
# settings
pd.options.plotting.backend = "plotly"


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = JupyterDash(__name__, external_stylesheets=external_stylesheets)

df = pd.read_csv('https://plotly.github.io/datasets/country_indicators.csv')

available_indicators = df['Indicator Name'].unique()

app.layout = html.Div([
    html.Div([

        html.Div([
            dcc.Dropdown(
                id='crossfilter-xaxis-column',
                options=[{'label': i, 'value': i} for i in available_indicators],
                value="Fertility rate, total (births per woman)"
            ),
            dcc.RadioItems(
                id='crossfilter-xaxis-type',
                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
                value="Linear",
                labelStyle={'display': 'inline-block'}
            )
        ],
        style={'width': '49%', 'display': 'inline-block'}),

        html.Div([
            dcc.Dropdown(
                id='crossfilter-yaxis-column',
                options=[{'label': i, 'value': i} for i in available_indicators],
                value="Life expectancy at birth, total (years)"
            ),
            dcc.RadioItems(
                id='crossfilter-yaxis-type',
                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
                value="Linear",
                labelStyle={'display': 'inline-block'}
            )
        ], style={'width': '49%', 'float': 'right', 'display': 'inline-block'})
    ], style={
        'borderBottom': 'thin lightgrey solid',
        'backgroundColor': 'rgb(250, 250, 250)',
        'padding': '10px 5px'
    }),

    html.Div([
        dcc.Graph(
            id='crossfilter-indicator-scatter',
            hoverData={'points': [{'customdata': 'Japan'}]}
        )
    ], style={'width': '49%', 'display': 'inline-block', 'padding': '0 20'}),
    html.Div([
        dcc.Graph(id='x-time-series'),
        dcc.Graph(id='y-time-series'),
    ], style={'display': 'inline-block', 'width': '49%'}),

    html.Div(dcc.Slider(
        id='crossfilter-year--slider',
        min=df['Year'].min(),
        max=df['Year'].max(),
        value=df['Year'].max(),
        marks={str(year): str(year) for year in df['Year'].unique()},
        step=None
    ), style={'width': '49%', 'padding': '0px 20px 20px 20px'})
])


@app.callback(
    dash.dependencies.Output('crossfilter-indicator-scatter', 'figure'),
    [dash.dependencies.Input('crossfilter-xaxis-column', 'value'),
     dash.dependencies.Input('crossfilter-yaxis-column', 'value'),
     dash.dependencies.Input('crossfilter-xaxis-type', 'value'),
     dash.dependencies.Input('crossfilter-yaxis-type', 'value'),
     dash.dependencies.Input('crossfilter-year--slider', 'value')])
def update_graph(xaxis_column_name, yaxis_column_name,
                 xaxis_type, yaxis_type,
                 year_value):
    dff = df[df['Year'] == year_value]

    fig = px.scatter(x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'],
            y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'],
            hover_name=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name']
            )

    fig.update_traces(customdata=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'])

    fig.update_xaxes(title=xaxis_column_name, type="linear" if xaxis_type == 'Linear' else 'log')

    fig.update_yaxes(title=yaxis_column_name, type="linear" if yaxis_type == 'Linear' else 'log')

    fig.update_layout(margin={'l': 40, 'b': 40, 't': 10, 'r': 0}, hovermode="closest")

    return fig


def create_time_series(dff, axis_type, title):

    fig = px.scatter(dff, x='Year', y='Value')

    fig.update_traces(mode="lines+markers")

    fig.update_xaxes(showgrid=False)

    fig.update_yaxes(type="linear" if axis_type == 'Linear' else 'log')

    fig.add_annotation(x=0, y=0.85, xanchor="left", yanchor="bottom",
                       xref="paper", yref="paper", showarrow=False, align='left',
                       bgcolor="rgba(255, 255, 255, 0.5)", text=title)

    fig.update_layout(height=225, margin={'l': 20, 'b': 30, 'r': 10, 't': 10})

    return fig


@app.callback(
    dash.dependencies.Output('x-time-series', 'figure'),
    [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
     dash.dependencies.Input('crossfilter-xaxis-column', 'value'),
     dash.dependencies.Input('crossfilter-xaxis-type', 'value')])
def update_y_timeseries(hoverData, xaxis_column_name, axis_type):
    country_name = hoverData['points'][0]['customdata']
    dff = df[df['Country Name'] == country_name]
    dff = dff[dff['Indicator Name'] == xaxis_column_name]
    title="<b>{}</b><br>{}".format(country_name, xaxis_column_name)
    return create_time_series(dff, axis_type, title)


@app.callback(
    dash.dependencies.Output('y-time-series', 'figure'),
    [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
     dash.dependencies.Input('crossfilter-yaxis-column', 'value'),
     dash.dependencies.Input('crossfilter-yaxis-type', 'value')])
def update_x_timeseries(hoverData, yaxis_column_name, axis_type):
    dff = df[df['Country Name'] == hoverData['points'][0]['customdata']]
    dff = dff[dff['Indicator Name'] == yaxis_column_name]
    return create_time_series(dff, axis_type, yaxis_column_name)


app.run_server(mode="jupyterlab", port = 8090, dev_tools_ui=True, #debug=True,
              dev_tools_hot_reload =True, threaded=True)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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