Public
Edited
Apr 21
Insert cell
Insert cell
Insert cell
Insert cell
import {vl} from "@vega/vega-lite-api-v5"
Insert cell
football = FileAttachment("football_results_project@2.csv").csv()
Insert cell
import {printTable} from '@uwdata/data-utilities'
Insert cell
printTable(football.slice(0,10))
Insert cell
vl.markCircle({size:70})
.data(football)
.transform(
vl.groupby('team','continent_name')
.aggregate(
vl.sum('score').as('goals_scored'),
vl.sum('opponent_score').as('goals_conceded'),
vl.count().as('total_games')
)
)
.encode(
vl.x().fieldQ('goals_scored').title('Goals Scored'),
vl.y().fieldQ('goals_conceded').title('Goals Conceded'),
vl.tooltip().fieldN('team'),
vl.size().fieldQ('total_games'),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}), //Tableau 10 Color Pallete - Keep colors consistent for each continent,
vl.opacity().value(0.5)
)
.title('Goals Scored and Conceded by Country')
.width(800)
.height(400)
.render()
Insert cell
{
const hover = vl.selectPoint('hover')
.encodings('x')
.on('mouseover')
.toggle(false)
.nearest(true);
const isHovered = hover.empty(false);

const plot2 = vl.markLine()
.data(football)

.encode(
vl.x().fieldT('year').title('Year'),
vl.y().count().title('# of Football Matches'),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}), //Tableau 10 Color Pallete - Keep colors consistent for each continent,
vl.opacity().value(0.7)
)
.width(800)
.height(800)
.title('Trend of Football Matches by Continent')
;
const base = plot2.transform(vl.filter(isHovered));

const label = {align: 'left', dx: 5, dy: -5};
const white = {stroke: 'white', strokeWidth: 2};


return vl.data(football)
.layer(
plot2,
vl.markRule({color: '#aaa'})
.transform(vl.filter(isHovered))
.encode(vl.x().fieldT('year')),
plot2.markCircle()
.params(hover)
.encode(vl.opacity().if(isHovered, vl.value(1)).value(0)),
base.markText(label, white).encode(vl.text().count()),
base.markText(label).encode(vl.text().count()),
)
.width(800)
.height(600)
.render()
}
Insert cell
continents = ['Europe','South America','North America','Africa','Asia','Oceania']
Insert cell
Insert cell
{
const brush = vl.selectInterval()
.encodings('x');

const continent = vl.selectPoint('Selection')
.fields('continent_name');

const plot1 = vl.markLine()
.data(football)
.params(brush,continent)
.encode(
vl.x().fieldT('year').title('Year'),
vl.y().count().title('# of Football Matches'),
vl.color().fieldN('continent_name'),
vl.opacity().if(continent,vl.value(0.75)).value(0.05),
vl.tooltip().fieldN('continent_name'),
vl.size().value(4)
)
.width(720)
.height(400)
.title('Trend of Football Matches by Continent')
;

const plot2 = vl.markCircle({size:70})
.data(football)
.params(continent)
.transform(
vl.filter(brush),
vl.groupby('team','continent_name')
.aggregate(
vl.sum('score').as('goals_scored'),
vl.sum('opponent_score').as('goals_conceded'),
vl.count().as('total_games')
)
)
.encode(
vl.x().fieldQ('goals_scored').title('Goals Scored'),
vl.y().fieldQ('goals_conceded').title('Goals Conceded'),
vl.tooltip(['team','goals_scored','goals_conceded']),
vl.size().fieldQ('total_games'),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}), //Tableau 10 Color Pallete - Keep colors consistent for each continent,
vl.opacity().if(continent,vl.value(0.75)).value(0.05)
)
.title('Goals Scored and Conceded by Country')
.width(720)
.height(300);



