Public
Edited
Feb 17
Insert cell
Insert cell
import {vl} from "@vega/vega-lite-api-v5"
Insert cell
Insert cell
weather = FileAttachment("weather-1@4.csv").csv()
Insert cell
import {printTable} from '@uwdata/data-utilities'
Insert cell
printTable(weather.slice(0,10))
Insert cell
Insert cell
vl.markPoint({size:70})
.data(weather)
.transform(
vl.groupby('station','elevation')
.aggregate(
vl.sum('PRCP').as('total_precipitation')
)
)
.encode(
vl.x().fieldQ('elevation').title('Elevation'),
vl.y().fieldQ('total_precipitation').title('Total Precipitation'),
vl.tooltip().fieldN('station'),
vl.opacity().value(0.5)
)
.title('Elevation vs Total Precipitation by Station')
.width(800)
.height(400)
.render()
Insert cell
Insert cell
vl.markPoint({size:70})
.data(weather)
.transform(
vl.groupby('station','elevation')
.aggregate(
vl.sum('SNOW').as('total_snow')
),
vl.filter('datum.total_snow > 0')
)
.encode(
vl.x().fieldQ('elevation'),
vl.y().fieldQ('total_snow'),
vl.tooltip().fieldN('station'),
vl.opacity().value(0.5)
)
.width(800)
.height(400)
.render()
Insert cell
{
const brush = vl.selectInterval()
.encodings('x');

const plot1 = vl.markBar()
.data(weather)
.params(brush)
.encode(
vl.x().fieldQ('elevation').bin({maxbins:40}).title('Elevation'),
vl.y().count().title('Frequency'),
vl.color().value('#4B9E66')
)
.width(750)
.height(300)
;
const plot2 = vl.markCircle({size:50})
.data(weather)
.transform(
vl.groupby('station','elevation')
.aggregate(
vl.sum('SNOW').as('total_snow'),
vl.sum('PRCP').as('precipitation')
),
)
.encode(
vl.x().fieldQ('precipitation').title('Total Precipitation'),
vl.y().fieldQ('total_snow').title('Total Snowfall'),
vl.color().value('#4B9E66'),
vl.opacity().if(brush, vl.value(0.75)).value(0.05),
vl.tooltip().fieldN(['station','elevation'])
)
.width(750)
.height(500)
;

return vl.vconcat(plot1,plot2).title('Station Elevation and Precipitation').render()
}
Insert cell
Insert cell
Insert cell
vl.markBar()
.data(weather)
.transform(
vl.groupby('Month')
.aggregate(
vl.mean('AWND').as('avg_wind')
)
)
.encode(
vl.x().fieldN('Month').sort(['January','February','March','April','May','June','July','August','September']),
vl.y().fieldQ('avg_wind').title('Average Wind Speed')
)
.title('Wind Speeds by Month')
.width(600)
.height(400)
.render()

Insert cell
Insert cell
vl.markCircle({size:100})
.data(weather)
.transform(
vl.groupby('Month','state')
.aggregate(
vl.mean('AWND').as('avg_wind')
),
//vl.filter("datum.avg_wind >= 8")
)
.encode(
vl.x().fieldN('Month').sort(['January','February','March','April','May','June','July','August','September']),
vl.y().fieldQ('avg_wind').title('Average Wind Speed'),
vl.tooltip('state'),
vl.opacity().value(0.4)
)
.title('Average Wind Speed by State for each Month')
.width(600)
.height(400)
.render()

Insert cell
Insert cell
vl.markBar()
.data(weather)
.transform(
vl.groupby('Month','station')
.aggregate(
vl.mean('AWND').as('avg_wind'),
),
)
.encode(
vl.x().fieldQ('avg_wind').bin({maxbins:20}).title('Average Wind Speed'),
vl.y().count('station').title('Frequency'),
vl.column('Month').sort(['January','February','March','April','May','June','July','August','September']).header({labelFontSize:14}),
vl.color().fieldN('Month').sort(['January','February','March','April','May','June','July','August','September'])
)
.title('Histogram of Average Wind Speeds by Month')
.width(600)
.height(400)
.render()

