Public
Edited
Jan 14, 2024
Insert cell
Insert cell
Insert cell
workbook = FileAttachment("TFL Bus Safety@1.xlsx").xlsx()
Insert cell
Insert cell
// Data Cleaning
londonBusIncidents.forEach(d => {
if (d['Victim Category'] === 'Conductor') {d['Victim Category'] = 'Bus Driver'}
if (d['Victim Category'] === 'Member Of Public') {d['Victim Category'] = 'Pedestrian'}
if (d['Victim Category'] === 'Non-Operational Staff') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'Operational Staff') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'Contractor Staff') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'TfL Staff') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'Operations staff (other)') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'Contractor Staff') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'Insufficient Data') {d['Victim Category'] = 'Other'}
if (d['Victim Category'] === 'MotorCyclist') {d['Victim Category'] = 'Motorcyclist'}
if (d['Victim Category'] === '3rd Party driver / Occupant') {d['Victim Category'] = "Another Vehicle's ocuppant"}

if (d['Borough'] === 'Richmond Upon Thames') { d['Borough'] = 'Richmond upon Thames' }
if (d['Borough'] === 'Hammersmith & Fulham') { d['Borough'] = 'Hammersmith and Fulham' }
if (d['Borough'] === 'Kensington & Chelsea') { d['Borough'] = 'Kensington and Chelsea' }
if (d['Borough'] === 'Barking & Dagenham') { d['Borough'] = 'Barking and Dagenham' }
})
Insert cell
londonBusIncidentsDataframe = aq.from(londonBusIncidents)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
height: 150,
color: {
domain: ["Accidents", "Injured Individuals"],
range: ["#DC4743", "lightgray"]
},
marks: [
Plot.areaY(incidentsInjuriesFold, {
x: "Date Of Incident",
y1: "Count", // area chart is stacked by default, so we use y1 instead of y to avoid this.
fill: "Type",
tip: true,
}),
Plot.gridX({interval: "month", stroke: "white", strokeOpacity: 0.1})
]
})
Insert cell
injuriesSeverity = londonBusIncidentsDataframe.groupby("Injury Result Description").count()
Insert cell
injuriesSeverity.view()
Insert cell
Insert cell
Plot.plot({
height: 400,
width: 395,
marginLeft: -40,
y: { label:null, ticks: [] }, // to hide the y-axis
x: {
label: null,
padding: 0.4,
tickFormat: (x) => injuriesCategories[x]
},
color: {
domain: Object.keys(injuriesCategories),
range: ["lightgray", "#DC4743", "lightgray", "#DC4743"]
},
marks: [
Plot.barY(injuriesSeverity, {
x: "Injury Result Description",
y: "count",
fill: "Injury Result Description",
sort: { x: "y", reverse: true }
}),
Plot.text(injuriesSeverity, {
x: "Injury Result Description",
y: "count",
text: (d) => d.count,
dy: -6,
})
]
})
Insert cell
accidentsByYear = londonBusIncidentsDataframe
.groupby("Year", "Victim Category")
.count({as: "YearTotal"})
Insert cell
accidentsByYear.view()
Insert cell
accidentsByYear.groupby('Victim Category').pivot("Year", "YearTotal").view()
Insert cell
londonBusIncidentsDataframe.groupby('Victim Category').count().view()
Insert cell
Insert cell
viewof dasharray = Inputs.range([0,100])
Insert cell
viewof dy = Inputs.range([-100,100])
Insert cell
viewof dx = Inputs.range([-100,100])
Insert cell
viewof marginLeft = Inputs.range([-100, 100])
Insert cell
Plot.plot({
height: 600,
width: 400,
marginLeft: 25,
x: { ticks: [], label: null },
y: { ticks: [], inset: 0, label: null },
fy: { padding: 0 },
facet: {
label: null
},
marks: [
// Plot.frame(),
Plot.axisFy({ anchor: "left", dy: 28, dx: -15, textAnchor: "start" }),
Plot.image(images, {
x: 2014.5,
fy: "Victim Category",
src: "url",
width: 40
}),
Plot.line(accidentsByYear, {
x: "Year",
y: "YearTotal",
fy: "Victim Category",
frameAnchor: "left",
stroke: (d) =>
d["Victim Category"] === "Passenger" ? "#DC4743" : "#B9BDBD",
strokeWidth: 3,
sort: { fy: "y", reduce: "max", order: "descending" }
}),
Plot.ruleX([2017], {
stroke: "#B9BDBD",
strokeDasharray: "4, 4",
opacity: 0.5
}),
Plot.dot(accidentsByYear, {
x: (d) => {
return d.Year === 2017 ? d.Year : null;
},
y: "YearTotal",
stroke: (d) => {
return d.Year === 2017 && d["Victim Category"] === "Passenger"
? "#DC4743"
: "#B9BDBD";
},
fill: (d) => {
return d.Year === 2017 && d["Victim Category"] === "Passenger"
? "#DC4743"
: "#B9BDBD";
},
fy: "Victim Category"
}),
Plot.ruleY([0], { stroke: "#B9BDBD", strokeDasharray: "1, 2" }),
Plot.text(accidentsByYear, {
x: (d) => {
return d.Year === 2015 || d.Year === 2017 ? d.Year : null;
},
y: "YearTotal",
fy: "Victim Category",
text: "YearTotal",
frameAnchor: "top",
dy: 10
})
]
})
Insert cell
london = FileAttachment("londonBoroughs.json").json()
Insert cell
statemesh = topojson.mesh(london, london.objects.boroughs)
Insert cell
states = topojson.feature(london, london.objects.boroughs).features
Insert cell
accidentsByBourough1 = londonBusIncidentsDataframe.groupby("Borough").count()
Insert cell
accidentsByBorough.view()
Insert cell
// yearlyAccidentsByBorough = accidentsByBourough.groupby("Borough").pivot("Year", "count")
Insert cell
// yearlyAccidentsByBorough.view()
Insert cell
// yearlyAccidentsByBorough.filter(d => d.Borough === 'City of London').column(2017).get(0)
Insert cell
viewof selectedYear = Inputs.select(years, {value: ""})
Insert cell
viewof selectedBusRoute = Inputs.select(busRoutes, {value: "All Rotues"})
Insert cell
viewof selectedVictimCategory = Inputs.select(victimCategories, {value: ""})
Insert cell
viewof selectedOperator = Inputs.select(operators, {value: ""})
Insert cell
londonBusIncidentsDataframe.view()
Insert cell
Insert cell
accidentsByBorough = londonBusIncidentsDataframe
.params({
route: selectedBusRoute,
year: selectedYear,
victim: selectedVictimCategory,
operator: selectedOperator
})
// .filter((d, $) => {
// return d.Route === 1
// })
// .filter((d, $) =>
// ($.route !== "All Routes" ? d.Route === $.route : true) &&
// ($.year !== "All Years" ? d.Year === $.year : true) &&
// ($.operator !== "All Operators" ? d.Operator === $.operator : true) &&
// ($.victim !== "All Categories" ? d["Victim Category"] === $.victim : true)
// )
.groupby("Borough")
.count()
Insert cell
accidentsByBoroughMap = new Map(accidentsByBorough.objects().map(({Borough, count}) => [Borough, count]))
Insert cell
Plot.plot({
width: 600,
height: width * 0.4,
color: {
range: ["#FFFFFF", "#F2F2F2", "#E5E5E5", "#DA9D9B", "#DB605D", "#DC241F"],
type: "linear",
legend: true
},
projection: {
type: "mercator",
domain: statemesh
},
marks: [
Plot.geo(
states,
Plot.centroid({
strokeOpacity: 0.7,
stroke: "gray",
fill: (d) => accidentsByBoroughMap.get(d.id),
title: (d) => {
return `Borough: ${d.id}\n Accidents: ${accidentsByBoroughMap.get(d.id)}`
},
tip: true
})
)
]
})
Insert cell
busRoutes = ["All Routes", ...londonBusIncidentsDataframe.select("Route").dedupe("Route").array("Route").sort(sortAlphaNum)];
Insert cell
operators = ["All Operators", ...londonBusIncidentsDataframe.select("Operator").dedupe("Operator").array("Operator").sort()]
Insert cell
years = ["All Years", ...londonBusIncidentsDataframe.select("Year").dedupe("Year").array("Year").sort()]
Insert cell
victimCategories = ["All Categories", ...londonBusIncidentsDataframe.select("Victim Category").dedupe("Victim Category").array("Victim Category").sort()]
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