Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Cannot display table with html.Table()

I followed the code in User Guide about hidden Div.
The 2 dropdowns using the shared data work perfectly, but the table isn’t displayed and it shows an error “TypeError: Object of type ‘DataFrame’ is not JSON serializable”.

I tried using dcc.Graph for id=‘data-df’, return plotly.figure_factory.create_table(df) for the table, and also generate_table(df) but neither of them displays the table.

Here is my code:

app = dash.Dash()

app.layout = html.Div([
    html.Div(id='data-df', style={'display': 'none'}),
    html.Div(
        dcc.Input(id='event-url', value='', type='text')
    ),
    html.Br(),
     
    html.Div([
        dcc.Dropdown(
            id='types-menu'
        )], style={'width': '40%', 'display': 'inline-block'}
    ),
    html.Div([
        dcc.Dropdown(
        id='names-menu'
        )], style={'width': '40%', 'display': 'inline-block'}
    ),    
    
    html.Hr(),
    html.Table(
        id='data-table')

    ]

@app.callback(
    dash.dependencies.Output('data-df', 'children'),
    [dash.dependencies.Input('event-url', 'value')]
)
def update_dataframe(url):
    df = pd.read_csv("report.csv", sep="\t", encoding="utf-8")
    
    return df.to_json()

@app.callback(
    dash.dependencies.Output('types-menu', 'options'),
    [dash.dependencies.Input('data-df', 'children')]
)
def update_types_menu(df):
    df = pd.read_json(df, orient='split')
    col = df['Types']
    
    col = col.as_matrix()
    
    return [{'label': i, 'value': i} for i in col]

@app.callback(
    dash.dependencies.Output('names-menu', 'options'),
    [dash.dependencies.Input('data-df', 'children')]
)
def update_names_menu(df):
    df = pd.read_json(df, orient='split')

    col = df['Names']
    
    col = col.drop_duplicates().as_matrix()

    return [{'label': i, 'value': i} for i in col]

@app.callback(
    dash.dependencies.Output('data-table', 'children'),
    [dash.dependencies.Input('data-df', 'children')]
)
def gen_data_table(df):
    
    df = pd.read_json(df, orient='split')
    
    return df

Since the data is going up to the browser, it needs to be converted from a Python object to a something that can be serialized as a JSON string. Some of these conversions are done automatically (e.g. numpy arrays are converted to lists) but others, like a full DataFrame, is not.

The children property of the html.Table component does not take a dataframe as an input argument. You can try for yourself with:

html.Table(df)

Instead, you need to convert the dataframe to a set of valid HTML components yourself. See the example of “Reusable components” in the user guide: https://plot.ly/dash/getting-started-part-1. Then, you can update your function to look like:

@app.callback(
    dash.dependencies.Output('data-table', 'children'),
    [dash.dependencies.Input('data-df', 'children')]
)
def gen_data_table(df):

    df = pd.read_json(df, orient='split')

    return generate_table(df)

I see. Thank you for your response.

I have reordered my table for the dash_table_experiments and it is working perfectly :slight_smile: