cd /news/ai-tools/19-extraordinary-charts-made-with-op… · home › topics › ai-tools › article
[ARTICLE · art-161183] src=chris-parmer.com ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

19 extraordinary charts made with Opus 5.5 and Plotly

A blog post demonstrates that Claude Code running Anthropic's Opus 5.5 model generated 19 custom Plotly charts that mimic designer-grade SVG work, including a Voronoi airport map, an Isotype population chart, an xkcd-style line chart, a migration chord diagram and an arc diagram. The author reports that Opus 5.5 wrote circle-packing algorithms, used Plotly's SVG interface and drew cubic Béziers, with arcs approximated because Plotly paths do not accept the SVG arc command. The post argues that world-class data visualization is now available to anyone with access to a coding agent.

read8 min views24 publishedOct 16, 2026
19 extraordinary charts made with Opus 5.5 and Plotly
Image: Chris-Parmer (auto-discovered)

Frontier AI is extraordinary at making charts with Plotly. Plotly has a very flexible graphics engine under the hood. In this post, I asked a coding agent (Claude Code with Opus 5.5) to make graphs that leaned into Plotly's SVG interface and that are more akin to what you might see from graphic designers making things with Illustrator or what you might see in a D3.js gallery. Illustrator, D3, and Plotly use the same technology for graphics - SVG - and so what you can create in one you can create in the other.

Under the hood, Opus wrote circle packing algorithms, leaned into Plotly's SVG interface, and drew many, many cubic beziers. World-class data visualization is now available to anyone with access to a coding agent. We love to see it!

See some more examples in my other post,

