Skip to content

Commit

Permalink
Update as_widget() to use the new altair.JupyterChart (#113)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpsievert authored Nov 7, 2023
1 parent f3200e9 commit 45441ae
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 39 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to shinywidgets will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [UNRELEASED]

* `as_widget()` uses the new `altair.JupyterChart()` to coerce `altair.Chart()` into a `ipywidgets.widgets.Widget` instance. (#120)

## [0.2.2] - 2023-10-31

* `@render_widget` now builds on `shiny`'s `render.transformer` infrastructure, and as a result, it works more seamlessly in `shiny.express` mode. (#110)
Expand Down
35 changes: 8 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ See the [using ipywidgets section](https://shiny.rstudio.com/py/docs/ipywidgets.

### What ipywidgets are supported?

In theory, shinywidgets supports any instance that inherits from `{ipywidgets}`' `Widget` class.
In theory, shinywidgets supports any instance that inherits from `{ipywidgets}`' `Widget` class. That is, if `isinstance(obj, ipywidgets.widgets.Widget)` returns `True` for some object `obj`, then `{shinywidgets}` should be able to render it.

That said, `{shinywidgets}` can also "directly" render objects that don't inherit from `Widget`, but have a known way of coercing into a `Widget` instance. This list currently includes:
`{shinywidgets}` can also render objects that don't inherit from `Widget`, but have a known way of coercing into a `Widget` instance. This list currently includes:

* Altair charts (via the [vega](https://pypi.org/project/vega/) package).
* Bokeh widgets (via the [jupyter_bokeh](https://github.com/bokeh/jupyter_bokeh) package).
* Plotly's `Figure` class (via `FigureWidget`).
* Altair charts (i.e., `altair.Chart()` instances).
* Plotly figures (i.e., `plotly.go.Figure()`)
* Pydeck's `Deck` class (via it's `.show()` method).
* Bokeh widgets (via the [jupyter_bokeh](https://github.com/bokeh/jupyter_bokeh) package).
* Bokeh widgets are a bit of a special case, as they require some extra setup to work in Shiny. See the [Bokeh widgets aren't displaying, what gives?](#bokeh-widgets-arent-displaying-what-gives) section below for more details.

[See here](https://github.com/rstudio/py-shinywidgets/blob/main/shinywidgets/_as_widget.py) for more details on how these objects are coerced into `Widget` instances, and if you know of other packages that should be added to this list, please [let us know](https://github.com/rstudio/py-shinywidgets/issues/new)
[See here](https://github.com/rstudio/py-shinywidgets/blob/main/shinywidgets/_as_widget.py) for more details on how these objects are coerced into `Widget` instances, and if you know of other packages that should be added to this list, please [let us know](https://github.com/rstudio/py-shinywidgets/issues/new).

### Bokeh widgets aren't displaying, what gives?
### Bokeh setup

Similar to how you have to run `bokeh.io.output_notebook()` to run `{bokeh}` in notebook, you also have to explicitly bring the JS/CSS dependencies to the Shiny app, which can be done this way:

Expand Down Expand Up @@ -94,26 +95,6 @@ that widget requires initialization code in a notebook environment. In this case
`{shinywidgets}` probably won't work without providing the equivalent setup information to
Shiny. Some known cases of this are:

#### bokeh

To use `{bokeh}` in notebook, you have to run `bokeh.io.output_notebook()`. The
equivalent thing in Shiny is to include the following in the UI definition:

```py
from shiny import ui
from shinywidgets import bokeh_dependencies

app_ui = ui.page_fluid(
bokeh_dependencies(),
# ...
)
```


#### Other widgets?

Know of another widget that requires initialization code? [Please let us know about
it](https://github.com/rstudio/py-shinywidgets/issues/new)!

## Development

Expand Down
10 changes: 8 additions & 2 deletions shinywidgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

__author__ = """Carson Sievert"""
__email__ = "[email protected]"
__version__ = "0.2.2"
__version__ = "0.2.2.9000"

from ._dependencies import bokeh_dependency
from ._shinywidgets import output_widget, reactive_read, register_widget, render_widget, as_widget
from ._shinywidgets import (
as_widget,
output_widget,
reactive_read,
register_widget,
render_widget,
)

__all__ = ("output_widget", "register_widget", "render_widget", "reactive_read", "bokeh_dependency", "as_widget")
14 changes: 4 additions & 10 deletions shinywidgets/_as_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,13 @@ def as_widget(x: object) -> Widget:

def as_widget_altair(x: object) -> Optional[Widget]:
try:
from vega.widget import VegaWidget
from altair import JupyterChart
except ImportError:
raise ImportError("Install the vega package to use altair with shinywidgets.")

if not hasattr(x, "to_dict"):
raise TypeError(
f"Don't know how to coerce {x} (an altair object) into an ipywidget without a .to_dict() method."
raise RuntimeError(
"Failed to import altair.JupyterChart (do you need to pip install -U altair?)"
)

try:
return VegaWidget(x.to_dict()) # type: ignore
except Exception as e:
raise RuntimeError(f"Failed to coerce {x} into a VegaWidget: {e}")
return JupyterChart(x) # type: ignore


def as_widget_bokeh(x: object) -> Optional[Widget]:
Expand Down

0 comments on commit 45441ae

Please sign in to comment.