Visualization

Embedding Altair charts in the web app

Concepts

Altair in a server context

Embedding Vega-Lite in a page

A scatter plot of diameter vs. mutation

A bar chart of counts by site

Exporting charts

Check for Understanding

Why does Altair not produce an image file directly, and what does the browser use to render the chart?

Altair produces a Vega-Lite JSON specification—a description of the chart's data, marks, and encodings. Rendering pixels from that specification requires the Vega-Lite runtime, which runs as JavaScript in the browser. The Vega-Embed library loads the spec, runs the renderer, and inserts an SVG or Canvas element into the page. This separation means the chart can be interactive (zoom, pan, tooltip) without any additional server code.

If you change the data in the database and reload the page, what needs to happen for the chart to update?

The page must make a new request to the chart data route, which queries the database and returns an updated Vega-Lite specification. If the chart spec is loaded once on page load and cached in the browser, it will not update automatically. Using HTMX to fetch the spec on demand (e.g., when the user clicks a "Refresh" button or when the page loads) ensures the chart always reflects the current data.

What does an Altair color encoding do, and how would you use it to distinguish mutated from non-mutated snails?

The color encoding maps a data field to the hue of each mark. To distinguish mutated from non-mutated snails: color=alt.Color("mutated:N") where :N indicates a nominal (categorical) field. Altair will automatically assign different colors to True and False values and add a legend. You can customize the color scheme with alt.Scale(range=["steelblue", "orange"]).

What is Vega-Embed, and where in the HTML must the script tag loading it appear?

Vega-Embed is a JavaScript library that takes a Vega-Lite JSON specification and a DOM element, renders the chart, and adds interactive features (tooltips, zoom, export button). The script tag must appear before any JavaScript that calls vegaEmbed(); placing it in the <head> or at the end of <body> both work, but the call to vegaEmbed() must run after both the script and the mount-point <div> exist in the DOM.

Exercises

Add a histogram

Ask the LLM to add a histogram of shell diameters to the visualization page. Before accepting the output, decide: how many bins make sense for the range of values in the data? Does the LLM choose a reasonable bin width? If not, adjust the specification and verify the result looks sensible.

Add rich tooltips

Modify the scatter plot so that hovering over a point shows the site name, survey date, diameter, and mutation status in the tooltip. Implement the Altair encoding yourself first using the Altair documentation, then compare with what the LLM produces.

Compare chart types

Display the count of measurements per site as both a bar chart and a dot plot. Ask the LLM which encoding is more effective for this data and why. Evaluate the reasoning: does it match what you would conclude from looking at both charts?

Test the chart route

Write a pytest test that calls the chart data route and checks that the response body is valid JSON with at least a mark key and a data key (the minimum required by Vega-Lite). Do not test the exact values—just that the structure is present and the status code is 200.