Как обновить сюжетную / тире фигуру из редактируемой таблицы? - PullRequest
1 голос
/ 16 мая 2019

У меня есть объект DataTable, содержащий удаляемые строки и столбцы.Я хотел бы обновить фигуру на основе видимых строк.Я не уверен, как создать обратный вызов и какие аргументы передать.Данные, хранящиеся в объекте таблицы, могут фактически не изменяться при удалении строк в браузере.

from dash_table import DataTable

def lineplot(id, df, cols, title=None, xlabel=None, ylabel=None, x=None, 
             xaxis_type=None, yaxis_type=None, plotly_config=plotly_config,
            ):

    if x is None:
        x_values = df.index
        xlabel = df.index.name
    else:
        x_values = df[x]

    data = [{
        'x': x_values,
        'y': df[col],
        'name': col }  for col in cols]

    layout = go.Layout(
        title=go.layout.Title(
            text=title,
            xref='paper',
            xanchor='center'
        ),
        xaxis = go.layout.XAxis(
            title=go.layout.xaxis.Title(
                text=xlabel,
                font=plotly_config['font'],

            ),
            type=xaxis_type
        ),
        yaxis=go.layout.YAxis(
            title=go.layout.yaxis.Title(
                text=ylabel,
                font=plotly_config['font'],
            ),
        type=yaxis_type
        ),
        showlegend=True
    )


    return dcc.Graph(
        id=id,
        figure={'data': data,
                'layout': layout},
        style={"max-width": "600px", 
               "margin": "auto", 
               "display": "inline-block"})

def table(id, df):
    dt = DataTable(
        id=id,
        data=df.to_dict('records'),
        columns=[{"name": i, 
                  "id": i, 
                  "deletable": True, 
                  "searchable": True} for i in df.columns], 
        sorting=True, 
        style_cell={
            'minWidth': '0px', 
            'maxWidth': '180px',
            'whiteSpace': 'no-wrap',
            'overflow': 'hidden',
            'textOverflow': 'ellipsis'},
        style_table={'overflowX': 'scroll'},
        row_deletable=True,
        pagination_mode="fe",
        pagination_settings={
                "displayed_pages": 1,
                "current_page": 0,
                "page_size": 15},
        navigation="page"
        )
    return dt

app = dash.Dash(__name__)
app.layout = html.Div(children=[
    table(id='table', df=pd.DataFrame(...)),
    lineplot(id='plot',...)
])

@app.callback(Output('plot', 'data'),
              [Input('table', 'data')])
def update_graph(data):
    return pd.DataFrame(data)

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

1 Ответ

0 голосов
/ 17 мая 2019

Я не уверен, как создать обратный вызов и какие аргументы передать.

Необходимые аргументы должны содержать информацию в вашей таблице, чтобы вы могли обновить свой графиксоответственно.Вы можете найти атрибуты, которые можно собрать из компонентов, в онлайн-документации: https://dash.plot.ly/datatable/reference.

Данные, хранящиеся в объекте таблицы, могут фактически не изменяться при удалении строк в браузере.

Я не уверен, понял ли я, что вы имеете в виду под этим.Если вы удалите строки в своей таблице через веб-интерфейс, у вас будет соответствующее изменение в данных, которые передаются в вашу функцию обновления, что позволяет соответствующим образом обновлять график.

Я внес несколько изменений вВаш код, чтобы он выглядел более естественным для меня.В некоторых местах мне приходилось вносить изменения, потому что у меня не было достаточно информации о ваших целях.Ниже вы можете увидеть рабочий пример, который вы должны настроить в соответствии с вашими потребностями.Я создал жестко закодированный тестовый фрейм данных.Вам нужно создать его динамически, если вы хотите загрузить данные во время выполнения.

from dash_table import DataTable
from dash.dependencies import Input, Output
import dash
import dash_html_components as html
import dash_core_components as dcc
import pandas as pd
import plotly.graph_objs as go


raw_data = {
        'column1': [4, 24, 31, 2, 3],
        'column2': [25, 94, 57, 62, 70]
}
test_df = pd.DataFrame(raw_data)


app = dash.Dash(__name__)
app.layout = html.Div(children=[
    DataTable(
        id='table',
        data=test_df.to_dict('records'),
        columns=[{"name": i,
                  "id": i,
                  "deletable": True,
                  "searchable": True} for i in test_df.columns],
        sorting=True,
        style_cell={
            'minWidth': '0px',
            'maxWidth': '180px',
            'whiteSpace': 'no-wrap',
            'overflow': 'hidden',
            'textOverflow': 'ellipsis'},
        style_table={'overflowX': 'scroll'},
        row_deletable=True,
        pagination_mode="fe",
        pagination_settings={
            "displayed_pages": 1,
            "current_page": 0,
            "page_size": 15},
        navigation="page"
    ),
    dcc.Graph(
        id='plot',
        style={"max-width": "600px",
               "margin": "auto",
               "display": "inline-block"})
])


@app.callback(Output('plot', 'figure'),
              [Input('table', 'data'),
               Input('table', 'columns')])
def update_graph(data, cols):
    df = pd.DataFrame(data, columns=[c['name'] for c in cols])
    x_values = df.index

    data = [{
        'x': x_values,
        'y': df[col['name']],
        'name': col['name']} for col in cols]

    layout = go.Layout(
        title=go.layout.Title(
            text='title',
            xref='paper',
            xanchor='center'
        ),
        xaxis=go.layout.XAxis(
            title=go.layout.xaxis.Title(
                text='x-title'
            ),
            type=None
        ),
        yaxis=go.layout.YAxis(
            title=go.layout.yaxis.Title(
                text='y-title'
            ),
            type=None
        ),
        showlegend=True
    )

    return {"data": data, "layout": layout}


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