Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Altair charts #7

Open
joelostblom opened this issue Feb 28, 2024 · 4 comments
Open

Support Altair charts #7

joelostblom opened this issue Feb 28, 2024 · 4 comments
Labels
p: low Address issue when time permits t: feature-request

Comments

@joelostblom
Copy link

joelostblom commented Feb 28, 2024

Is your feature request related to a problem? Please describe.

Currently, altair charts renders as text:

image

The output from altair is vega-lite specs that can be rendered as interactive HTML. I tried some of the different renderers here https://altair-viz.github.io/user_guide/display_frontends.html, such as PNG and SVG, but none of them display.

Describe the solution you'd like
Chart objects to render by default as they do in a notebook environment.

Describe alternatives you've considered
Not sure what an alternative solution would be here.

Additional context

Code:

import pyodide_js
await pyodide_js.loadPackage('micropip')
import micropip
await micropip.install('altair')

import altair as alt
import pandas as pd

source = pd.DataFrame({
    'a': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'b': [28, 55, 43, 91, 81, 53, 19, 87, 52]
})

chart = alt.Chart(source).mark_bar().encode(
    x='a',
    y='b'
)

chart

Edit: Modified the MWE to include await before micropip.install().

@coatless
Copy link
Collaborator

It looks like the pyodide package for this is now being built thanks to your work in:

pyodide/pyodide#4580

From there, we'll probably add a detect statement to run the necessary setup Python code to include the graphs similar to matplotlib.

@coatless coatless added p: low Address issue when time permits t: feature-request labels Mar 1, 2024
@psychemedia
Copy link

psychemedia commented Mar 14, 2024

Related to this is a more general issue relating to the rendering of HTML from IPython.__repr__ calls in other packages.

Eg with ipyleaflet we get a similar issue:

import micropip
await micropip.install(["ipyleaflet", "sqlite3"])
from IPython.display import display
from ipyleaflet import Map, Marker, basemaps, basemap_to_tiles
m = Map(
  basemap=basemap_to_tiles(
    basemaps.NASAGIBS.ModisTerraTrueColorCR, "2017-04-08"
  ),
  center=(52.204793, 360.121558),
  zoom=4
)
m.add_layer(Marker(location=(52.204793, 360.121558)))
display(m)

returns text.

Map(center=[52.204793, 360.121558], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_in_title', 'zoom_out_text', 'zoom_out_title']), AttributionControl(options=['position', 'prefix'], position='bottomright')), crs={'name': 'EPSG3857', 'custom': False}, default_style=MapStyle(), dragging_style=MapStyle(cursor='move'), layers=(TileLayer(attribution='Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ([ESDIS](https://earthdata.nasa.gov/)) with funding provided by NASA/HQ.', base=True, max_zoom=9, min_zoom=1, name='NASAGIBS.ModisTerraTrueColorCR', options=['attribution', 'bounds', 'detect_retina', 'max_native_zoom', 'max_zoom', 'min_native_zoom', 'min_zoom', 'no_wrap', 'tile_size', 'tms', 'zoom_offset'], url='https://map1.vis.earthdata.nasa.gov/wmts-webmerc/MODIS_Terra_CorrectedReflectance_TrueColor/default/2017-04-08/GoogleMapsCompatible_Level9/{z}/{y}/{x}.jpg'), Marker(location=[52.204793, 360.121558], options=['alt', 'draggable', 'keyboard', 'rise_offset', 'rise_on_hover', 'rotation_angle', 'rotation_origin', 'title', 'z_index_offset'])), options=['bounce_at_zoom_limits', 'box_zoom', 'center', 'close_popup_on_click', 'double_click_zoom', 'dragging', 'fullscreen', 'inertia', 'inertia_deceleration', 'inertia_max_speed', 'interpolation', 'keyboard', 'keyboard_pan_offset', 'keyboard_zoom_offset', 'max_zoom', 'min_zoom', 'prefer_canvas', 'scroll_wheel_zoom', 'tap', 'tap_tolerance', 'touch_zoom', 'world_copy_jump', 'zoom', 'zoom_animation_threshold', 'zoom_delta', 'zoom_snap'], style=MapStyle(), zoom=4.0)

In an IPython/Jupyter notebook, display() is available without having to explicitly import, so it may be useful to:

  1. support some sort of display() function;
  2. automatically import it.

@joelostblom
Copy link
Author

joelostblom commented Aug 4, 2024

Great point @psychemedia ! It would be very helpful if it was possible to support the same outputs as jupyter environments (such as_repr_html_()) since this would also give nicer output for pandas dataframes etc.

I noticed that it seems like these are already support in some cases, for example for pandas data frames where either _repr_html_() or to_html() gives the following output (which I believe would look like in jupyter if the relevant CSS styles were added):

image

Likewise I can use display_html to display arbitrary HTML code:

image

So if an object has a _repr_html_() method already, it might just be a matter of hooking into that instead of the default __repr__() (maybe a similar solution also exists for tibbles and similar in R?). However, if I try to add an onClick JS event, then nothing happens when I try to click the button (text should be displayed below as in this demo):

image

@coatless Is the reason for altair charts and similar output not displaying this inabiility to execution JS code (which in the case of altair would prevent loading Vega-Lite from the CDNs)? That could be why the png/svg renderers are not working either since they still require to connect to the VegaLite CDNs to create the charts in the first place. Do you have an idea where to get started with working on this? I'm working on a viz textbook for ggplot and altair and would love to use this extension for the interactive coding exercises in both languages.

@joelostblom
Copy link
Author

I should also add that altair has a way of forcing the output to be HTML (instead of automatically converting to textual output in unsupported environments) via to_html(), but it doesn't actually render the chart (which I'm guessing is due to the reason mentioned above):

image

The content of the output div:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p: low Address issue when time permits t: feature-request
Projects
None yet
Development

No branches or pull requests

3 participants