geemap icon indicating copy to clipboard operation
geemap copied to clipboard

Fix issues hindering use of geemap with Panel

Open MarcSkovMadsen opened this issue 3 years ago • 4 comments
trafficstars

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

image

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

MarcSkovMadsen avatar Jun 12 '22 09:06 MarcSkovMadsen

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

giswqs avatar Jun 12 '22 12:06 giswqs

Thanks so much. I don't know how to debug these kind of issues. So any help is appreciated.

MarcSkovMadsen avatar Jun 12 '22 14:06 MarcSkovMadsen

The ipyleaflet DrawControl does not raise any errors in the console or terminal

image



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()

MarcSkovMadsen avatar Jun 12 '22 19:06 MarcSkovMadsen

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

giswqs avatar Jun 12 '22 21:06 giswqs

@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.

giswqs avatar Jun 23 '23 01:06 giswqs