Insert cell
Insert cell
station_nm = ['ALBUQUERQUE INTL AP','Bateman','CARLSBAD CAVERN CITY AP','CLAYTON MUNI AIR PK','CLINES CORNERS','DEMING MUNI AP',
'FARMINGTON RGNL AP','GALLUP MUNI AP','Hopewell','LAS VEGAS MUNI AP','North Costilla','RATON MUNI CREWS AP','ROSWELL IND AIR PK',
'SANTA FE CO MUNI AP','Santa Fe','Senorita Divide #2','TRUTH OR CONSEQUENCE AP','TUCUMCARI MUNI AP','Taos Powderhorn',
'Tres Ritos','Wesner Springs']
Insert cell
{
const selection = vl.selectPoint('Selection')
.init({station: station_nm[0]})
.fields('station')
.bind(vl.menu(station_nm));

return vl.markCircle()
.data(weather)
.params(selection)
.transform(
vl.filter("datum.state == 'NM'"),
vl.filter("datum.AWND > 0")
)
.encode(
vl.x().fieldT('Date'),
vl.y().fieldQ('AWND').title('Wind Speed'),
vl.color().if(selection,vl.fieldN('station')).value('grey'),
vl.opacity().if(selection,vl.value(0.6)).value(0.05)
)
.title('New Mexico Wind Speeds by Station')
.width(600)
.height(400)
.render()
}
Insert cell
Insert cell
Insert cell
vl.markBar()
.data(weather)
.encode(
vl.x().mean('PRCP').title('Average Precipitation'),
vl.y().fieldN('state').sort({field:'PRCP',op:'mean',order:'descending'}).title('State'),
vl.color().value("#32567E")
)
.title('Average Precipitation by State')
.render()
Insert cell
Insert cell
{
const brush = vl.selectInterval()
.encodings('x');

const plot1 = vl.markBar()
.data(weather)
.params(brush)
.transform(
vl.groupby('latitude','longitude')
.aggregate(
vl.sum('PRCP').as('Total_PRCP')
),
)
.encode(
vl.x().fieldQ('Total_PRCP').bin({maxbins:40}).title('Total Precipitation'),
vl.y().count().title('Frequency'),
vl.color().value("#32567E")
)
.width(750)
.height(300)
;

const plot2 = vl.markCircle({size:40})
.data(weather)
.transform(
vl.groupby('latitude','longitude')
.aggregate(
vl.sum('PRCP').as('Total_PRCP')
),
)
.encode(
vl.x().fieldQ('longitude').scale({domain:[-125,-60],clamp:true}).title('Latitude'),
vl.y().fieldQ('latitude').scale({domain:[25,50],clamp:true}).title('Longitude'),
vl.color().fieldQ('Total_PRCP').scale({
"domain": [0,20,25,30,150],
"range": ["#32567E",'#A1C1E6',"#ffffff",'#F0B6A0',"#C03C3C"] // ["#003156","#ffffff","#470000"]
,reverse:true}),
vl.opacity().if(brush,vl.value(0.75)).value(0.05)
)
.width(750)
.height(500)
;

return vl.vconcat(plot1,plot2).title('Precipitation by Geography for the Continental US').render()
}


Insert cell
Insert cell
Insert cell
{
const plot1 = vl.markBar()
.data(weather)
.transform(
vl.groupby('station','state')
.aggregate(
vl.min('TMIN').as('Coldest_temp')
),
//vl.filter("datum.state == 'ME'"),
vl.filter('datum.Coldest_temp < -12')
)
.encode(
vl.x().fieldQ('Coldest_temp').title('Low Temperature'),
vl.y().fieldN('station').sort({field:'Coldest_temp',order:'descending'}).title('Station'),
vl.color().value('#575CA5'),
vl.tooltip('state')
)
.title('Stations with the Coldest Observed Temperatures')
.width(400)
.height(600)
;

const plot2 = vl.markBar()
.data(weather)
.transform(
vl.groupby('station','state')
.aggregate(
vl.min('TMAX').as('Hottest_temp')
),
vl.filter('datum.Hottest_temp > 100.5')
)
.encode(
vl.x().fieldQ('Hottest_temp').title('High Temperature'),
vl.y().fieldN('station').sort({field:'Hottest_temp',order:'descending'}).title('Station'),
vl.color().value('#DA563C'),
vl.tooltip('state')
)
.title('Stations with the Hottest Observed Temperatures')
.width(400)
.height(600)
;
return vl.hconcat(plot1,plot2).render()
}

Insert cell
Insert cell
{
const brush = vl.selectInterval()
.encodings('x');

const plot1 = vl.markBar()
.data(weather)
.params(brush)
.transform(
vl.groupby('latitude','longitude')
.aggregate(
vl.mean('TAVG').as('mean_temp')
),
)
.encode(
vl.x().fieldQ('mean_temp').bin({maxbins:40}).title('Mean Temperature'),
vl.y().count().title('Frequency'),
vl.color().fieldQ('mean_temp').scale({
"domain":[18,44,84],
"range": ['#575CA5','#FFFFFF','#DA563C']
}
))
.width(750)
.height(300)
;


const plot2 = vl.markCircle({size:40})
.data(weather)
.transform(
vl.groupby('latitude','longitude')
.aggregate(
vl.mean('TAVG').as('mean_temp')
),
)
.encode(
vl.x().fieldQ('longitude').scale({domain:[-125,-60],clamp:true}).title('Longitude'),
vl.y().fieldQ('latitude').scale({domain:[25,50],clamp:true}).title('Latitude'),
vl.color().fieldQ('mean_temp').scale({
"domain":[18,44,84],
"range": ['#575CA5','#FFFFFF','#DA563C']
}
),
vl.opacity().if(brush, vl.value(0.75)).value(0.05)
)
.width(750)
.height(500)
;

return vl.vconcat(plot1,plot2).title('Mean Temperature by Geography').render()
}
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