panel icon indicating copy to clipboard operation
panel copied to clipboard

Improve uniformity in case of multiindex column for Tabulator

Open etihwo opened this issue 7 months ago • 0 comments

When multiindex column are used for Tabulator there are some inconsistencies in the configuration and in the events.

Minimal Reproductible Example

Details

from bokeh.models.widgets.tables import NumberFormatter

import numpy as np
import pandas as pd
import panel as pn

pn.extension("tabulator")


# no multiindex
df_simple = pd.DataFrame(np.random.randn(4, 4), columns=["A", "B", "C", "D"])
table_simple = pn.widgets.Tabulator(
    df_simple,
    show_index=False,
    titles={"A": "Title A"},
    header_tooltips={"A": "Tooltip for column A"},
    formatters={"A": NumberFormatter(format="0.00")},
)


# sinple index, multiple columns
level_1 = ["A", "A", "A", "B", "B", "B"]
level_2 = ["one", "one", "two", "two", "three", "three"]
level_3 = ["X", "Y", "X", "Y", "X", "Y"]

multi_index = pd.MultiIndex.from_arrays(
    [level_1, level_2, level_3],
    names=["Level 1", "Level 2", "Level 3"],
)
df_multiple = pd.DataFrame(np.random.randn(4, 6), columns=multi_index)
table_multiple = pn.widgets.Tabulator(
    df_multiple,
    show_index=True,
    formatters={("A", "one", "Y"): NumberFormatter(format="0.00")},
    header_tooltips={"A_one_Y": "Concatenated tooltip"},
    titles={
        ("A", "one", "X"): "Tuple title",  # Not supported
        "A_one_Y": "Concatenated title",  # Not supported
    },
)


table_simple.on_click(print)
table_multiple.on_click(print)
table_simple.on_edit(print)
table_multiple.on_edit(print)

pn.Column(table_simple, table_multiple).servable()

Image

Events

When simple dataframe are used the value in the CellClickEvent or in TableEditEvent corresponds to the name of the column in the dataframe. But for multiindex column dataframe, the name of the column is not the tuple of the column.

# When clicked on the table_simple
CellClickEvent(column=A, row=1, value=-0.18331825421012962)
# When clicked on the table_multiple
CellClickEvent(column=A_one_Y, row=1, value=-0.30569064050133327)

The proposition is to have the following behaviour in the second case

CellClickEvent(column=('A', 'one', 'Y'), row=1, value=-0.30569064050133327)

Proposed code is ce0b04cf70411bcf214d9879072a1a207a3bdf33

Configuration of column

In case of multiindex column, depending of the configurated parameter it might be necessary to use the tuple or the concat form of the column name. Refer to the following part of the code in the MRE.

    formatters={("A", "one", "Y"): NumberFormatter(format="0.00")},
    header_tooltips={"A_one_Y": "Concatenated tooltip"},

The proposition is to uniform by considering the tuple format. The previous code will become:

    formatters={("A", "one", "Y"): NumberFormatter(format="0.00")},
    header_tooltips={("A", "one", "Y"): "Concatenated tooltip"},

Column title

Actually, there is no way to change the title of the column in case of multiindex column. For example, in the code above, the following lines have no effect:

    titles={
        ("A", "one", "X"): "Tuple title",  # Not supported
        "A_one_Y": "Concatenated title",  # Not supported
    },

The proposition is to consider the tuple format and to implement partial tuple to allow to change the name of intermediate level:

    titles={
        ("A", ): "For the top level", 
        ("A", "one"): "For the next level", 
        ("A", "one", "X"): "Tuple title", 
    },

Proposed code is 76c7137c9df1d4810872f2defda4520244c0a3eb

etihwo avatar May 17 '25 07:05 etihwo