Public
Edited
Jun 10, 2023
17 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ageData = [
{ "person": "Mary", "age": 45 },
{ "person": "Jane", "age": 52 },
{ "person": "Jamil", "age": 35 },
{ "person": "Liang", "age": 21 }
]
Insert cell
Insert cell
printTable(ageData)
Insert cell
Insert cell
printTableTypes(ageData)
Insert cell
Insert cell
vl.markBar() // select the mark type
.data(ageData) // add the data
.encode( // add the visual encodings
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250) // set graph size
.render()
Insert cell
Insert cell
vegalite({
mark: 'bar', // select the mark type
data: {values: ageData}, // add the data
encoding: { // add the visual encodings
x: {field: 'person', type: 'nominal'},
y: {field: 'age', type: 'quantitative'}
},
width: 250, height: 250, // set graph size
})
Insert cell
Insert cell
Insert cell
vl.markBar()
.data(ageData)
.title({text: "Friend's Age"})
.encode({
x: {field: 'person', type: 'nominal', title: 'Friend'}, // now the x encoding expressed as JSON
y: {field: 'age', type: 'quantitative', title: 'Age'} // y encoding expressed as JSON
}).width(300).render()
Insert cell
Insert cell
{
// Same code as before but store in a plot variable
const plot = vl.markBar()
.data(ageData)
.encode(
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250);
return plot.toObject();
}
Insert cell
Insert cell
{
const plot = vl.markBar()
.data(ageData)
.encode(
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250);
return html`<pre>${JSON.stringify(plot.toObject(), 0, 2)}</pre>`; // prettify the string
}
Insert cell
Insert cell
Insert cell
ageBarPlot = vl.markBar()
.data(ageData)
.encode(
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250);
Insert cell
Insert cell
ageBarPlot.render()
Insert cell
Insert cell
printVegaLiteJSON(ageBarPlot);
Insert cell
Insert cell
printVegaLiteJSON(ageBarPlot, true);
Insert cell
Insert cell
vegalite({
"mark": {
"type": "bar"
},
"data": {
"values": [
{
"person": "Mary",
"age": 45
},
{
"person": "Jane",
"age": 52
},
{
"person": "Jamil",
"age": 35
},
{
"person": "Liang",
"age": 21
}
]
},
"encoding": {
"x": {
"field": "person",
"type": "nominal"
},
"y": {
"field": "age",
"type": "quantitative"
}
},
"width": 250,
"height": 250
})
Insert cell
Insert cell
vegalite({
"mark": {
"type": "bar"
},
"data": {
values: ageData // point data to ageData
},
"encoding": {
"x": {
"field": "person",
"type": "nominal"
},
"y": {
"field": "age",
"type": "quantitative"
}
},
"width": 250,
"height": 250
})
Insert cell
Insert cell
vegalite({
width: 250, height: 250,
data: {values: ageData},
mark: 'bar',
encoding: {
x: {field: 'person', type: 'nominal'},
y: {field: 'age', type: 'quantitative'}
}
})
Insert cell
Insert cell
vegalite({
width: 250, height: 250,
data: {url: "https://jonfroehlich.github.io/vis/data/age_data.json"}, // now load data from external file
mark: 'bar',
encoding: {
x: {field: 'person', type: 'nominal'},
y: {field: 'age', type: 'quantitative'}
}
})
Insert cell
Insert cell
Insert cell
vl.markBar()
.data(ageData)
.transform(
// In Vega-Lite, datum refers to the current data point when iterating
// through all data points in the dataset. In this case, we
// can setup a filter to remove data that has an age field less than 40
vl.filter('datum.age >= 40') // keep all data with age >= 40
)
.encode(
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250)
.render()
Insert cell
Insert cell
vegalite({
width: 250, height: 250,
data: {values: ageData},
transform: [{filter: 'datum.age >= 40'}], // keep all data with age >= 40
mark: 'bar',
encoding: {
x: {field: 'person', type: 'nominal'},
y: {field: 'age', type: 'quantitative'}
}
})
Insert cell
Insert cell
{
const ageFilterParam = vl.param("age_threshold")
.value(20) // initial value
.bind(vl.slider(20, 60, 5).name('Filter ages: ')) // add slider with min, max, step
return vl.markBar()
.data(ageData)
.params(ageFilterParam)
.transform(
vl.filter('datum.age >= age_threshold')
)
.encode(
vl.x().fieldN('person'),
vl.y().fieldQ('age')
)
.width(250).height(250)
.render()
}
Insert cell
Insert cell
vegalite({
"data": {"url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"}, // updated url to absolute path
"mark": "bar",
"encoding": {
"x": {"timeUnit": "month", "field": "date", "type": "temporal"},
"y": {"aggregate": "mean", "field": "precipitation"}
}
})
Insert cell
Insert cell
vl.markBar()
.data({url: "https://vega.github.io/vega-lite/data/seattle-weather.csv"})
.encode(
vl.x().fieldT('date').timeUnit('month'),
vl.y().fieldQ('precipitation').aggregate('mean')
)
.width(200).height(200)
.render()
Insert cell
Insert cell
vegalite({
"width": 300, "height": 200,
"data": {"url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"}, // change url to abs path
"mark": "area",
"encoding": {
"x": {
"timeUnit": "yearmonth", "field": "date",
"axis": {"format": "%Y"}
},
"y": {
"aggregate": "sum", "field": "count"
},
"color": {
"field": "series",
"scale": {"scheme": "category20b"}
}
}
})
Insert cell
Insert cell
vl.markArea()
.data({url: "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"})
.encode(
vl.x().fieldT('date'),
vl.y().fieldQ('count').aggregate('sum'),
vl.color().fieldN('series').scale({scheme: 'category20b'})
).render()
Insert cell
Insert cell
vegalite({
"width": 300, "height": 300,
"data": {"url": "https://vega.github.io/vega-lite/data/cars.json"}, // change url to absolute path
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"}
}
})
Insert cell
Insert cell
vl.markPoint()
.data({url: "https://vega.github.io/vega-lite/data/cars.json"})
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon')
)
.width(300).height(300)
.render()
Insert cell
Insert cell
Insert cell
vegalite({
"width" : 400,
"data": {
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43}
]
},
"encoding": {
"y": {"field": "a", "type": "nominal"},
"x": {"field": "b", "type": "quantitative", "scale": {"domain": [0, 60]}}
},
"layer": [{
"mark": "bar"
}, {
"mark": {
"type": "text",
"align": "left",
"baseline": "middle",
"dx": 3
},
"encoding": {
"text": {"field": "b", "type": "quantitative"}
}
}]
})
Insert cell
Insert cell
vl.data([{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43}])
.layer(
vl.markBar().encode(
vl.y().fieldN('a'),
vl.x().fieldQ('b').scale({domain: [0, 60]}),
),
vl.markText({align: 'left', baseline: 'middle', dx: 3}).encode(
vl.y().fieldN('a'),
vl.x().fieldQ('b').scale({domain: [0, 60]}),
vl.text().fieldQ('b')
)
)
.width(400)
.render()
Insert cell
Insert cell
{
const data = [{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43}];

const barPlot = vl.markBar()
.encode(
vl.y().fieldN('a'),
vl.x().fieldQ('b').scale({domain: [0, 60]})
);

const barText = vl.markText({align: 'left', baseline: 'middle', dx: 3})
.encode(
vl.y().fieldN('a'),
vl.x().fieldQ('b').scale({domain: [0, 60]}),
vl.text().fieldQ('b')
);

return vl.data(data)
.layer(barPlot, barText)
.width(400)
.render();
}
Insert cell
vegalite({
"repeat": {"column": ["Origin", "Cylinders"]},
"spec": {
"data": {"url": "https://vega.github.io/vega-lite/data/cars.json"},
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {"field": {"repeat": "column"}, "type": "nominal"}
}
},
"resolve": {"scale": {"color": "independent"}}
})
Insert cell
Insert cell
vegalite({
"data": {"url": "https://vega.github.io/vega-lite/data/cars.json"},
"layer": [
{
"params": [{
"name": "brush",
"select": {"type": "interval", "encodings": ["x"]}
}],
"mark": "bar",
"encoding": {
"x": {"field": "Acceleration", "bin": true},
"y": {"aggregate": "count"}
}
},
{
"transform": [{"filter": {"param": "brush"}}],
"mark": "bar",
"encoding": {
"x": {"field": "Acceleration", "bin": true},
"y": {"aggregate": "count"},
"color": {"value": "goldenrod"}
}
}
]
})
Insert cell
Insert cell
vl.data({url: "https://vega.github.io/vega-lite/data/cars.json"})
.layer(
vl.markBar()
.params(vl.selectInterval({encodings: ['x']}).name('brush'))
.encode(
vl.x().fieldQ('Acceleration').bin(true),
vl.y().aggregate('count')
),
vl.markBar()
.transform(vl.filter({param: 'brush'}))
.encode(
vl.x().fieldQ('Acceleration').bin(true),
vl.y().aggregate('count'),
vl.color().value('goldenrod')
)
).width(200).height(200).render()
Insert cell
Insert cell
Insert cell
printTable(await d3.csv("https://vega.github.io/vega-lite/data/lookup_groups.csv"))
Insert cell
Insert cell
printTable(await d3.csv("https://vega.github.io/vega-lite/data/lookup_people.csv"))
Insert cell
Insert cell
Insert cell
vegalite({
"data": {"url": "https://vega.github.io/vega-lite/data/lookup_groups.csv"},
"transform": [{
"lookup": "person",
"from": {
"data": {"url": "https://vega.github.io/vega-lite/data/lookup_people.csv"},
"key": "name",
"fields": ["age", "height"]
}
}],
"mark": "bar",
"encoding": {
"x": {"field": "group"},
"y": {"field": "age", "aggregate": "mean"}
}
})
Insert cell
Insert cell
vl.markBar()
.data({url: "https://vega.github.io/vega-lite/data/lookup_groups.csv"})
.transform(
vl.lookup("person").from(
vl.data({url: "https://vega.github.io/vega-lite/data/lookup_people.csv"})
.key("name").fields(['age', 'height'])
)
)
.encode(
vl.x().fieldN('group'),
vl.y().fieldQ('age').aggregate('mean')
).height(200).render();
Insert cell
Insert cell
nbaDataFile = FileAttachment("nba_shooting_stats_2000-2023.csv");
Insert cell
nbaData = nbaDataFile.csv({typed: true})
Insert cell
Insert cell
printTable(nbaData.slice(-5))
Insert cell
Insert cell
printTableTypes(nbaData)
Insert cell
Insert cell
nbaDataFixedTypes = nbaData.map((d) => ({ ...d, Year: new Date(d.Year, 0) }))
Insert cell
printTableTypes(nbaDataFixedTypes)
Insert cell
Insert cell
Insert cell
Insert cell
vl.markLine()
.data(nbaDataFixedTypes)
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ('3 Pointers Made')
).render()
Insert cell
Insert cell
{
const plot = vl.markLine()
.data(nbaDataFixedTypes)
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ('3 Pointers Made')
);

