From 5cea47a3dfcadaffab857fe12299a45aa5acce7b Mon Sep 17 00:00:00 2001 From: Simeon Schwarzenberg Date: Fri, 11 Jul 2025 08:53:22 +0200 Subject: [PATCH 1/4] Allow layout callbacks to be installed on a plotly FigureWidget --- shinywidgets/_render_widget_base.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/shinywidgets/_render_widget_base.py b/shinywidgets/_render_widget_base.py index 5e8021a..617de91 100644 --- a/shinywidgets/_render_widget_base.py +++ b/shinywidgets/_render_widget_base.py @@ -174,6 +174,7 @@ def set_layout_defaults(widget: Widget) -> Tuple[Widget, bool]: # Plotly provides it's own layout API (which isn't a subclass of ipywidgets.Layout) if pkg == "plotly": from plotly.graph_objs import Layout as PlotlyLayout # pyright: ignore + from plotly.basewidget import BaseFigureWidget # pyright: ignore if isinstance(layout, PlotlyLayout): if layout.height is not None: @@ -190,7 +191,12 @@ def set_layout_defaults(widget: Widget) -> Tuple[Widget, bool]: if fill: widget._config = {"responsive": True, **widget._config} # type: ignore - widget.layout = layout + if isinstance(widget, BaseFigureWidget): + # Reassigning the layout to a FigureWidget drops installed callbacks; + # use native update_layout instead. + widget.update_layout(layout) # pyright: ignore + else: + widget.layout = layout # altair, confusingly, isn't setup to fill it's Layout() container by default. I # can't imagine a situation where you'd actually want it to _not_ fill the parent From e0a43a55b4e06fab1ae13e2e58327a550e5ec8e4 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 14 Jul 2025 17:10:53 -0500 Subject: [PATCH 2/4] No need to ignore typing --- shinywidgets/_render_widget_base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shinywidgets/_render_widget_base.py b/shinywidgets/_render_widget_base.py index 617de91..8b07005 100644 --- a/shinywidgets/_render_widget_base.py +++ b/shinywidgets/_render_widget_base.py @@ -173,8 +173,8 @@ def set_layout_defaults(widget: Widget) -> Tuple[Widget, bool]: # Plotly provides it's own layout API (which isn't a subclass of ipywidgets.Layout) if pkg == "plotly": - from plotly.graph_objs import Layout as PlotlyLayout # pyright: ignore - from plotly.basewidget import BaseFigureWidget # pyright: ignore + from plotly.graph_objs import Layout as PlotlyLayout + from plotly.basewidget import BaseFigureWidget if isinstance(layout, PlotlyLayout): if layout.height is not None: @@ -194,7 +194,7 @@ def set_layout_defaults(widget: Widget) -> Tuple[Widget, bool]: if isinstance(widget, BaseFigureWidget): # Reassigning the layout to a FigureWidget drops installed callbacks; # use native update_layout instead. - widget.update_layout(layout) # pyright: ignore + widget.update_layout(layout) else: widget.layout = layout From 282f6a53bd3b094a879bb7b2bfbce4e8830f7937 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 14 Jul 2025 17:23:09 -0500 Subject: [PATCH 3/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8e2423..bb35a70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [UNRELEASED] * `datetime.date()` values are properly JSON serialized. (#204) +* Callbacks on a plotly `FigureWidget` are now retained for recent versions of plotly. (#207, thanks @simeonschwarzenberg) ## [0.6.2] - 2025-05-21 From 21ec87fab1478048d5067f1754c452a7194d63ab Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 14 Jul 2025 17:26:05 -0500 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb35a70..27f65c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [UNRELEASED] * `datetime.date()` values are properly JSON serialized. (#204) -* Callbacks on a plotly `FigureWidget` are now retained for recent versions of plotly. (#207, thanks @simeonschwarzenberg) +* Fixed an issue were callbacks on a plotly `FigureWidget` object were getting dropped with recent versions of plotly. (#207, thanks @simeonschwarzenberg) ## [0.6.2] - 2025-05-21