You have found a useful pattern in a notebook. Now the chart needs to live in a React application, match its theme, fit a phone, and explain itself to a new reader. unstable_fromObservablePlot can carry a supported Plot-style specification across that boundary, leaving you to review the translation and add the context.
Why this matters
The expensive part of a handoff is remembering the decisions behind the picture. Which column identifies a series? Are the bars stacked? Does the horizontal axis represent time or categories? Translating those choices into an inspectable configuration gives the next author something concrete to check.
Two questions, two charts
Choose Multi-series line to compare weekly growth in two plans. Follow each line from week 1 to week 4; Free stays higher, while Pro also grows. Choose Stacked bars to compare monthly totals and the contribution of each plan. These are separate synthetic examples, so a week on the line is not a month in the bars.
Plot.lineY(data, { x: "week", y: "users", stroke: "plan" }).plot({ color: { scheme: "tableau10" } })
Free rises from 240 to 360; Pro rises from 90 to 280.
The notation above corresponds to the plain-object input used in this demo. The adapter returns a LineChart configuration; this page adds its title, description, summary, and exact-value table.
What the adapter actually accepts
The input is a plain object describing marks, data, and channels. It is not an arbitrary Plot.plot() result, a rendered SVG, or a JavaScript program to execute. AlineY mark with a numeric week field becomes a LineChart; abarY mark with a fill field can become a StackedBarChart.
Translation warnings are part of the result. Multiple data marks may be reduced to the first one, facets are not reconstructed, and function-valued channels are not preserved. Some unsupported input can still return a partial configuration. A warning therefore needs a decision from the caller; it is not an automatic refusal to render.
When to reach for it
Use it for a supported chart whose field mappings you can inspect. Keep a complex Plot composition in Plot when its custom marks, transforms, or facets are the point. For a translation you keep, author a title and summary, enable the exact-value table, and test the keyboard and small-screen experience. Translation does not write that explanation or add anavigation tree for you.
Wiring it up
import { unstable_fromObservablePlot } from "semiotic/experimental" const config = unstable_fromObservablePlot({ marks: [{ type: "lineY", data, options: { x: "week", y: "users", stroke: "plan" } }], }) if (config.warnings?.length) { // Show the warnings and resolve the unsupported parts before rendering. }The adapter uses an experimental entry point, so pin the package version and keep a representative translation in your tests. The reference page lists the supported marks and the shape of the returned configuration.
Other places this helps
The same review applies when a notebook figure enters a report, an analyst hands a chart to a product team, or an assistant proposes a chart in another grammar. Preserve the question and encoding, then check the destination's reading experience.