Altair: Multiple Charts in one HTML

Created on 9 Apr 2019  路  2Comments  路  Source: altair-viz/altair

Is there a way to display multiple charts on the same webpage using Altair? I am currently saving the files individually using chart.to_html("filename.html), but can't figure out a way to show the 5 different visuals into one html page.

Please let me know if there's a way to do that.

question

Most helpful comment

A more complete answer, for people finding this via Google:

If you want to combine multiple charts into a single chart, you can use concatenation:

import altair as alt
import pandas as pd
chart1 = alt.Chart(df).mark_point().encode(x='x', y='y')
chart2 = alt.Chart(df).mark_line().encode(x='x', y='y')

(chart1 | chart2).save('charts.html')

If for some reason you'd like the charts to be rendered separately and the two renderings embedded into a single HTML page, this is possible, but Altair has no built-in functionality for that.

The best approach would be to construct an HTML template using vega-embed directly, and insert the output of chart.to_json() in the correct place in the template.

Here is a simple example, from which you can use standard HTML/CSS approaches to customize the layout if you wish:

import altair as alt
import pandas as pd

two_charts_template = """
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vega@{vega_version}"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-lite@{vegalite_version}"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@{vegaembed_version}"></script>
</head>
<body>

<div id="vis1"></div>
<div id="vis2"></div>

<script type="text/javascript">
  vegaEmbed('#vis1', {spec1}).catch(console.error);
  vegaEmbed('#vis2', {spec2}).catch(console.error);
</script>
</body>
</html>
"""


df = pd.DataFrame({'x': range(5), 'y': range(5)})

chart1 = alt.Chart(df).mark_point().encode(x='x', y='y')
chart2 = alt.Chart(df).mark_line().encode(x='x', y='y')

with open('charts.html', 'w') as f:
    f.write(two_charts_template.format(
        vega_version=alt.VEGA_VERSION,
        vegalite_version=alt.VEGALITE_VERSION,
        vegaembed_version=alt.VEGAEMBED_VERSION,
        spec1=chart1.to_json(indent=None),
        spec2=chart2.to_json(indent=None),
    ))

All 2 comments

Yes, you can export charts as JSON, and use vega-embed to embed as many of them as you'd like into a single page.

Altair's chart.save('filename.html') just provides a convenience wrapper around this for one chart.

You can see a simple example HTML template here: https://altair-viz.github.io/user_guide/saving_charts.html#html-format

A more complete answer, for people finding this via Google:

If you want to combine multiple charts into a single chart, you can use concatenation:

import altair as alt
import pandas as pd
chart1 = alt.Chart(df).mark_point().encode(x='x', y='y')
chart2 = alt.Chart(df).mark_line().encode(x='x', y='y')

(chart1 | chart2).save('charts.html')

If for some reason you'd like the charts to be rendered separately and the two renderings embedded into a single HTML page, this is possible, but Altair has no built-in functionality for that.

The best approach would be to construct an HTML template using vega-embed directly, and insert the output of chart.to_json() in the correct place in the template.

Here is a simple example, from which you can use standard HTML/CSS approaches to customize the layout if you wish:

import altair as alt
import pandas as pd

two_charts_template = """
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vega@{vega_version}"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-lite@{vegalite_version}"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@{vegaembed_version}"></script>
</head>
<body>

<div id="vis1"></div>
<div id="vis2"></div>

<script type="text/javascript">
  vegaEmbed('#vis1', {spec1}).catch(console.error);
  vegaEmbed('#vis2', {spec2}).catch(console.error);
</script>
</body>
</html>
"""


df = pd.DataFrame({'x': range(5), 'y': range(5)})

chart1 = alt.Chart(df).mark_point().encode(x='x', y='y')
chart2 = alt.Chart(df).mark_line().encode(x='x', y='y')

with open('charts.html', 'w') as f:
    f.write(two_charts_template.format(
        vega_version=alt.VEGA_VERSION,
        vegalite_version=alt.VEGALITE_VERSION,
        vegaembed_version=alt.VEGAEMBED_VERSION,
        spec1=chart1.to_json(indent=None),
        spec2=chart2.to_json(indent=None),
    ))
Was this page helpful?
0 / 5 - 0 ratings

Related issues

breadbaron picture breadbaron  路  4Comments

HalukaMB picture HalukaMB  路  3Comments

Juan-132 picture Juan-132  路  3Comments

LukeMathWalker picture LukeMathWalker  路  3Comments

tonylee3399 picture tonylee3399  路  3Comments