posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
41 stars 2 forks source link

Marker popups do no show for ipyleaflet maps #101

Open SamEdwardes opened 1 year ago

SamEdwardes commented 1 year ago

Description

When I include a marker.popup the marker does not show up.

ipyleaflet==0.17.3
ipywidgets==8.0.6
shiny==0.4.0
shinyswatch==0.2.4
shinywidgets==0.2.1

What I Did

With a popup, the marker not render:

import ipyleaflet as L
from ipywidgets import HTML
from shiny import App, reactive, render, ui
from shinywidgets import output_widget, reactive_read, register_widget

app_ui = ui.page_fluid(
    output_widget("map"),
)

def server(input, output, session):
    # Initialize and display when the session starts (1)
    map = L.Map(center=(51.476852, -0.000500), zoom=12, scroll_wheel_zoom=True)

    # Add a marker with a popup
    marker = L.Marker(location=(51.476852, -0.000500), draggable=False)

    # Add a popup
    msg = HTML()
    msg.value = "Hello <b>World</b>"
    msg.placeholder = "Some HTML"
    msg.description = "Some HTML"
    marker.popup = msg

    # Add the layer
    map.add_layer(marker)

    # Register map
    register_widget("map", map)

app = App(app_ui, server)

Screenshot 2023-06-26 at 15 59 01@2x


With no popup, the map renders as expected:

import ipyleaflet as L
from ipywidgets import HTML
from shiny import App, reactive, render, ui
from shinywidgets import output_widget, reactive_read, register_widget

app_ui = ui.page_fluid(
    output_widget("map"),
)

def server(input, output, session):
    # Initialize and display when the session starts (1)
    map = L.Map(center=(51.476852, -0.000500), zoom=12, scroll_wheel_zoom=True)

    # Add a marker with a popup
    marker = L.Marker(location=(51.476852, -0.000500), draggable=False)

    # Add the layer
    map.add_layer(marker)

    # Register map
    register_widget("map", map)

app = App(app_ui, server)

Screenshot 2023-06-26 at 15 59 28@2x

Other info

cpsievert commented 1 year ago

I'm able to run the popup example successfully with ipywidgets 7.6.5 and ipyleaflet 0.17.3. It looks as though something with ipywidgets >8 broke popups -- https://github.com/jupyter-widgets/ipyleaflet/issues/1081

Anyway, it'd also be interesting to know if, with this same environment, whether popups work for you in a Jupyter notebook

SamEdwardes commented 1 year ago

I am able to render it successfully in JupyterLab:

import ipyleaflet as L
from ipywidgets import HTML

map = L.Map(center=(51.476852, -0.000500), zoom=12, scroll_wheel_zoom=True)

# Add a marker with a popup
marker = L.Marker(location=(51.476852, -0.000500), draggable=False)

# Add a popup
msg = HTML()
msg.value = "Hello <b>World</b>"
msg.placeholder = "Some HTML"
msg.description = "Some HTML"
marker.popup = msg

# Add the layer
map.add_layer(marker)

map
Screenshot 2023-06-27 at 13 41 51@2x

I am using:

ipyleaflet==0.17.3
ipywidgets==8.0.6
jupyter-events==0.6.3
jupyter-lsp==2.2.0
jupyter_client==8.0.2
jupyter_core==5.2.0
jupyter_server==2.5.0
jupyter_server_terminals==0.4.4
jupyterlab==4.0.2
jupyterlab-pygments==0.2.2
jupyterlab-widgets==3.0.7
jupyterlab_server==2.23.0
SamEdwardes commented 1 year ago

I was able to get my shiny for python app working with the following requirements:

shiny==0.4.0
ipywidgets==7.7.5
shinywidgets==0.2.1
ipyleaflet==0.17.3
shinyswatch==0.2.4
pins==0.8.1
pandas==1.5.3
pyarrow==12.0.1
rich==13.4.2

I am assuming that something broke in ipywidgets >= 8.0.0

filipwastberg commented 8 months ago

The strange thing for me is that it works in jupyter/quarto, but not in Shiny. However, downgrading to a ipywidgets version < 8 solved it for me as well.

gadenbuie commented 1 month ago

I can confirm that popups no longer work with shinywidgets and ipywidgets>=8.0.0. If I use map.add(popup) to directly add the popup to the map, I get the following client-side error:

Class HTMLStyleModel not found in module @jupyter-widgets/controls@2.0.0

I'm pretty sure that we need to update the version of @jupyter-widgets/html-manager that we use in shinywidgets https://github.com/posit-dev/py-shinywidgets/blob/d4e0f7c3066356bfd51e0174f67bb20b51ecbb57/js/package.json#L18 but this will require code changes in shinywidgets.

For now, I can get away with settings ipywidgets<8.0.0 in my requirements.txt, but this doesn't work on shinylive.

from shiny.express import input, render, ui
from shinywidgets import render_widget
from ipyleaflet import Map, Marker, Popup
from ipywidgets import HTML

@render_widget
def map():
    map = Map(center=(50.6252978589571, 0.34580993652344), zoom=3)
    popup = Popup(child=HTML(value="hello"))
    point = Marker(location=(52.204793, 0.121558), draggable=False)
    map.add(point)
    map.add(popup)

    return map
gadenbuie commented 1 month ago

@cpsievert Here's an ipynb version of the above example where popups work as expected: https://gist.github.com/gadenbuie/621159ebb65c6bede63a66132a38b88e with

ipykernel==6.29.4
ipyleaflet==0.19.1
ipython==8.24.0
    # via
    #   ipykernel
    #   ipywidgets
ipywidgets==8.1.2
    # via ipyleaflet