Published
Edited
Feb 20, 2021
Insert cell
md`# Assignment: Visualization with a Partner`
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
d3 = require('d3')
Insert cell
import {printTable} from '@uwdata/data-utilities'
Insert cell
fileContents = FileAttachment("rollercosters_paired_assignment@1.csv")
Insert cell
df = d3.csvParse(await fileContents.text(), d3.autoType)
Insert cell
printTable(df.slice(0, 10))
Insert cell
md`**Are there correlations between nausea, intensity, and excitement and ride length and speed?**`
Insert cell
{
const naus = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('nausea').title('Nausea Rating'),
vl.y().fieldQ('ride_length').title('Ride Length'),
vl.color().fieldQ('avg_speed').scale({scheme:'lightgreyteal'}).legend({titleOrient: 'left'})
.title('Average Speed')
)
.width(250)
.height(250);
const ints = vl.markCircle()
//.data(df.filter(d => d.intensity !== 44.94)) I uploaded an updated version of the csv with the correction
.data(df)
.encode(
vl.x().fieldQ('intensity').title('Intensity Rating'),
vl.y().fieldQ('ride_length').title(null),
vl.color().fieldQ('avg_speed')
)
.width(250)
.height(250);
const exc = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('excitement').title('Excitement Rating'),
vl.y().fieldQ('ride_length').title(null),
vl.color().fieldQ('avg_speed')
)
.width(250)
.height(250);
return vl.hconcat(naus, ints, exc)
.title({
text: 'Nausea, Intensity, and Excitement by Ride Length and Average Speed',
anchor: 'middle',
fontSize:16
}).render();
}
Insert cell
{
const naus2 = vl.markCircle({'color':'#6495ED'})
.data(df2)
.encode(
vl.y().fieldQ('ride_length').title('Ride Length'),
vl.x().fieldQ('nausea').title('Ratings'),
vl.color({'datum':'Nausea'})
);
const exc2 = vl.markCircle()
.data(df2)
.encode(
vl.y().fieldQ('ride_length'),
vl.x().fieldQ('excitement'),
vl.color({'datum': 'Excitement'})
);
const ints2 = vl.markCircle()
.data(df2)
.encode(
vl.y().fieldQ('ride_length'),
vl.x().fieldQ('intensity'),
vl.color({'datum':'Intensity'})
);
const ratings_together = vl.layer(naus2, exc2, ints2)
.title({
text: 'Nausea, Excitement, and Intensity by Ride Length',
anchor: 'middle'
})
.width(250)
.height(250);
return ratings_together.render()
}
Insert cell
{
const ratings_matrix = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('intensity').axis({grid:false}),
vl.y().fieldQ('excitement'),
vl.color().fieldN('nausea_rating')
)
.width(250)
.height(250)
}
Insert cell
md`**On average, do rollercoasters with the fastest max speeds also have faster average speeds?**`
Insert cell
vl.data(df)
.transform({fold: ['avg_speed', 'max_speed']})
.encode(
vl.x().average('value').title('Speed').axis({grid:false}),
// vl.y({sort: {op: 'mean', field: 'max_speed', order: 'ascending'}}).fieldN("rollercoaster_type"),
vl.y({sort:['Hypercoaster', 'Vertical Drop Coaster', 'Twister Coaster', 'Inverted Roller Coaster',
'Compact Inverted Coaster','Looping Roller Coaster','Wooden Roller Coaster ',
'Corkscrew Roller Coaster','Mini Roller Coaster','Spiral Coaster', 'Wooden Wild Mouse',
'Mine Train Coaster','Dinghy Slide','Stand Up Roller Coaster']})
.fieldN("rollercoaster_type").title('Rollercoaster Type'),
vl.color().scale({scheme:'lightgreyteal'}).fieldN('key').legend({title: 'Avg vs Max Speed'})
)
.layer(
vl.markBar()
.transform({filter: "datum.key == 'max_speed'"}),
vl.markBar()
.transform({filter: "datum.key == 'avg_speed'"})
)
.width(700)
.height(350)
.title({text:'Average vs Max Speed by Rollercoaster Type', anchor:'center', fontSize:18})
.config({style:{cell:{stroke:'transparent'}}})
.render()
Insert cell
md`**Are custom roller coasters:**
- faster than non-custom?
- more exciting than non-custom?`
Insert cell
{
const colors = {
domain:['0', '1'],
range: ['#dc7b43','#c8bdb9']
};
const custSpeed = vl.markBar()
.data(df)
.encode(
vl.x().average('avg_speed').axis({grid:false}).title('Avg Speed'),
vl.y().fieldN('custom_design').title(null),
vl.color().fieldN('custom_design').scale(colors).legend({title: 'Custom Design'})
)
const custExcitement = vl.markBar()
.data(df)
.encode(
vl.x().average('excitement').axis({grid:false}).title('Excitement'),
vl.y().fieldN('custom_design').axis({title:'Custom Design', fontSize:20}),
vl.color().fieldN('custom_design').scale(colors)
)
const custIntensity = vl.markBar()
.data(df)
.encode(
vl.x().average('intensity').axis({grid:false}).title('Intensity'),
vl.y().fieldN('custom_design').title(null),
vl.color().fieldN('custom_design').scale(colors)
)
return vl.vconcat(custSpeed, custExcitement, custIntensity)
.title({text: 'Differences Between Custom and Non-Custom Rollercoaster Design',
fontSize:16, anchor: 'center', offset: 20})
.render()
}
Insert cell
df2 = df
Insert cell
dashboard = {
const naus = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('nausea').axis({grid:false}).title('Nausea Rating'),
vl.y().fieldQ('ride_length').title('Ride Length'),
vl.color().fieldQ('avg_speed').scale({scheme:'lightgreyteal'}).legend({orient:'left', titleOrient: 'left'})
.title('Average Speed')
)
.width(250)
.height(250);
const ints = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('intensity').axis({grid:false}).title('Intensity Rating'),
vl.y().fieldQ('ride_length').title(null),
vl.color().fieldQ('avg_speed')
)
.width(250)
.height(250);
const exc = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('excitement').axis({grid:false}).title('Excitement Rating'),
vl.y().fieldQ('ride_length').title(null),
vl.color().fieldQ('avg_speed')
)
.width(250)
.height(250);
const ratings_matrix = vl.markCircle()
.data(df)
.encode(
vl.x().fieldQ('intensity').axis({grid:false}).title('Intensity'),
vl.y().fieldQ('excitement').title('Excitement'),
vl.color().fieldN('nausea_rating').scale({scheme:'tableau20'}).title('Nausea Rating')
)
.width(250)
.height(250)
//avg vs max speed
const speed = vl.data(df)
.transform({fold: ['avg_speed', 'max_speed']})
.encode(
vl.x().average('value').title('Speed').axis({grid:false}),
// vl.y({sort: {op: 'mean', field: 'max_speed', order: 'ascending'}}).fieldN("rollercoaster_type"),
vl.y({sort:['Hypercoaster', 'Vertical Drop Coaster', 'Twister Coaster', 'Inverted Roller Coaster',
'Compact Inverted Coaster','Looping Roller Coaster','Wooden Roller Coaster ',
'Corkscrew Roller Coaster','Mini Roller Coaster','Spiral Coaster', 'Wooden Wild Mouse',
'Mine Train Coaster','Dinghy Slide','Stand Up Roller Coaster']})
.fieldN("rollercoaster_type").title('Rollercoaster Type'),
vl.color().scale({scheme:'lightgreyteal'}).fieldN('key').legend({orient:'right', title: 'Avg vs Max Speed'})
)
.layer(
vl.markBar()
.transform({filter: "datum.key == 'max_speed'"}),
vl.markBar()
.transform({filter: "datum.key == 'avg_speed'"})
)

