Possible to combine DataTables using pagination?

Hi all, just started working with Dash and Plotly and loving it so far, so decided to join the community!

I am working on building an app for my research team that will aid some of my colleagues create “better” and more consistent plots for their presentations in a simple way. The hope is to utilize dcc.Upload to allow users to upload any number of CSV or Excel files that have common sets of data (e.g., stress-strain curves with one file/dataset per curve). From there, I would like to use DataTables to display each of the datasets for quick viewing purposes prior to setting up some dropdowns or such to pick x- and y-data to be plotted from the uploaded data.

That brings me to my question. Is it possible to combine multiple DataTables together with pagination such that each table is not displayed simultaneously? Since I am allowing an arbitrary number of files to be uploaded, there could potentially be many more tables than I’d like to display on a page at once.

I tried simply passing a list of dictionaries to the DataTable component, but that didn’t work. Passing a list of DataTables provided the undesired output: two DataTables stacked on top of each other on the page. See basic example of the two approaches I tried below:

from dash import Dash, html, dcc, dash_table
import dash_bootstrap_components as dbc
import pandas as pd

app = Dash(__name__)

# Sample dataframes. There would be any number of these types of similar datasets uploaded by the user.
df_1 = pd.DataFrame({"stress": [0, 1, 2, 3], "strain": [0.0, 0.1, 0.2, 0.3]})
df_2 = pd.DataFrame({"stress": [0, 1.5, 2.5, 3.5], "strain": [0.0, 0.11, 0.21, 0.31]})

## Approach 1
# Attempting to pass a list of dictionaries to the DataTable, but an error is displayed on the page.
tables = dash_table.DataTable(data=[df.to_dict("records") for df in [df_1, df_2]])

## Approach 2
# Attempting to create a list of DataTables, but this just stacks the two tables one after the other.
tables = [
    dash_table.DataTable(
        data=df.to_dict("records"),
    )
    for df in [df_1, df_2]
]

app.layout = dbc.Container([dbc.Row([dbc.Col(tables)])])

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

If what I’m trying to do isn’t possible, does anyone have a recommendation of an alternative that achieves something nice and clean like my original intent?

Thank you!

Hello @mnolaya,

Thank you for being part of the community!

Are the tables going to be in the same format, or are they different columns? If they arent the same columns, the it is a little difficult to work with it.

However, what you could do is give the user the ability to tab through the different tables using something like dbc tabs. It would feel more like excel sheets. :slight_smile:

Hey @jinnyzor ! Thanks for the welcome.

To answer your initial question – yes, the format of the tables (in terms of columns) will be exactly the same. There is the chance that one table has more data points (row-wise) than the other, but in general they should be very much consistent in their formatting. I could include a check in the uploaded files to ensure that’s the case.

Your other option sounds really cool though. I took a quick peek at the dcb.Tab docs and it looks like there’s something I can work with. Since we’re already having a dialogue, I might as well ask… Is it possible to dynamically introduce X number of tabs depending on X number of uploaded files? But yeah, in essence, a pseudo-Excel sheet is kinda what I’d like to provide the user uploading their data.

Yes, it is possible to add x number of tabs, you’d create your tabs and datatable’s based upon user upload and then send the whole children to a target tabs which houses it.

Something like this:

app.layout = html.Div([
dcc.Upload(id='uploading'),
dbc.Tabs(
 id='myTabs'
)]

@app.callback(
Output('myTabs','children'),
Input('uploading', 'contents'),
State('myTabs','children')
)
def addTable(c, tabs):
     tabContent, fileName = parsecontents(c)
     tabs.append(dbc.Tab(tabContent, label=fileName))
     return tabs

If you want to create functionality that is similar based upon the tabs, you might think about introducing pattern-matching callbacks, but for now, I’d focus on getting the tables and tabs to work.

Also, if you get to uploading a bunch of files and the tabs grows very large, you might consider a dropdown to select the file they want to look at.