{"slug": "19-extraordinary-charts-made-with-opus-5-5-and-plotly", "title": "19 extraordinary charts made with Opus 5.5 and Plotly", "summary": "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.", "body_md": "# 19 extraordinary charts made with Opus 5.5 and Plotly\n\nFrontier 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.\n\nUnder 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!\n\n    See some more examples in my other post,\n    [Plotly for Highly Customizable Print-Ready Data Visualization](https://chris-parmer.com/plotly-for-highly-customizable-print-ready-data-visualization/).\n\n## Airport Voronoi\n\n[plotly/datasets 2011_february_us_airport_traffic.csv](https://github.com/plotly/datasets/blob/master/2011_february_us_airport_traffic.csv) · [PublicaMundi us-states.json](https://github.com/PublicaMundi/MappingAPI) ·\n    [Code](https://chris-parmer.com/python/airport-voronoi/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-01.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-01.png)\n\nThere'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`.\n\n## Isotype population\n\n[Our World in Data, Population (HYDE, Gapminder, UN WPP)](https://ourworldindata.org/grapher/population) ·\n    [Code](https://chris-parmer.com/python/isotype/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-02.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-02.png)\n\nEach 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.\n\n## xkcd style\n\n[Karl Rupp via Our World in Data](https://ourworldindata.org/grapher/transistors-per-microprocessor) ·\n    [Code](https://chris-parmer.com/python/xkcd-style/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-03.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-03.png)\n\nThe 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.\n\n## Migration chord\n\n[Abel & Cohen (2019), bilateral international migration flow estimates](https://doi.org/10.6084/m9.figshare.7731233) ·\n    [Code](https://chris-parmer.com/python/chord-diagram/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-04.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-04.png)\n\nThe 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.\n\n## Arc diagram\n\n[Donald Knuth, The Stanford GraphBase, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/miserables.json) ·\n    [Code](https://chris-parmer.com/python/arc-diagram/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-05.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-05.png)\n\nOne 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`.\n\n## Circle packing\n\n[Our World in Data, Population 2023 (UN WPP 2024)](https://ourworldindata.org/grapher/population) ·\n    [Code](https://chris-parmer.com/python/circle-packing/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-06.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-06.png)\n\nPlotly 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`.\n\n## Streamgraph\n\n[U.S. Bureau of Labor Statistics, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/unemployment-across-industries.json) ·\n    [Code](https://chris-parmer.com/python/streamgraph/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-07.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-07.png)\n\nThe 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.\n\n## Horizon chart\n\n[NOAA NCEI, GHCN-Daily and U.S. Climate Normals 1991–2020](https://www.ncei.noaa.gov/access/services/data/v1) ·\n    [Code](https://chris-parmer.com/python/horizon-chart/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-08.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-08.png)\n\nEach 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.\n\n## Radial dendrogram\n\n[the Flare class hierarchy, via vega-datasets](https://github.com/vega/vega-datasets/blob/main/data/flare.json) ·\n    [Code](https://chris-parmer.com/python/radial-tree/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-09.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-09.png)\n\nThe 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.\n\n## Star chart\n\n[d3-celestial by Olaf Frohn (Hipparcos stars, IAU constellation figures)](https://github.com/ofrohn/d3-celestial) ·\n    [Code](https://chris-parmer.com/python/star-chart/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-10.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-10.png)\n\nThis 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.\n\n## Circos genome plot\n\n[UCSC Genome Browser hg38 cytoBand and NCBI RefSeq curated](https://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/) ·\n    [Code](https://chris-parmer.com/python/circos/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-11.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-11.png)\n\nEverything 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.\n\n## Chart of biography\n\n    Encyclopaedia Britannica and ODNB dates, hardcoded ·\n    [Code](https://chris-parmer.com/python/chart-of-biography/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-12.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-12.png)\n\nEach 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.\n\n## Parliament chart\n\n[House of Commons Library, General Election 2024 results](https://commonslibrary.parliament.uk/research-briefings/cbp-10009/) ·\n    [Code](https://chris-parmer.com/python/parliament/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-13.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-13.png)\n\nThe 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.\n\n## Hex tile map\n\n[U.S. Census Bureau CPS ASEC via FRED](https://fred.stlouisfed.org/) · CARTO hexgrid layout ·\n    [Code](https://chris-parmer.com/python/hex-tile-map/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-14.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-14.png)\n\nEvery 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.\n\n## Daylight chart\n\n[computed with the NOAA Solar Calculator equations](https://gml.noaa.gov/grad/solcalc/calcdetails.html) ·\n    [Code](https://chris-parmer.com/python/daylight-chart/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-15.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-15.png)\n\nThe 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.\n\n## BMI nomogram\n\n[computed; WHO BMI classification](https://www.who.int/data/gho/data/themes/topics/topic-details/GHO/body-mass-index) ·\n    [Code](https://chris-parmer.com/python/nomogram/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-16.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-16.png)\n\nThe 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.\n\n## Tufte minimal\n\n[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) ·\n    [Code](https://chris-parmer.com/python/tufte-minimal/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-17.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-17.png)\n\nThree 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.\n\n## Periodic table\n\n[Periodic-Table-JSON, compiled from Wikipedia](https://github.com/Bowserinator/Periodic-Table-JSON) ·\n    [Code](https://chris-parmer.com/python/periodic-table/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-18.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-18.png)\n\nEach 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.\n\n## Topographic map\n\n[Copernicus DEM GLO-30 (ESA), via AWS Open Data](https://registry.opendata.aws/copernicus-dem/) ·\n    [Code](https://chris-parmer.com/python/topographic-map/) ·\n    [SVG](https://chris-parmer.com/static/static-charts-2/static2-19.svg) ·\n    [PNG](https://chris-parmer.com/static/static-charts-2/static2-19.png)\n\nTwo `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.", "url": "https://wpnews.pro/news/19-extraordinary-charts-made-with-opus-5-5-and-plotly", "canonical_source": "https://chris-parmer.com/19-extraordinary-charts-made-with-opus-5-5-and-plotly/", "published_at": "2026-10-16 00:00:00+00:00", "updated_at": "2026-10-30 21:16:43.037273+00:00", "lang": "en", "topics": ["ai-tools", "generative-ai", "large-language-models", "ai-agents"], "entities": ["Anthropic", "Claude Code", "Opus 5.5", "Plotly", "Our World in Data", "Donald Knuth"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/19-extraordinary-charts-made-with-opus-5-5-and-plotly", "markdown": "https://wpnews.pro/news/19-extraordinary-charts-made-with-opus-5-5-and-plotly.md", "text": "https://wpnews.pro/news/19-extraordinary-charts-made-with-opus-5-5-and-plotly.txt", "jsonld": "https://wpnews.pro/news/19-extraordinary-charts-made-with-opus-5-5-and-plotly.jsonld"}}