Animated charts and story telling with IpyVizzu

vizzuhq/ipyvizzu: ipyvizzu is the Jupyter Notebook integration of Vizzu. (github.com). You can use it to create animated stories.

It can of course be used with Panel. You will need to transform the Ipyvizzu Chart to something that can be rendered. For example like

def to_ipyvizzue_pane(chart: Chart, **params) -> pn.pane.HTML:
    """Returns a HTML pane containing the Ipyvizzu animation

    You can provide all the usual parameters like `height`, `width` and `sizing_mode`
    to control the layout of the `HTML` pane.
    """
    id = "ipyvizzu-" + uuid4().hex.upper()
    code = "\n".join(chart._calls)
    template = f"""
<div id="{id}" style="height:100%;width:100%"></div>
<script type="text/javascript">
element = document.getElementById('{id}')
{code}
</script>
"""
    return pn.pane.HTML(template, **params)

Here we show the Titanic example.

from uuid import uuid4

import pandas as pd
import panel as pn
from ipyvizzu import Chart, Config, Data
from ipyvizzu.template import DisplayTarget

pn.extension(sizing_mode="stretch_width", template="fast")

DATA_PATH = "titanic.csv"
DATA_URL = "https://raw.githubusercontent.com/vizzuhq/ipyvizzu/main/docs/examples/stories/titanic/titanic.csv"


def load_data() -> Data:
    """Returns an IpyVizzu Data set

    Here you can return whatever data you want.
    """
    try:
        data_frame = pd.read_csv(DATA_PATH)
    except FileNotFoundError:
        data_frame = pd.read_csv(DATA_URL)
        data_frame.to_csv(DATA_PATH, index=False)

    data = Data()
    data.add_data_frame(data_frame)
    return data


def get_chart() -> Chart:
    """Returns your chart

    Here you can implement whatever animation you want
    """
    # We need DisplayTarget.MANUAL to control the display for Panel
    # We set height and width to 100% to let Panel control the heigh and width
    chart = Chart(width="100%", height="100%", display=DisplayTarget.MANUAL)

    chart.animate(DATA)

    chart.animate(
        Config({"x": "Count", "y": "Sex", "label": "Count", "title": "Passengers of the Titanic"})
    )
    chart.animate(
        Config({"x": ["Count", "Survived"], "label": ["Count", "Survived"], "color": "Survived"})
    )
    chart.animate(Config({"x": "Count", "y": ["Sex", "Survived"]}))
    return chart


def to_ipyvizzue_pane(chart: Chart, **params) -> pn.pane.HTML:
    """Returns a HTML pane containing the Ipyvizzu animation

    You can provide all the usual parameters like `height`, `width` and `sizing_mode`
    to control the layout of the `HTML` pane.
    """
    id = "ipyvizzu-" + uuid4().hex.upper()
    code = "\n".join(chart._calls)
    template = f"""
<div id="{id}" style="height:100%;width:100%"></div>
<script type="text/javascript">
element = document.getElementById('{id}')
{code}
</script>
"""
    return pn.pane.HTML(template, **params)


DATA = load_data()
CHART = get_chart()

pn.pane.Markdown(
    """
# Panel works with the tools you know and love. This includes IpyVizzu.
"""
).servable() # .servable() adds teh pane to the app

to_ipyvizzue_pane(CHART, height=500, sizing_mode="stretch_both").servable()

pn.state.template.param.update(
    site="Awesome Panel",
    title="Animations with IpyVizzu",
)

# Serve the app with `panel serve name_of_script.py`.

To run the example you will need to

pip install panel ipyvizzu pandas

You can run the script with panel serve name_of_script.py. Add --autoreload during development.

5 Likes

There is now a Vizzu pane which should be used. See Vizzu