.title({text:'Average vs Max Speed by Rollercoaster Type', anchor:'center', fontSize:16, offset: 20});
//custom vs non-custom
const colors = {
domain:['0', '1'],
range: ['#dc7b43','#c8bdb9']
};
const custSpeed = vl.markBar()
.data(df)
.encode(
vl.x().average('avg_speed').axis({grid:false}).title('Avg Speed'),
vl.y().fieldN('custom_design').title(null),
vl.color().fieldN('custom_design').scale(colors).legend({orient: 'right', title: 'Custom Design'})
);
const custExcitement = vl.markBar()
.data(df)
.encode(
vl.x().average('excitement').axis({grid:false}).title('Excitement'),
vl.y().fieldN('custom_design').axis({title:'Custom Design', fontSize:20}),
vl.color().fieldN('custom_design').scale(colors)
);

const custIntensity = vl.markBar()
.data(df)
.encode(
vl.x().average('intensity').axis({grid:false}).title('Intensity'),
vl.y().fieldN('custom_design').title(null),
vl.color().fieldN('custom_design').scale(colors)
);
return vl.vconcat(
ratings_matrix.title({
text: 'Relationship Between Excitement, Intensity, and Nausea',
anchor: 'middle',fontSize:16}
),
vl.hconcat(naus, ints, exc).title({
text: 'Nausea, Intensity, and Excitement by Ride Length and Average Speed',
anchor: 'middle',fontSize:16}),
speed,
vl.vconcat(custSpeed, custExcitement, custIntensity)
.title({text: 'Differences Between Custom and Non-Custom Rollercoaster Design',
fontSize:16, offset: 20})).config({style:{cell:{stroke:'transparent'}}}).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