Public
Edited
May 6
Insert cell
Insert cell
Popdata2.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
Insert cell
rawData = FileAttachment("Popdata2.csv").csv()
Insert cell
import { Plot } from "@observablehq/plot"
Insert cell
d3 = require("d3")
Insert cell
data = rawData.map(d => ({
year: +d["Year"],
medianAge: +d["Median\nAge"],
fertilityRate: +d["Fertility\nRate"]
})).filter(d => d.year && d.medianAge && d.fertilityRate)
Insert cell
data1 = rawData.columns
Insert cell
Insert cell
Plot.plot({
title: "Global Median Age",
marks: [
Plot.lineY(data, {
x: "year",
y: "medianAge",
stroke: "steelblue",
tip: true
})
]
})
Insert cell
Plot.plot({
title: "Global Fertility Rate",
marks: [
Plot.lineY(data, {
x: "year",
y: "fertilityRate",
stroke: "tomato",
tip: true
})
]
})
Insert cell
Plot.plot({
title: "Global Median Age and Fertility Rate",
x: {
label: "Year",
domain: [1960, 2020],
ticks: [1960, 1970, 1980, 1990, 2000, 2010, 2020]
},
y: {
label: "Fertility Rate",
domain: [1, 5],
grid: true
},
color: {
domain: ["Fertility Rate", "Median Age"],
range: ["steelblue", "tomato"],
legend: true
},
marks: [
// Left Y-axis for Fertility Rate
Plot.axisY({ anchor: "left", label: "Fertility Rate", color: "steelblue" }),

// Right Y-axis for Median Age
Plot.axisY(
d3.scaleLinear(d3.extent(data, d => d.medianAge), [1, 5]).ticks(),
{
y: d3.scaleLinear(d3.extent(data, d => d.medianAge), [1, 5]),
anchor: "right",
label: "Median Age",
color: "tomato",
tickFormat: d3.scaleLinear(d3.extent(data, d => d.medianAge), [1, 5]).tickFormat()
}
),

// Fertility Rate line (left axis)
Plot.lineY(data, {
x: "year",
y: "fertilityRate",
stroke: "steelblue",
}),

// Median Age line (mapped to fertility axis range)
Plot.lineY(
data.map(d => ({
year: d.year,
mapped: d3.scaleLinear(d3.extent(data, d => d.medianAge), [1, 5])(d.medianAge)
})),
{
x: "year",
y: "mapped",
stroke: "tomato"
}
),

Plot.ruleY([1])
]
})
Insert cell
medianAgeScale = d3.scaleLinear(
d3.extent(data, d => d.medianAge),
[1, 5]
);
Insert cell
// Define scale for Median Age mapped to Fertility Rate axis
Plot.plot({
title: "Global Median Age and Fertility Rate",
x: {
label: "Year",
domain: [1960, 2020],
ticks: [1960, 1970, 1980, 1990, 2000, 2010, 2020]
},
y: {
label: "Fertility Rate",
domain: [1, 5],
grid: true
},
color: {
domain: ["Fertility Rate", "Median Age"],
range: ["steelblue", "tomato"],
legend: true
},
marks: [
// Left Y-axis for Fertility Rate
Plot.axisY({
anchor: "left",
label: "Fertility Rate",
color: "steelblue"
}),

// Right Y-axis for Median Age using mapped scale
Plot.axisY({
anchor: "right",
label: "Median Age",
color: "tomato",
scale: medianAgeScale,
tickFormat: d3.format(".0f")
}),

// Fertility Rate line (left axis)
Plot.lineY(data, {
x: "year",
y: "fertilityRate",
stroke: "steelblue"
}),

// Median Age line (mapped to fertility axis range)
Plot.lineY(data.map(d => ({
year: d.year,
mapped: medianAgeScale(d.medianAge)
})), {
x: "year",
y: "mapped",
stroke: "tomato"
}),

// Tooltip dot for both values
Plot.dot(data.map(d => ({
year: d.year,
fertilityRate: d.fertilityRate,
medianAge: d.medianAge,
mapped: medianAgeScale(d.medianAge)
})), {
x: "year",
y: "fertilityRate",
title: d => `Year: ${d.year}
Fertility Rate: ${d.fertilityRate.toFixed(2)}
Median Age: ${d.medianAge.toFixed(2)}`,
r: 5,
fill: "transparent",
tip: true
}),

// Base line
Plot.ruleY([1])
]
})
Insert cell
Popdata2.csv
X
Country
Y
Population (2024)
Color
Size
Facet X
Facet Y
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Plot.plot({
x: {label: "Country"},
y: {label: "Population (2024)", grid: true},
marks: [
Plot.barY(
worldPop2024.slice(0, 10),
{x: "Country", y: "Population (2024)", tip: true}
)
]
})
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