Search code examples
pythonplotly-dash

Styling a datatable in a function and returning to layout


I have multiple dataframes that I want to display on my dash app. They all undergo similar formatting so I want to do the dashtable formatting within a separate function to which I input the dataframe to be styled. I have tried below but I get "Error Loading layout" on my dash server

import dash
from dash import html, dash_table
import pandas as pd

def styletable(dataframe):
    # Create a copy of the original DataFrame to avoid modifying it directly
    styled_df = dataframe.copy()

    COLNAMES = styled_df.columns
    indexName = styled_df.reindex().columns[0]

    # Convert the styled DataFrame to a Dash DataTable
    styled_table = dash_table.DataTable(
        columns=[{'name': indexName, 'id': indexName}] + [{'name': col, 'id': col, 'type': 'numeric'} for col in COLNAMES],
        data=styled_df,
        style_data_conditional=[
            {
                'if': {'column_id': col, 'filter_query': f'{{col}} < 0'},
                'color': 'red'
            }
            for col in styled_df.columns
        ],
        style_header={'fontWeight': 'bold'}
    )
    print(styled_table)
    return styled_table


app = dash.Dash()

df = pd.DataFrame({
    'Name': ['John Doe', 'Jane Doe', 'Mary Smith', 'Peter Jones'],
    'Age': [30, 25, 40, 35],
    'Salary': [50000, 40000, 60000, 55000]
})

styled_table = styletable(df)

app.layout = html.Div([styled_table])

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

Solution

  • your Dataframe must be transformed into a dict with to_dict('records')

    def styletable(dataframe):
        # Create a copy of the original DataFrame to avoid modifying it directly
        styled_df = dataframe.copy()
    
        COLNAMES = styled_df.columns
        indexName = styled_df.reindex().columns[0]
    
        # Convert the styled DataFrame to a Dash DataTable
        styled_table = dash_table.DataTable(
            columns=[{'name': indexName, 'id': indexName}] + [{'name': col, 'id': col, 'type': 'numeric'} for col in COLNAMES],
            data=styled_df.to_dict('records'),
            style_data_conditional=[
                {
                    'if': {'column_id': col, 'filter_query': f'{{col}} < 0'},
                    'color': 'red'
                }
                for col in styled_df.columns
            ],
            style_header={'fontWeight': 'bold'}
        )
        print(styled_table)
        return styled_table