When a Tabulator is backed by a GeoDataFrame, the geometry column's raw shapely objects end up in the widget's ColumnDataSource. On sync/patch to the browser, bokeh raises SerializationError: can't serialize <class 'shapely.geometry.polygon.Polygon'>, which breaks the session.
The initial render can appear fine, but a data update (patching the ColumnDataSource) triggers the failure, so it shows up as a silent stall in a served app.
Reproduce
import geopandas as gpd
import panel as pn
from shapely.geometry import Polygon
from bokeh.document import Document
from bokeh.core.serialization import Serializer
gdf = gpd.GeoDataFrame(
{"v": [1, 2], "geometry": [Polygon([(0, 0), (1, 0), (1, 1)]),
Polygon([(2, 0), (3, 0), (3, 1)])]},
crs="EPSG:4326",
)
w = pn.widgets.Tabulator(gdf)
doc = Document()
w.get_root(doc)
w.value = gdf.copy() # patches the ColumnDataSource
for m in doc.models:
if hasattr(m, "data"):
Serializer().encode(m.data) # SerializationError: can't serialize Polygon
Expected
Tabulator should be able to display a geometry column (for example by serializing it as WKT text), or at minimum document that geometry columns must be stringified before being passed to Tabulator.
Environment
panel 1.8.10a0, bokeh 3.8.2, geopandas 1.1.4, shapely 2.1.2, Python 3.14.3
When a
Tabulatoris backed by aGeoDataFrame, the geometry column's raw shapely objects end up in the widget'sColumnDataSource. On sync/patch to the browser, bokeh raisesSerializationError: can't serialize <class 'shapely.geometry.polygon.Polygon'>, which breaks the session.The initial render can appear fine, but a data update (patching the
ColumnDataSource) triggers the failure, so it shows up as a silent stall in a served app.Reproduce
Expected
Tabulator should be able to display a geometry column (for example by serializing it as WKT text), or at minimum document that geometry columns must be stringified before being passed to Tabulator.
Environment
panel 1.8.10a0, bokeh 3.8.2, geopandas 1.1.4, shapely 2.1.2, Python 3.14.3