Public
Edited
Jun 28, 2023
Paused
11 forks
Importers
57 stars
Plot: A few custom time axesAccess to Family planningPlot: Marimekko
Autoplot matrix
What do people buy on Bandcamp?Plot: colorContrast transformA Timeline of Democratic Presidential CandidatesPlot: Diverging stacked barsPlot: Horizon ChartPlot: Ridgeline PlotTwo-Tone Pseudo Color Scales with Observable Plot & Vega-LiteRecreating Östling’s regression visualizationsError barsPlot: regressionSkies PlotHorizon graph & Barcode with PlotTemporal AliasingPlot for mathematiciansPlot Isotype dot plotCOVID-19 Netherlands Reproduction Number TutorialPlot Mountain SunsetSpine chartsGreenhouse gas emission projectionsRaincloud Plots with Observable PlotUpset Plots with Observable PlotExploring CIELChabNature variant waves graphicWhen Presidents Fade AwayThe Coronavirus landscapeOur World In Data charts visualisationThe normal modelVisualizing The New York Times’s Mini CrosswordDistributions and summary statistics - a collection of Plot examplesVariants of SARS-Cov-2 in EuropeLaid off: 6 million jobs and countingConcentration values vs. TimeTopological subsamplingPlot of plotsCyclical time scale, v2Bullet graph IIPlot: Bullet graphCyclical time scaleRoad traffic under COVID restrictions (France)K-means binningMatrix diagramELD ViewerHappy anniversary, Project Gutenberg!ROC curvePlot stargazer historyPlot HyperboloidPhone bar plotsLog-scale histogramDatabase Outage PlotBertin’s hotelIreland’s top trade partnersBump chartBubble MatrixRenko ChartGitHub BurndownPlot: Grid choroplethCandlestick Chart
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = Plot.plot({
width,
height: Math.min(780, width),
marginTop: 20,
marginLeft: 60,
marginRight: 70,
marginBottom: 33,
facet: { data: cofields, x: "0", y: "1" },
fx: { domain: fields },
fy: { domain: fields },
axis: null,
marks: [Plot.frame(), new SubPlot(cofields)]
})
Insert cell
Insert cell
Insert cell
myData = [{}]
Insert cell
Insert cell
PlotMatrix = () => html`${viewof fields}${viewof colorSel}${legend}${chart}`
Insert cell
Insert cell
class SubPlot extends Plot.Mark {
// This function receives the facet information (fx and fy), and returns a new Plot
render({ fx, fy }, _scales, _channels, dimensions) {
// The charts on the same column must share the same x scale, and the charts on the
// same row must share the same y scale (except on the diagonal). Currently this works
// because plots are consistent, but it’s not guaranteed if you start playing with
// more custom charts.
return htl.svg`<g>${Plot.plot({
...dimensions,
insetTop: fx === fy ? 20 : 6,
insetBottom: fx === fy ? 0 : 6,
inset: 6,
axis: null,
nice: true,
color: color.scale("color"),
marks: [
fx === fy
? [
// diagonal cell (one dimension)
Plot.auto(data, { x: fx, color: { value: colorBy } }),
Plot.text([fx], {
frameAnchor: "top",
fontWeight: "bold",
dy: 5
})
]
: [
// two dimensions
Plot.gridX({ ticks: 5 }),
Plot.gridY({ ticks: 7 }),
Plot.auto(data, { x: fx, y: fy, color: { value: colorBy } })
],
fx === fields[0] && fy !== fx
? [
// left y axes (note that we omit it on the top-left cell, where y is defined by the bar chart)
Plot.dotY(data, { y: fy, filter: [] }), // no output, but necessary to set the y scale
Plot.axisY({ ticks: 7, label: null, anchor: "left" })
]
: null,
fx === fields[fields.length - 1] && fy !== fx
? [
// right y axes
Plot.dotY(data, { y: fy, filter: [] }),
Plot.axisY({ ticks: 7, label: null, anchor: "right" })
]
: null,
fy === fields[fields.length - 1]
? [
// bottom x axes
Plot.dotX(data, { x: fx, filter: [] }),
Plot.axisX({ ticks: 5, anchor: "bottom", labelAnchor: "center" })
]
: null
]
})}`;
}
}
Insert cell
Insert cell
columns = (data.columns || Object.keys(data[0])).filter((key) => {
// filter out fields which can't be useful at all (ordinal with too many values)
const values = Plot.valueof(data, key);
for (const p of values)
if (typeof p === "string") return new Set(values).size < 30;
return true;
})
Insert cell
colorBy = Object.assign(Plot.valueof(data, colorSel), {label: colorSel})
Insert cell
// This chart, while not super interesting, defines a color scale shared across subplots
// You can specify options that depend on the selected colorSel field, or let Plot choose the default.
color = Plot.barX(data, Plot.groupZ({ x: "count" }, { fill: colorBy })).plot({
height: 20,
axis: null,
color:
colorSel === "species"
? { scheme: "category10" }
: colorSel === "island"
? { scheme: "buylrd" }
: colorSel === "economy (mpg)"
? { scheme: "inferno" }
: {}
})
Insert cell
Insert cell
cofields = d3.cross(fields, fields)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more