geemap
geemap copied to clipboard
Fix issues hindering use of geemap with Panel
I would like to enable people to use geemap in their data apps via Panel. Panel supports ipywidgets in general via ipywidgets_bokeh. See https://panel.holoviz.org/reference/panes/IPyWidget.html#panes-gallery-ipywidget.
I can see geemap is built upon ipywidgets, so I was hoping it would work out of the box. But when I run a minimal example I get errors in the browser console and in the terminal.
I've seen this with other ipywidgets. Sometimes the issue has been on ipywidgets_bokeh side, sometimes on the ipywidget side. So I'm positing here because I don't know where the issue is.
Reproducible example
pip install geemap==0.13.10 ipywidgets_bokeh==1.2.1 panel==0.13.1
Then panel serve script.py --autoreload --show where script.py contains
import geemap
map = geemap.Map(center=[40,-100], zoom=4)
import panel as pn
pn.extension("ipywidgets", template="fast")
pn.state.template.param.update(
site="Awesome Panel", title="Panel + Geemap - Google Earth Engine Data Apps"
)
pn.panel(map).servable()
Then I see the errors
ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Error: Could not create a view for model id b97b1de12b934e639c9b914f53f0985f
at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2087124
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.catch (async)
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.then (async)
e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
t.create_child_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
add_control_model @ Map.js:194
e.update @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
(anonymous) @ Map.js:233
Promise.then (async)
render_leaflet @ Map.js:231
Promise.then (async)
render @ Map.js:227
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.then (async)
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.then (async)
e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
e.display_model @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
await in render (async)
_render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
build @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
renderTo @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
f @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
await in f (async)
t.add_document_standalone @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
await in t.add_document_standalone (async)
t.add_document_from_session @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:586
await in t.add_document_from_session (async)
w @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
t.embed_items @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
await in t.embed_items (async)
embed_document @ script?theme=dark:286
(anonymous) @ script?theme=dark:289
(anonymous) @ script?theme=dark:305
o.safely @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:595
fn @ script?theme=dark:281
ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Error: Could not create child view
at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2087124
at async Promise.all (:5006/index 0)
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.catch (async)
t.create_child_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
add_control_model @ Map.js:194
e.update @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
(anonymous) @ Map.js:233
Promise.then (async)
render_leaflet @ Map.js:231
Promise.then (async)
render @ Map.js:227
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.then (async)
(anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Promise.then (async)
e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
e.display_model @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
await in render (async)
_render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
render @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
build @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
renderTo @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
f @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
await in f (async)
t.add_document_standalone @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
await in t.add_document_standalone (async)
t.add_document_from_session @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:586
await in t.add_document_from_session (async)
w @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
t.embed_items @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
await in t.embed_items (async)
embed_document @ script?theme=dark:286
(anonymous) @ script?theme=dark:289
(anonymous) @ script?theme=dark:305
o.safely @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:595
fn @ script?theme=dark:281
ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'indexOf')
at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2459037
at gg.Bl [as loader] (ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2459166)
at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2741052
at new Promise (<anonymous>)
at gg.loadClass (ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2740898)
at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2091629

and in the terminal
$ panel serve 'script.py' --autoreload --show
2022-06-12 11:07:23,557 Starting Bokeh server version 2.4.3 (running on Tornado 6.1)
2022-06-12 11:07:23,559 User authentication hooks NOT provided (default user enabled)
2022-06-12 11:07:23,560 Bokeh app running at: http://localhost:5006/script
2022-06-12 11:07:23,561 Starting Bokeh server with process id: 32072
2022-06-12 11:07:27,280 WebSocket connection opened
2022-06-12 11:07:27,281 ServerConnection created
2022-06-12 11:07:27,305 WebSocket connection opened
2022-06-12 11:07:27,306 ServerConnection created
2022-06-12 11:07:28,329 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
2022-06-12 11:07:28,591 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
2022-06-12 11:07:28,597 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
2022-06-12 11:07:29,826 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
2022-06-12 11:07:29,926 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
2022-06-12 11:07:29,931 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
This is likely an ipyleaflet issue rather than geemap. Try out the ipyleaflet DrawControl example below. If you encounter the same issue, then it should be reported to ipyleaflet. Otherwise, I will look into what packages other than ipyleaflet might have caused the issue.
https://ipyleaflet.readthedocs.io/en/latest/controls/draw_control.html
Thanks so much. I don't know how to debug these kind of issues. So any help is appreciated.
The ipyleaflet DrawControl does not raise any errors in the console or terminal

from ipyleaflet import Map, basemaps, basemap_to_tiles, DrawControl
watercolor = basemap_to_tiles(basemaps.Stamen.Watercolor)
m = Map(layers=(watercolor, ), center=(50, 354), zoom=5)
draw_control = DrawControl()
draw_control.polyline = {
"shapeOptions": {
"color": "#6bc2e5",
"weight": 8,
"opacity": 1.0
}
}
draw_control.polygon = {
"shapeOptions": {
"fillColor": "#6be5c3",
"color": "#6be5c3",
"fillOpacity": 1.0
},
"drawError": {
"color": "#dd253b",
"message": "Oups!"
},
"allowIntersection": False
}
draw_control.circle = {
"shapeOptions": {
"fillColor": "#efed69",
"color": "#efed69",
"fillOpacity": 1.0
}
}
draw_control.rectangle = {
"shapeOptions": {
"fillColor": "#fca45d",
"color": "#fca45d",
"fillOpacity": 1.0
}
}
m.add_control(draw_control)
import panel as pn
pn.extension('ipywidgets', template="fast")
pn.panel(m).servable()
This might be an ipywidgets issue. Some of the ipy packages used by geemap include ipyleaflet, ipywidgets, ipytree, ipyevents. I am not sure which one causes the issue. Check out the similar issues below.
- https://github.com/jupyter-widgets/pythreejs/issues/206
- https://stackoverflow.com/questions/56477875/child-widget-creation-in-ipywidgets-produces-an-error-using-viewlist-and-create
@MarcSkovMadsen Have you resolved this issue? Can you try out the latest geemap version to see if the issue still exists? Feel reopen the issue if needed.