[Plotly for Highly Customizable Print-Ready Data Visualization](https://chris-parmer.com/plotly-for-highly-customizable-print-ready-data-visualization/).

Airport Voronoi #

plotly/datasets 2011_february_us_airport_traffic.csv · PublicaMundi us-states.json ·

    [Code](https://chris-parmer.com/python/airport-voronoi/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-01.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-01.png)

There's no map trace here. The airports are projected to Albers x/y in numpy, scipy builds the Voronoi cells, shapely clips them to the US outline, and it all goes on an ordinary x/y plot with scaleanchor locking the aspect to 1:1. Each shade bucket is a single go.Scatter with fill="toself" holding dozens of cell polygons separated by None.

Isotype population #

[Our World in Data, Population (HYDE, Gapminder, UN WPP)](https://ourworldindata.org/grapher/population) ·
    [Code](https://chris-parmer.com/python/isotype/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-02.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-02.png)

Each little person is a hand-drawn polygon written out as an SVG path string and added with fig.add_shape(type="path"). Partial figures are the same polygon clipped in Python before it becomes a path. The axes are hidden and scaleanchor keeps the figures from stretching, so the plot area works like a sheet of paper you draw on in data units.

xkcd style #

[Karl Rupp via Our World in Data](https://ourworldindata.org/grapher/transistors-per-microprocessor) ·
    [Code](https://chris-parmer.com/python/xkcd-style/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-03.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-03.png)

The whole chart sits on hidden axes measured in pixels. Every stroke, the axes and arrows included, is resampled into tiny steps and nudged sideways by a few summed sine waves, then drawn as a plain go.Scatter line. A thicker white line underneath each one makes the halo. The handwriting is just font.family: Kaleido uses whatever fonts are installed on the machine.

Migration chord #

[Abel & Cohen (2019), bilateral international migration flow estimates](https://doi.org/10.6084/m9.figshare.7731233) ·
    [Code](https://chris-parmer.com/python/chord-diagram/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-04.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-04.png)

The ring segments and the ribbons are all layout.shapes with type="path". Plotly paths don't take the SVG arc command, so arcs are approximated with cubic Béziers, and each ribbon goes arc, quadratic curve through the center, arc, quadratic back, the same recipe as d3.ribbon. Region names are placed a letter at a time as annotations with textangle so they follow the circle.

Arc diagram #

[Donald Knuth, The Stanford GraphBase, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/miserables.json) ·
    [Code](https://chris-parmer.com/python/arc-diagram/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-05.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-05.png)

One row of markers, then one type="path" shape per pair of characters: a half circle made of two cubic Béziers, its line width set by how many chapters they share. The names are annotations rotated with textangle=-90, and the dark ground is just paper_bgcolor and plot_bgcolor.

Circle packing #

[Our World in Data, Population 2023 (UN WPP 2024)](https://ourworldindata.org/grapher/population) ·
    [Code](https://chris-parmer.com/python/circle-packing/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-06.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-06.png)

Plotly has no circle-packing trace, so the packing is d3's front-chain algorithm ported to Python. After that every country and continent is a type="circle" shape on 1:1 axes. The continent names around each rim are single letters placed as annotations and turned with textangle.

Streamgraph #

[U.S. Bureau of Labor Statistics, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/unemployment-across-industries.json) ·
    [Code](https://chris-parmer.com/python/streamgraph/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-07.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-07.png)

The wiggle baseline from Byron and Wattenberg's paper is computed in numpy. Each industry becomes one closed polygon (the top edge, then the bottom edge reversed) drawn with go.Scatter(fill="toself"). The recessions are add_vrect, and label sizes are worked out in pixels so each name fits inside its band.

Horizon chart #

[NOAA NCEI, GHCN-Daily and U.S. Climate Normals 1991–2020](https://www.ncei.noaa.gov/access/services/data/v1) ·
    [Code](https://chris-parmer.com/python/horizon-chart/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-08.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-08.png)

Each station's row is folded into four 3 °C bands in Python, with cold days flipped up into the blue hues. Every piece for a given band and hue, across all 28 rows, goes into a single fill="toself" scatter trace separated by None, so the whole chart is only a handful of traces. The key is a row of type="rect" shapes.

Radial dendrogram #

[the Flare class hierarchy, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/flare.json) ·
    [Code](https://chris-parmer.com/python/radial-tree/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-09.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-09.png)

The d3.cluster layout is computed in Python from the id/parent table: leaves spaced evenly around the circle, each parent at the mean angle of its children. Each link is a cubic Bézier in a type="path" shape. The 220 class names are annotations rotated with textangle to point outward, flipped on the left half so none read upside down.

Star chart #

[d3-celestial by Olaf Frohn (Hipparcos stars, IAU constellation figures)](https://github.com/ofrohn/d3-celestial) ·
    [Code](https://chris-parmer.com/python/star-chart/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-10.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-10.png)

This one is a real go.Scattergeo figure, using an azimuthal equidistant projection centered on the pole. Right ascension goes in as longitude, mirrored so you look up at the sky from inside, and declination goes in as latitude. The navy disc and the Milky Way are go.Choropleth polygons given a one-color colorscale; the stars are scattergeo markers sized by magnitude.

Circos genome plot #

UCSC Genome Browser hg38 cytoBand and NCBI RefSeq curated ·

    [Code](https://chris-parmer.com/python/circos/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-11.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-11.png)

Everything on the ring is a fill="toself" scatter polygon: positions are computed in polar coordinates and converted to x/y in numpy. Bands with the same Giemsa stain share one trace, so thousands of bands cost only a few traces. Chromosome and gene labels are annotations turned with textangle to sit along the circle.

Chart of biography #

Encyclopaedia Britannica and ODNB dates, hardcoded ·
    [Code](https://chris-parmer.com/python/chart-of-biography/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-12.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-12.png)

Each life is a short go.Scatter line on a year axis, with dotted ends where a date is uncertain. A greedy packing step in Python finds each person a lane where the name won't collide, and the names are a text trace in EB Garamond italic. The double border and the category rules are shapes.

Parliament chart #

[House of Commons Library, General Election 2024 results](https://commonslibrary.parliament.uk/research-briefings/cbp-10009/) ·
    [Code](https://chris-parmer.com/python/parliament/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-13.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-13.png)

The seat positions are computed on 14 half-rings, then sorted by angle so each party fills a wedge. That's one go.Scatter of markers per party on hidden 1:1 axes. The seat table on the right is rect and line shapes plus annotations in paper coordinates, and the two big numbers are annotations sitting in the gap in the middle.

Hex tile map #

[U.S. Census Bureau CPS ASEC via FRED](https://fred.stlouisfed.org/) · CARTO hexgrid layout ·
    [Code](https://chris-parmer.com/python/hex-tile-map/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-14.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-14.png)

Every state is a regular hexagon written as a type="path" shape, on a grid snapped from CARTO's hexgrid layout. Colors come from six bins rather than a continuous colorscale, and the legend is built from the same hexagons. An invisible marker trace sits on top so hover still works in the interactive version.

Daylight chart #

computed with the NOAA Solar Calculator equations ·

    [Code](https://chris-parmer.com/python/daylight-chart/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-15.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-15.png)

The sun's position is computed for every day of 2026 with NOAA's equations. Night, the three twilights and daylight are nested fill="toself" polygons in local clock time, which is why the daylight saving changes show up as vertical steps. Plotly simplifies nearly straight lines by default, and that made the curves look faceted, so line.simplify=False keeps them smooth.

BMI nomogram #

[computed; WHO BMI classification](https://www.who.int/data/gho/data/themes/topics/topic-details/GHO/body-mass-index) ·
    [Code](https://chris-parmer.com/python/nomogram/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-16.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-16.png)

The scale positions come from the standard three-parallel-scale nomogram equations. Every tick is a short segment in a mode="lines" scatter trace, and the red worked example is an ordinary trace laid across the scales. The title block in the corner is rect and line shapes with monospace annotations.

Tufte minimal #

[R datasets faithful (Härdle 1991)](https://vincentarelbundock.github.io/Rdatasets/csv/datasets/faithful.csv) · [MASS geyser](https://vincentarelbundock.github.io/Rdatasets/csv/MASS/geyser.csv) ·
    [Code](https://chris-parmer.com/python/tufte-minimal/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-17.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-17.png)

Three subplots, each with its axes switched off and redrawn as shapes that only span the data, which is Tufte's range frame. The dot-dash plot's rugs are scatter markers using the line-ns and line-ew marker symbols. The quartile plot is just line shapes with a gap for the middle half and a dot for the median.

Periodic table #

[Periodic-Table-JSON, compiled from Wikipedia](https://github.com/Bowserinator/Periodic-Table-JSON) ·
    [Code](https://chris-parmer.com/python/periodic-table/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-18.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-18.png)

Each tile is a rounded rectangle drawn as a type="path" shape and colored in Python from its melting point. Symbol, number, name and value are four separate text traces, with the text flipping between ink and white depending on how dark the tile is. The color bar across the top is 90 thin rectangles.

Topographic map #

[Copernicus DEM GLO-30 (ESA), via AWS Open Data](https://registry.opendata.aws/copernicus-dem/) ·
    [Code](https://chris-parmer.com/python/topographic-map/) ·
    [SVG](https://chris-parmer.com/static/static-charts-2/static2-19.svg) ·
    [PNG](https://chris-parmer.com/static/static-charts-2/static2-19.png)

Two go.Heatmap layers are stacked. The bottom one holds the elevation tints; the top one holds the hillshade on a dark colorscale whose alpha drops to zero on flat ground, which behaves like a multiply blend. The contours are go.Contour traces showing lines only, and the scale bar and north arrow are path shapes. This is the one chart with a raster inside its SVG, since Plotly heatmaps always export as an image.

── more in #ai-tools 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/19-extraordinary-cha…] indexed:0 read:8min 2026-10-16 · —