Tabulator on pandas groupby, describe, stack failing


I have a pandas dataframe in tidy format. Each column is a variable. I would like to show the statistic summary in a table for a selected amount of columns.
This is how I do this:


And the result looks like this in a jupyter notebook (only part of the result is shown):

But when I feed this dataframe into a tabulator widget,


the code executing gives me a value error:

ValueError: failed to validate DataTabulator(id=‘21068’, …).indexes: expected an element of List(String), got seq with invalid items [None]

Am I doing something wrong?

I guess you should convert groupby to pd.Dataframe
Before inserting it in tabulator


That’s also what I tried. But it give the same ValueError.

This is the traceback:

ValueError                                Traceback (most recent call last)
~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\IPython\core\ in __call__(self, obj, include, exclude)
    969             if method is not None:
--> 970                 return method(include=include, exclude=exclude)
    971             return None
    972         else:

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\panel\ in _repr_mimebundle_(self, include, exclude)
    614         doc = _Document()
    615         comm = state._comm_manager.get_server_comm()
--> 616         model = self._render_model(doc, comm)
    617         ref = model.ref['id']
    618         manager = CommManager(, plot_id=ref)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\panel\ in _render_model(self, doc, comm)
    453         if comm is None:
    454             comm = state._comm_manager.get_server_comm()
--> 455         model = self.get_root(doc, comm)
    457         if config.embed:

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\panel\ in get_root(self, doc, comm, preprocess)
    510         """
    511         doc = init_doc(doc)
--> 512         root = self._get_model(doc, comm=comm)
    513         if preprocess:
    514             self._preprocess(root)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\panel\widgets\ in _get_model(self, doc, root, parent, comm)
   1051         if comm:
   1052             with set_resource_mode('inline'):
-> 1053                 model = super()._get_model(doc, root, parent, comm)
   1054         else:
   1055             model = super()._get_model(doc, root, parent, comm)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\panel\widgets\ in _get_model(self, doc, root, parent, comm)
    185         source.selected.indices = self.selection
    186         properties = self._get_properties(source)
--> 187         model = self._widget_type(**properties)
    188         if root is None:
    189             root = model

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\bokeh\model\ in __init__(self, **kwargs)
    126         kwargs.pop("id", None)
--> 128         super().__init__(**kwargs)
    129         default_theme.apply_to_model(self)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\bokeh\core\ in __init__(self, **properties)
    205         for name, value in properties.items():
--> 206             setattr(self, name, value)
    208         self._initialized = True

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\bokeh\core\ in __setattr__(self, name, value)
    228         properties =
    229         if name in properties:
--> 230             return super().__setattr__(name, value)
    232         descriptor = getattr(self.__class__, name, None)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\bokeh\core\property\ in __set__(self, obj, value, setter)
    281             raise RuntimeError(f"{class_name}.{} is a readonly property")
--> 283         value =,, value)
    284         old = self._get(obj)
    285         self._set(obj, old, value, setter=setter)

~\Anaconda3\envs\jupyterlab-debugger\lib\site-packages\bokeh\core\property\ in prepare_value(self, owner, name, value, hint)
    363         else:
    364             obj_repr = owner if isinstance(owner, HasProps) else owner.__name__
--> 365             raise ValueError(f"failed to validate {obj_repr}.{name}: {error}")
    367         if isinstance(owner, HasProps):

ValueError: failed to validate DataTabulator(id='1743', ...).indexes: expected an element of List(String), got seq with invalid items [None]

I think you should flatten you dataframe. Maybe with something like this: df.columns = df.columns.get_level_values(0)

But without a minimal, reproducible example (MRE) it is hard to determine what exactly the problem is.

1 Like

This stack creates a MultiIndex DataFrame with None as name. This can be fixed by setting the name to an empty string:

import numpy as np
import panel as pn
from pandas.util.testing import makeDataFrame

# Create DataFrame
df0 = makeDataFrame()
df0["part"] = np.random.randint(1, 5, df0.shape[0])
df = df0.groupby(by="part").describe().stack()

# The fix
df.index.set_names(["part", ""], inplace=True)

# Tabulator
1 Like

Thanks @Hoxbro