Overview
Observable Plot is a JavaScript library for exploratory data visualization, created by Mike Bostock (the creator of D3.js) and the team at Observable. It represents Bostock’s answer to the question: “What would D3 look like if ease of use were the primary design goal?” The result is a concise, high-level API that produces sophisticated statistical graphics in just a few lines of code.
Plot follows the grammar-of-graphics paradigm (similar to ggplot2 in R) where visualizations are composed of marks (geometric elements like bars, dots, lines) mapped to data channels (x, y, color, size). But unlike ggplot2, Plot is designed for the JavaScript ecosystem and renders to SVG in the browser. It makes smart choices about scales, axes, legends, and labels automatically, so the defaults almost always look good.
Observable Plot integrates naturally with Observable notebooks (the company’s computational notebook platform) but works equally well as a standalone library in any JavaScript project. It is open-source (ISC license) and available via npm.
Strengths
- Extremely concise API — complex charts in 5-10 lines of code
- Smart defaults for scales, axes, colors, and legends
- Grammar-of-graphics approach enables composable, layered visualizations
- Built-in statistical transforms: bin, group, stack, normalize, window, tree
- Faceting (small multiples) is a first-class feature
- Excellent handling of temporal and categorical data
- Renders to clean SVG, easy to style with CSS
- Lightweight (~100KB) with zero dependencies
- Created by the D3 creator — deeply informed by visualization best practices
- Works in Observable notebooks, React, Svelte, or plain HTML
Limitations
- Limited interactivity — primarily produces static SVGs (tooltips via Plot.tip mark)
- Relatively new (2021), so the community and ecosystem are still growing
- Animation and transitions are not built in
- Less control over low-level details compared to D3
- Documentation, while good, has fewer community tutorials than mature libraries
- Not ideal for large datasets (>100K points) without aggregation
- Dashboard layout and multi-chart coordination require external solutions
- No built-in export to PNG/PDF — requires additional tools
Best For
Observable Plot is ideal for data scientists and analysts working in JavaScript who want the speed of ggplot2-style specification with web-native output. It excels in exploratory data analysis within Observable notebooks, rapid prototyping of statistical graphics, and situations where you want a chart that “just works” with minimal configuration. If you find D3 too verbose for everyday charts but need more flexibility than a charting library provides, Plot is the sweet spot.
Getting Started
Install via npm:
npm install @observablehq/plot
Create your first chart:
import * as Plot from "@observablehq/plot";
// In a browser or Observable notebook
const chart = Plot.plot({
marks: [
Plot.barY(data, Plot.groupX({ y: "count" }, { x: "category" })),
Plot.ruleY([0])
]
});
document.getElementById("chart").append(chart);
A scatterplot with color encoding and regression line:
Plot.plot({
color: { legend: true },
marks: [
Plot.dot(penguins, {
x: "culmen_length_mm",
y: "body_mass_g",
fill: "species"
}),
Plot.linearRegressionY(penguins, {
x: "culmen_length_mm",
y: "body_mass_g",
stroke: "species"
})
]
});
Supported Chart Types
Observable Plot handles bar charts, stacked bar charts, line graphs, area graphs (including stacked and streamgraph), scatterplots, bubble charts, histograms, heatmaps (via cell and rect marks), box plots (via rule and tick marks), dot plots, slope charts, hexbin plots, density contours, and small multiples/faceted charts. It also supports geographic marks for choropleth maps, tree/hierarchical layouts, and link diagrams. Through its composable mark system, many chart types not explicitly built in (like lollipop charts or dumbbell plots) can be assembled from primitives.