return vl.vconcat(plot1,plot2
).render()
}
Insert cell
Insert cell
{
const brush = vl.selectInterval()
.encodings('x');

const continent = vl.selectPoint('Selection')
.fields('continent_name');

const plot1 = vl.markLine()
.data(football_gdp)
.params(brush,continent)
.encode(
vl.x().fieldT('year').title('Year'),
vl.y().count().title('# of Football Matches'),
vl.color().fieldN('continent_name'),
vl.opacity().if(continent,vl.value(0.75)).value(0.05),
vl.tooltip().fieldN('continent_name'),
vl.size().value(4)
)
.width(720)
.height(400)
.title('Trend of Football Matches by Continent')
;

const plot2 = vl.markCircle({size:70})
.data(football_gdp)
.params(continent)
.transform(
vl.filter(brush),
vl.groupby('team','continent_name')
.aggregate(
vl.sum('score').as('goals_scored'),
vl.sum('opponent_score').as('goals_conceded'),
vl.median('gdp_per_capita').as('gdp_per_capita'),
vl.count().as('total_games')
),
vl.filter("datum.gdp_per_capita<=150000")
)
.encode(
vl.x().fieldQ('goals_scored').title('Goals Scored'),
vl.y().fieldQ('gdp_per_capita').title('GDP per Capita (2015 US$)').scale({domain: [0, 150000]}),
vl.tooltip(['team','goals_scored','gdp_per_capita']),
vl.size().fieldQ('total_games'),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}), //Tableau 10 Color Pallete - Keep colors consistent for each continent,
vl.opacity().if(continent,vl.value(0.75)).value(0.05)
)
.title('Goals Scored and Conceded by Country')
.width(720)
.height(300);



return vl.vconcat(plot1,plot2
).render()
}
Insert cell
Insert cell
{
const selection = vl.selectPoint('Select')
.fields('team');

return vl.markCircle({size:250})
.data(football_gdp)
.params(selection,[{"name":"selectyear","value":[1960],"bind":{"input":"range","min":1960,"max":2023,"step":1,"name":"Select year:"}}])
.transform(
vl.filter("datum.year==selectyear"),
//vl.filter("datum.tournament == FIFA World Cup"),
vl.calculate('datum.score - datum.opponent_score').as('diff'),
//vl.filter(selectyear),
vl.groupby('team','continent_name')
.aggregate(
vl.sum('score').as('goals_scored'),
vl.sum('opponent_score').as('goals_conceded'),
vl.sum('diff').as('goal_difference'),
vl.median('gdp_per_capita').as('gdp_per_capita'),
vl.count().as('total_games')
),
vl.filter("datum.gdp_per_capita<=150000"),
)
.encode(
vl.x().fieldQ('goal_difference').title('Goal Difference').scale({domain: [-70, 70]}),
vl.y().fieldQ('gdp_per_capita').title('GDP per Capita (2015 US$)').scale({domain: [0, 150000]}),
vl.tooltip(['team','goal_difference','goals_scored','goals_conceded','gdp_per_capita']),
//vl.size().fieldQ('total_games'),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}), //Tableau 10 Color Pallete - Keep colors consistent for each continent
vl.opacity().if(selection,vl.value(0.75)).value(0.05)
)
.title('Goal Difference and GDP Per Capita by Country')
.width(720)
.height(500)
.render()
}
Insert cell
{
const selection = vl.selectPoint('Select')
.fields('team');

return vl.markCircle({size:400})
.data(football_gdp)
.params(selection,[{"name":"selectyear","value":[1962],"bind":{"input":"range","min":1962,"max":2022,"step":4,"name":"Select year:"}}])
.transform(
vl.filter("datum.year==selectyear & datum.tournament == 'FIFA World Cup'"),
//vl.filter("datum.tournament == FIFA World Cup"),
vl.calculate('datum.score - datum.opponent_score').as('diff'),
//vl.filter(selectyear),
vl.groupby('team','continent_name')
.aggregate(
vl.sum('score').as('goals_scored'),
vl.sum('opponent_score').as('goals_conceded'),
vl.sum('diff').as('goal_difference'),
vl.median('gdp_per_capita').as('total_gdp'),
vl.count().as('total_games')
),
vl.filter("datum.total_gdp<=150000"),
)
.encode(
vl.x().fieldQ('goal_difference').title('Goal Difference').scale({domain: [-15, 15]}),
vl.y().fieldQ('total_gdp').title('GDP per Capita (2015 US$)').scale({domain: [0, 100000]}),
vl.tooltip(['team','goal_difference','goals_scored','goals_.conceded','total_gdp']),
vl.color().fieldN('continent_name').scale({domain:['Africa','Asia','Europe','North America','Oceania','South America'],range:["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b"]}),//Tableau10 colors, assign domain to keep colors consistent for each continent
vl.opacity().if(selection,vl.value(0.75)).value(0.1)
)
.title('Goal Difference and GDP Per Capita by Country (World Cup Games)')
.width(720)
.height(500)
.render()
}
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