Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple column levels #509

Merged
merged 10 commits into from
Jan 26, 2021

Conversation

shwinnn
Copy link
Collaborator

@shwinnn shwinnn commented Jan 13, 2021

Renders pandas MultiLevel column titles in the Table component when generated from a DataFrame.

As asked for in #507

@shwinnn shwinnn requested a review from tcbegley January 13, 2021 15:50
Copy link
Collaborator

@tcbegley tcbegley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if the higher levels weren't repeated, see attached screenshot. You can achieve this using colSpan in the html.Th elements.

I had a quick look just now but I didn't see any obvious ways of extracting the span, so you might have to figure it out yourself from df.columns.to_list() or similar. I guess it would look something like at each level you count the number of repeated indexes, taking into account when there's a change either in the current level or the level above.

image

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 14, 2021

Sorted. This will also work for column titles even in a DataFrame without multiple title 'levels' if they are repeated and adjacent. I think that's a good thing but could add logic to untangle that case if you disagree.

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 15, 2021

Oh hang on - I didn't consider the case where the level above changes but the below level is the same. I'll think about that.

@tcbegley
Copy link
Collaborator

Yeah, that seems to be the one outstanding thing. I've checked that if a key appears multiple times non-contiguously then it's alright.

import dash
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd

header = [
    [
        "location",
        "location",
        "location",
        "location",
        "location2",
        "location2",
        "location2",
        "location3",
        "location3",
        "location",
        "location",
    ],
    ["S1", "S2", "S3", "S3", "S1", "S2", "S3", "S3", "S3", "S1", "S2"],
]
df = pd.DataFrame(np.random.randint(0, 10, size=(10, 11)), columns=header)


app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = dbc.Container(dbc.Table.from_dataframe(df), className="p-5",)

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

One thing I did notice running this example is a lot of indexing past lexsort depth may impact performance warnings in the terminal. This can be resolved by sorting the column multiindex, but perhaps users want a particular ordering of columns which would be broken by doing this automatically

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 20, 2021

I definitely don't want to reorder the rows automatically. What do you think about just suppressing the warning (or allowing just the first instance through?)

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 20, 2021

Oh never mind! It can be avoided by just using .iloc[i,j] rather than .loc[i][col]

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 20, 2021

So that turned out to be far from trivial to do without having abominable for loops everywhere. I tested using the same file above, but changing the second "S1" to "S3". This should force a break even though both columns in that level have the title "S3" because the level above changes from "location" to "location2" at that point.

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 20, 2021

So it appears itertools.accumulate doesn't exist in Python 2.7. I will switch to using numpy.cumsum.

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 20, 2021

Okay, I've just written my own accumulator instead.

Copy link
Collaborator

@tcbegley tcbegley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it took me a while to look at this, looks good to me, thanks for the contribution!

Looks like there's a few conflicts with master. Could you merge in the changes or rebase onto master? Once you've done that I'll squash and merge.

@shwinnn
Copy link
Collaborator Author

shwinnn commented Jan 26, 2021

I didn't get any conflicts, but I've merged the changes (which seem to consist only of the colours PR I made last week).

@tcbegley
Copy link
Collaborator

Ah yeah, there might not have been conflicts in the sense of merge conflicts, but GitHub is very conservative about letting you merge changes if there are any newer commits on the target branch. Something like it will only do a fast-forward merge, not a three-way merge? Anyway, thanks for updating!

@tcbegley tcbegley merged commit a021585 into facultyai:master Jan 26, 2021
This was referenced Feb 5, 2021
@shwinnn shwinnn deleted the feature/multi-index-tables branch February 18, 2021 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants