Skip to content

Commit

Permalink
v2: Add VegaFusionWidget based on AnyWidget (#514)
Browse files Browse the repository at this point in the history
* Add VegaFusionWidget based on AnyWidget

* remove comment

* add vegafusion_widget test

* Rename test file

* fix ignore path for rename
  • Loading branch information
jonmmease authored Oct 8, 2024
1 parent 65022d3 commit 4d17974
Show file tree
Hide file tree
Showing 4 changed files with 544 additions and 25 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ jobs:
- name: Test vegafusion
working-directory: vegafusion-python/
run: pytest --ignore=tests/test_altair_mocks.py
run: pytest --ignore=tests/test_jupyter_widget.py

test-vegafusion-python-win-64:
runs-on: windows-2022
Expand Down Expand Up @@ -351,7 +351,7 @@ jobs:
python -m pip install pytest altair vega-datasets scikit-image
- name: Test vegafusion
working-directory: vegafusion-python/
run: pytest --ignore=tests/test_altair_mocks.py
run: pytest --ignore=tests/test_jupyter_widget.py


build-vegafusion-server-linux-64:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,105 @@ def test_altair_mock(mock_name, img_tolerance, delay):
altair_default_notebook = jupytext.read(io.StringIO(altair_default_markdown), fmt="markdown")
vegafusion_jupyter_notebook = jupytext.read(io.StringIO(vegafusion_jupyter_markdown), fmt="markdown")

voila_proc, chrome_driver = launch_voila()

try:
name = mock_name.replace("/", "-")
altair_imgs = export_image_sequence(
chrome_driver, altair_default_notebook, name + "_altair", actions, delay
)
vegafusion_mime_imgs = export_image_sequence(
chrome_driver, vegafusion_jupyter_notebook, name + "_vegafusion_mime", actions, delay
)

compare_images(altair_imgs, vegafusion_mime_imgs, img_tolerance * 0.99)

finally:
voila_proc.kill()
chrome_driver.close()
time.sleep(0.25)


def test_vegafusion_widget():

altair_chart_str = """
from vegafusion.jupyter import VegaFusionWidget
import altair as alt
from vega_datasets import data
source = data.seattle_weather.url
brush = alt.selection_interval(encodings=['x'])
bars = alt.Chart().mark_bar().encode(
x='month(date):O',
y='mean(precipitation):Q',
opacity=alt.condition(brush, alt.OpacityValue(1), alt.OpacityValue(0.7)),
).add_params(
brush
)
line = alt.Chart().mark_rule(color='firebrick').encode(
y='mean(precipitation):Q',
size=alt.SizeValue(3)
).transform_filter(
brush
)
chart = alt.layer(bars, line, data=source)
"""

# Convert to Vega spec and use VegaFusionWidget
notebook_text_vf = r"""
```python
{altair_chart_str}
vega_spec_inline = chart.to_dict(format="vega")
vega_spec_inline["data"][1]["url"] = "vegafusion+dataset://weather"
widget = VegaFusionWidget(
spec=vega_spec_inline,
inline_datasets={"weather": data.seattle_weather()}
)
widget
```
""".replace("{altair_chart_str}", altair_chart_str)

notebook_vf = jupytext.read(io.StringIO(notebook_text_vf), fmt="markdown")

# Display with default altair renderer
notebook_text_alt = f"""
```python
{altair_chart_str}
chart
```
"""
notebook_alt = jupytext.read(io.StringIO(notebook_text_alt), fmt="markdown")

# Define actions to perform a selection
actions = [
{"type": "snapshot"},
{"type": "move_to", "coords": [150, 150]},
{"type": "click_and_hold"},
{"type": "move_to", "coords": [200, 200]},
{"type": "release"},
{"type": "snapshot"}
]

voila_proc, chrome_driver = launch_voila()

try:
imgs_alt = export_image_sequence(chrome_driver, notebook_alt, "vegafusion_widget_alt", actions=actions, delay=0.25)
imgs_vf = export_image_sequence(chrome_driver, notebook_vf, "vegafusion_widget_vf", actions=actions, delay=0.25)

compare_images(imgs_alt, imgs_vf, 0.99)
finally:
voila_proc.kill()
chrome_driver.close()
time.sleep(0.25)

def launch_voila():
# Create selenium Chrome instance
chrome_opts = webdriver.ChromeOptions()

Expand All @@ -274,33 +373,17 @@ def test_altair_mock(mock_name, img_tolerance, delay):
# Sleep to allow Voila itself to start (this does not include loading a particular dashboard).
time.sleep(1.0)

try:
name = mock_name.replace("/", "-")
altair_imgs = export_image_sequence(
chrome_driver, altair_default_notebook, name + "_altair", actions, delay
)
vegafusion_mime_imgs = export_image_sequence(
chrome_driver, vegafusion_jupyter_notebook, name + "_vegafusion_mime", actions, delay
)

for i in range(len(altair_imgs)):
altair_img = altair_imgs[i]
vegafusion_mime_img = vegafusion_mime_imgs[i]
return voila_proc, chrome_driver

assert altair_img.shape == vegafusion_mime_img.shape, "Size mismatch with mime renderer"
def compare_images(baseline_imgs, test_imgs, img_tolerance):

similarity_mime_value = ssim(altair_img, vegafusion_mime_img, channel_axis=2)
print(f"({i}) similarity_mime_value={similarity_mime_value}")
for i, (baseline_img, test_img) in enumerate(zip(baseline_imgs, test_imgs)):
assert baseline_img.shape == test_img.shape, "Size mismatch"

# Allow slightly more image tolerance for mime renderer as floating point differences may
# be introduced by pre-transform process
mime_image_tolerance = img_tolerance * 0.99
assert similarity_mime_value >= mime_image_tolerance, f"Similarity failed with mime renderer on image {i}"
similarity_mime_value = ssim(baseline_img, test_img, channel_axis=2)
print(f"({i}) similarity_mime_value={similarity_mime_value}")

finally:
voila_proc.kill()
chrome_driver.close()
time.sleep(0.25)
assert similarity_mime_value >= img_tolerance, f"Similarity failed with mime renderer on image {i}"


def load_actions(mock_name):
Expand Down
Loading

0 comments on commit 4d17974

Please sign in to comment.