Public
Edited
Apr 17
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Inputs.table(restaurants, { width: 300 })
Insert cell
Insert cell
render({
width: 700,
height: 80,
mark: 'point',
data: { values: restaurants },
encoding: {
x: { field: 'lat', type: 'quantitative', axis: { title: 'Latitude' } },
y: { value: 0 },
jitter: { y: { height: 10 } } // vertical jitter to reduce overplotting
}
})

Insert cell
Insert cell
Insert cell
stats = {
const lats = restaurants.map(d => d.lat).sort(d3.ascending);
return {
min: d3.min(lats),
max: d3.max(lats),
mean: d3.mean(lats),
q1: d3.quantile(lats, 0.25),
q3: d3.quantile(lats, 0.75)
};
}

Insert cell
render({
width: 600,
height: 100,
layer: [
// 🔷 IQR bar
{
mark: 'bar',
data: {
values: [{ y: 0, x: stats.q1, x2: stats.q3 }]
},
encoding: {
x: {
field: 'x',
type: 'quantitative',
scale: { domain: [47.64, 47.68] },
axis: {
title: 'Latitude',
tickMinStep: 0.01,
values: [47.64, 47.65, 47.66, 47.67, 47.68]
}
},
x2: { field: 'x2' },
y: { field: 'y', type: 'ordinal', axis: null },
height: { value: 15 },
color: { value: '#d0d0d0' }
}
},

// 🔹 Ticks for min, mean, max
{
mark: 'tick',
data: {
values: [
{ label: 'min', lat: stats.min },
{ label: 'mean', lat: stats.mean },
{ label: 'max', lat: stats.max }
]
},
encoding: {
x: { field: 'lat', type: 'quantitative', scale: { domain: [47.64, 47.68] } },
y: { value: 0 },
color: { field: 'label', type: 'nominal' }
}
},

// 🏷️ Text labels with values for min, mean, max
{
mark: 'text',
data: {
values: [
{ label: `min: ${stats.min.toFixed(5)}`, lat: stats.min },
{ label: `mean: ${stats.mean.toFixed(5)}`, lat: stats.mean },
{ label: `max: ${stats.max.toFixed(5)}`, lat: stats.max }
]
},
encoding: {
x: { field: 'lat', type: 'quantitative', scale: { domain: [47.64, 47.68] } },
y: { value: -10 },
text: { field: 'label' },
color: { value: 'black' },
size: { value: 12 }
}
},

// 🏷️ Label for IQR with range
{
mark: 'text',
data: {
values: [
{
label: `IQR: ${stats.q1.toFixed(5)} – ${stats.q3.toFixed(5)}`,
x: (stats.q1 + stats.q3) / 2
}
]
},
encoding: {
x: { field: 'x', type: 'quantitative', scale: { domain: [47.64, 47.68] } },
y: { value: 20 },
text: { field: 'label' },
color: { value: '#555' },
size: { value: 12 }
}
}
]
})

Insert cell
Insert cell
render({
width: 600,
height: 200,
mark: 'bar',
data: { values: restaurants },
encoding: {
x: {
field: 'lat',
type: 'quantitative',
bin: { maxbins: 20 }, // Adjust bin count
axis: { title: 'Latitude', tickMinStep: 0.002 }
},
y: {
aggregate: 'count',
type: 'quantitative',
axis: { title: 'Count' }
}
}
})

Insert cell
Insert cell
Insert cell
Insert cell
render({
width: 600,
height: 200,
mark: 'bar',
data: { values: restaurants },
encoding: {
x: {
field: 'lat',
type: 'quantitative',
bin: { maxbins: 20 },
axis: { title: 'Latitude', tickMinStep: 0.01, format: '.3f' }
},
y: {
aggregate: 'count',
type: 'quantitative',
axis: { title: 'Count' }
},
color: {
field: 'key', // make sure this matches your actual data
type: 'nominal',
legend: { title: 'Restaurant Type' }
}
}
})

Insert cell
Insert cell
Insert cell
render({
width: 700,
height: 300,
mark: 'boxplot',
data: { values: restaurants },
encoding: {
x: {
field: 'key',
type: 'nominal',
axis: { title: 'Restaurant Type', labelAngle: -45 }
},
y: {
field: 'lat',
type: 'quantitative',
axis: { title: 'Latitude' },
scale: { domain: [47.650, 47.675] }
},
color: {
field: 'key',
type: 'nominal',
legend: null
}
}
})

Insert cell
Insert cell
Insert cell
Insert cell
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