Unlisted
Edited
Apr 24
1 fork
Importers
Insert cell
Insert cell
Insert cell
weather.sample(8).view()
Insert cell
Insert cell
Insert cell
tempMinMax = vl.markArea({ opacity: 0.3 })
.encode(
vl.x().month('date'),
vl.y().average('temp_max').title('Temperature ºC'),
vl.y2().average('temp_min'),
)
Insert cell
tempMiddle = vl.markLine()
.transform(
vl.calculate('(datum.temp_min + datum.temp_max) / 2').as('temp_avg')
)
.encode(
vl.x().month('date'),
vl.y().average('temp_avg').title('Temperature ºC'),
)
Insert cell
vl
// Instead of duplicating the data and filter in each layer, we can specify it at the "top level"
.data(weather)
.transform(
vl.filter('datum.city === "Boston" || datum.city === "San Luis Obispo"')
)
// Can also add encodings to the top level. What happens if you remove this color encoding?
.encode(
vl.color().fieldN('city')
)
.layer(tempMinMax, tempMiddle)
.render()
Insert cell
Insert cell
Insert cell
viewof rainTemp = vl
.data(weather)
.transform(vl.filter('datum.city === "Boston"'))
.layer(precipitationAvg, tempMinMax)
.resolve({ scale: { y: 'independent' }})
.title('Boston weather')
.render()
Insert cell
Insert cell
vl.markBar()
.encode(
vl.x().fieldQ('temp_max').bin(true)
.title('Temperature ºC'),
vl.y().count()
.title('Number of days')
)
.width(200)
.height(150)
.facet(vl.column().fieldN('city').header({ title: null}))
.resolve({ axis: { y: 'independent' }})
.data(weather)
.render()
Insert cell
{
const colors = {
domain: ['drizzle', 'fog', 'rain', 'hazy', 'sun'],
range: ['#aec7e8', '#c7c7c7', '#1f77b4', '#9467bd', '#e7ba52']
};
return vl.markBar()
.encode(
vl.x().fieldQ('temp_max')
.bin(true)
.title('Max. temperature ºC'),
vl.y().count().title('Number of days'),
vl.color().fieldN('weather').scale(colors)
)
.width(150)
.height(150)
.facet({column: vl.field('weather'), row: vl.field('city')})
.resolve({ scale: { x: 'independent' } })
.data(weather)
.render()
}
Insert cell
Insert cell
vl.markLine({ interpolate: 'monotone' })
.encode(
vl.x().month('date'),
vl.y().average(vl.repeat('column')), // <-- The y encoding will be set to the average of the repeat variables specified below
vl.color().fieldN('city')
)
.width(250)
.height(180)
.data(weather)
.repeat({ column: ['precipitation', 'wind_avg', 'temp_min'] }) // <-- Repeat the chart with each of these variables
.render()
Insert cell
Insert cell
Insert cell
Insert cell
vl.markCircle({ size: 30 })
.transform(
// Filter to Seattle data
)
.encode(
// x, using a repeat variable
// y, using a repeat variable
)
// width and height should come here (they are properties of the chart that will get repeated)
.repeat({
// row
// column
})
.data(weather) // <--- Data must come after the repeat
.render()
Insert cell
Insert cell
Insert cell
vl.hconcat(
vl.markBoxplot({ size: 50 })
.encode(
vl.y().fieldQ('wind_avg')
)
.width(75),
vl.markBar()
.encode(
vl.x().count(),
vl.y().fieldQ('wind_avg').bin(true),
)
.width(200)
)
.data(weather)
.resolve({ scale: { y: 'shared' }})
.render()

Insert cell
Insert cell
{
const row_order = ['wind_avg', 'precipitation', 'temp_max'];
const splom = vl.markCircle({ size: 30 })
.encode(
vl.x().fieldQ(vl.repeat('column')),
vl.y().fieldQ(vl.repeat('row'))
)
.width(140)
.height(125)
.repeat({
row: row_order,
column: row_order.toReversed()
});

const monthBars = vl.layer(
vl.markBar()
.encode(
vl.x().month('date'),
vl.y().average(vl.repeat('row'))
),
vl.markRule({ color: 'firebrick', strokeWidth: 2 })
.encode(
vl.y().average(vl.repeat('row'))
)
)
.width(125)
.height(125)
.repeat({
row: row_order
});

const colors = {
domain: ['drizzle', 'fog', 'rain', 'hazy', 'sun'],
range: ['#aec7e8', '#c7c7c7', '#1f77b4', '#9467bd', '#e7ba52']
};
const weatherFacets = vl.markBar()
.encode(
vl.x().fieldQ('temp_max').bin(true),
vl.y().count().title('Number of days'),
vl.color().fieldN('weather').scale(colors)
)
.width(125)
.height(125)
.facet({column: vl.field('weather')});

return vl.data(weather)
.transform(vl.filter('datum.city === "San Luis Obispo"'))
.title('San Luis Obispo Weather Dashboard')
.vconcat(
vl.hconcat(splom, monthBars),
weatherFacets
)
.resolve({ legend: { color: 'independent' } })
.render()
}
Insert cell
Insert cell
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