Hello,
im using the new Tabulator widget and trying the streaming tutorially from this page https://panel.holoviz.org/reference/widgets/Tabulator.html#streaming and the example works.
But if i start from an initially empty dataframe for the tabulator, like this
different_sized_stream_df = pd.DataFrame(np.random.randn(0, 5), columns=list('ABCDE'))
different_sizedstream_table = pn.widgets.Tabulator(different_sized_stream_df, layout='fit_columns', width=450, height=400)
def different_sized_stream_data(follow=True):
different_sized_stream_df = pd.DataFrame(np.random.randn(10, 5), columns=list('ABCDE'))
different_sizedstream_table.stream(different_sized_stream_df, follow=follow)
pn.state.add_periodic_callback(different_sized_stream_data, period=1000)
pn.Column(
pn.Row(different_sizedstream_table)
).servable()
then no values are shown and i get this error:
2021-04-19 20:31:01,858 Exception in callback <bound method PeriodicCallback._periodic_callback of PeriodicCallback(callback=<function different_sized_stream_data at 0x0000018F0516F8B8>, count=None, name='PeriodicCallback00101', per
iod=1000, running=True, timeout=None)>
Traceback (most recent call last):
File "PATH\.venv\lib\site-packages\tornado\ioloop.py", line 905, in _run
return self.callback()
File "PATH\.venv\lib\site-packages\panel\io\callbacks.py", line 70, in _periodic_callback
self.callback()
File "PATH\panel_dev.py", line 21, in different_sized_stream_data
different_sizedstream_table.stream(different_sized_stream_df, follow=follow)
File "PATH\.venv\lib\site-packages\panel\widgets\tables.py", line 851, in stream
super().stream(stream_value, rollover, reset_index)
File "PATH\.venv\lib\site-packages\panel\widgets\tables.py", line 394, in stream
self.param.trigger('value')
File "PATH\.venv\lib\site-packages\param\parameterized.py", line 1541, in trigger
self_.set_param(**dict(params, **triggers))
File "PATH\.venv\lib\site-packages\param\parameterized.py", line 1472, in set_param
self_._batch_call_watchers()
File "PATH\.venv\lib\site-packages\param\parameterized.py", line 1611, in _batch_call_watchers
self_._execute_watcher(watcher, events)
File "PATH\.venv\lib\site-packages\param\parameterized.py", line 1573, in _execute_watcher
watcher.fn(*args, **kwargs)
File "PATH\.venv\lib\site-packages\panel\widgets\tables.py", line 748, in _validate
self.style = self.value.style
File "PATH\.venv\lib\site-packages\pandas\core\frame.py", line 901, in style
return Styler(self)
File "PATH\.venv\lib\site-packages\pandas\io\formats\style.py", line 156, in __init__
raise ValueError("style is not supported for non-unique indices.")
ValueError: style is not supported for non-unique indices.
Not sure what that means though, no styling is used and the index is unique too for the updating dataframe.
EDIT 1:
The culprit seems to be this line at https://github.com/holoviz/panel/blob/44be3cfbc069ee2579b780aadc1f4076a70473f7/panel/widgets/tables.py#L382
value_index_start = self.value.index.max() + 1
self.value.index.max() gives np.nan for an empty index, therefore all resulting index values will be np.nan.
and consequently non-unique when the styling is set here https://github.com/holoviz/panel/blob/44be3cfbc069ee2579b780aadc1f4076a70473f7/panel/widgets/tables.py#L742.
def _validate(self, event):
super()._validate(event)
if self.value is not None:
todo = []
if self.style is not None:
todo = self.style._todo
self.style = self.value.style
self.style._todo = todo
A kinda hacky workaround is settin an index on the empty initial dataframe like this
pd.DataFrame([], columns=list('ABCDE'), index=[0,1,2])
then the updating works, but it shows the fake index rows as all nan-cells which looks ugly.
Best option would be to probably safeguard the starting index with something like this i guess:
if self.value.index.max() is np.nan: # or self.value.size
value_index_start = 1
else:
value_index_start = self.value.index.max() + 1
EDIT 2:
i have submitted an issue here https://github.com/holoviz/panel/issues/2217