I am trying to use a tabulator to select rows of a DataFrame that have start and stop times. When I select a row of the tabulator I would like the DatatimeRangeSlider to be updated with data from the DataFrame. The app renders fine but if I click on any row other than the first row I get a TypeError for trying to set a read only value. The callback I’m binding to completes fine, the error is thrown deeper in the Panel code.
Can anyone see what I am doing wrong?
import datetime as dt
import numpy as np
import pandas as pd
import panel as pn
import datetime as dt
from tail_recursive import tail_recursive
np.random.seed(7)
# pn.extension('tabulator')
@tail_recursive
def make_dates(start, n_ranges, i=0, acc=[]):
"""Makes a list of tuples of (int, datetime, datetime) objects."""
if i == n_ranges:
return acc
delta = dt.timedelta(minutes=5)
acc += [(i + 1000, start, start + delta)]
return make_dates(start + delta, n_ranges, i+1, acc)
def row_range(row, index):
"""Returns the previous row and subsequent row of a DataFrame. Performs boundary
checking for when row is the first or last value of the index and returns current
the current row in those cases."""
idx_min, idx_max = index[0], index[-1]
return (
row - 1 if row > idx_min else row,
row + 1 if row < idx_max else row,
)
df = pd.DataFrame.from_records(
make_dates(dt.datetime(2023, 1, 1), 10),
columns=['pass_id', 'start', 'stop'],
)
editors = {column: None for column in df.columns}
df_widget = pn.widgets.Tabulator(df, editors=editors, selection=[0])
def update_slider(selection):
"""Create a new slider based on the current selected row of the df_widget tabulator
with the appropriate values. """
print(selection)
row = selection[0]
start_row, stop_row = row_range(row, df.index)
slider = pn.widgets.DatetimeRangeSlider(
name="slider",
start=df.at[start_row, 'start'],
end=df.at[stop_row, 'stop'],
step=1000,
value=(df.at[row, 'start'], df.at[row, 'stop']),
)
print("Callback complete")
return slider
app = pn.Column(df_widget, pn.bind(update_slider, df_widget.param.selection))
app.servable()
TypeError received.
[5]
Callback complete
2023-07-17 09:37:36,654 Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x119dfe140>>, <Task finished name='Task-106' coro=<ServerSession.with_document_locked() done, defined at /Users/scott/panel/.venv/lib/python3.10/site-packages/bokeh/server/session.py:77> exception=TypeError("Read-only parameter 'value_end' cannot be modified")>)
Traceback (most recent call last):
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/tornado/ioloop.py", line 738, in _run_callback
ret = callback()
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/tornado/ioloop.py", line 762, in _discard_future_result
future.result()
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/bokeh/server/session.py", line 98, in _needs_document_lock_wrapper
result = await result
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/reactive.py", line 429, in _change_coroutine
state._handle_exception(e)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/io/state.py", line 436, in _handle_exception
raise exception
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/reactive.py", line 427, in _change_coroutine
self._change_event(doc)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/reactive.py", line 445, in _change_event
self._process_events(events)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/reactive.py", line 1441, in _process_events
self._update_selection(events.pop('indices'))
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/widgets/tables.py", line 1532, in _update_selection
self.selection = indices
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 367, in _f
instance_param.__set__(obj, val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 369, in _f
return f(self, obj, val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 1252, in __set__
obj.param._call_watcher(watcher, event)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 2043, in _call_watcher
self_._execute_watcher(watcher, (event,))
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 2025, in _execute_watcher
watcher.fn(*args, **kwargs)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/param.py", line 869, in _replace_pane
self._update_inner(new_object)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/pane/base.py", line 704, in _update_inner
new_pane, internal = self._update_from_object(
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/pane/base.py", line 680, in _update_from_object
cls._recursive_update(old_object, object)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/panel/pane/base.py", line 649, in _recursive_update
old.param.update(**new_params)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 1895, in update
setattr(self_or_cls, k, v)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 367, in _f
instance_param.__set__(obj, val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 369, in _f
return f(self, obj, val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/__init__.py", line 625, in __set__
super(Dynamic,self).__set__(obj,val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 369, in _f
return f(self, obj, val)
File "/Users/scott/panel/.venv/lib/python3.10/site-packages/param/parameterized.py", line 1207, in __set__
raise TypeError("Read-only parameter '%s' cannot be modified" % self.name)
TypeError: Read-only parameter 'value_end' cannot be modified