return printVegaLiteJSON(plot);
}
Insert cell
Insert cell
vegalite({
width: 400, height: 300,
data: {values: nbaDataFixedTypes},
mark: 'line',
encoding: {
x: {field: 'Year', type: 'temporal'},
y: {field: '3 Pointers Made', type: 'quantitative'}
}
})
Insert cell
Insert cell
vl.markLine()
.data(nbaDataFixedTypes)
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ(vl.repeat('layer')).title('Field Goals Made'),
vl.color().datum(vl.repeat('layer')) // map color to the repeat field
)
.repeat(vl.layer(['3 Pointers Made', '2 Pointers Made']))
.render()
Insert cell
Insert cell
{
const plot = vl.markLine()
.data(nbaDataFixedTypes)
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ(vl.repeat('layer')).title('Field Goals Made'),
vl.color().datum(vl.repeat('layer')) // map color to the repeat field
)
.repeat(vl.layer(['3 Pointers Made', '2 Pointers Made']));

return printVegaLiteJSON(plot, false);
}
Insert cell
Insert cell
vegalite({
width: 400, height: 300,
data: {values: nbaDataFixedTypes},
repeat: {layer: ['3 Pointers Made', '2 Pointers Made']},
spec:{
mark: 'line',
encoding: {
x: {field: 'Year', type: 'temporal'},
y: {field: {repeat: 'layer'}, type: 'quantitative', title: 'Field Goals Made'},
color: {datum: {repeat: 'layer'}, type: 'nominal'}
}
}
})
Insert cell
Insert cell
vl.markPoint({tooltip: true})
.data(nbaDataFixedTypes)
.encode(
vl.x().fieldQ('3 Pointers Attempted'),
vl.y().fieldQ('2 Pointers Attempted'),
vl.color().fieldQ('Year').timeUnit('year')
).render()
Insert cell
Insert cell
Insert cell
vl.markLine()
.data(nbaDataFixedTypes)
// Because our fields have spaces, we need to use bracket notation
// If our field names did not have spaces, we could write the following like
// datum.3PM / datum.3PA * 100
// See https://stackoverflow.com/a/64703327/388117
.transform({calculate: "datum['3 Pointers Made']/datum['3 Pointers Attempted'] * 100", as:'3-Pt Percentage'})
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ('3-Pt Percentage') // Graph the 3-pt percentage
).render()
Insert cell
vl.markLine()
.data(nbaDataFixedTypes)
// because our fields have spaces, we need to use bracket notation
// See https://stackoverflow.com/a/64703327/388117
.transform(
{calculate: "datum['3 Pointers Made']/datum['3 Pointers Attempted'] * 100", as:'3-Pt Percentage'},
{calculate: "datum['2 Pointers Made']/datum['2 Pointers Attempted'] * 100", as:'2-Pt Percentage'})
.encode(
vl.x().fieldT('Year'),
vl.y().fieldQ(vl.repeat('layer')).title("Field Goal Percentage"), // Graph the 3-pt percentage
vl.color().datum(vl.repeat('layer')) // map color to the repeat field
)
.repeat(vl.layer(['3-Pt Percentage', '2-Pt Percentage']))
.render()
Insert cell
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