Public
Edited
Mar 30, 2023
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 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.dotX(data, { y: fy }), // 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.dotX(data, { y: fy }),
Plot.axisY({ ticks: 7, label: null, anchor: "right" })
]
: null,
fy === fields[fields.length - 1]
? [
// bottom x axes
Plot.dotY(data, { x: fx }),
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 = Plot.valueof(data, 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