Insert cell
Insert cell
import { aq, op } from '@uwdata/arquero'
Insert cell
embed = require("vega-embed@5")
Insert cell
vegalite = require("@observablehq/vega-lite@0.1")
Insert cell
Insert cell
viewof accidents_de_voiture_chicago = aq // viewof shows the table view, but assigns the table value
.fromCSV(await FileAttachment('car_crashes_chicago@7.csv').text())
.view({ height: 240 })
Insert cell
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
width: 500,
height: 500,
data: {url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json",
format: {type: "topojson", feature: "chicago_sides"} // on doit indiquer quels objets on va dessiner
},
projection: {type :"mercator" },
mark: {
type: "geoshape"
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
accidents_par_heure_jour = accidents_de_voiture_chicago
.groupby("heure", "jour")
.count()
.rename({ count: "accidents_count" })
.orderby("heure", "jour")
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: { values: accidents_par_heure_jour.objects() },
mark: { type: "rect" },
encoding: {
x: {
field: "heure",
title: "Heure de la journée",
bin: { maxbins: 24 }, // Regrouper par heure
type: "ordinal"
},
y: {
field: "jour",
title: "Jour de la semaine",
type: "ordinal"
},
color: {
field: "accidents_count",
type: "quantitative",
title: "Nombre d'accidents",
scale: { scheme: "reds" }
},
tooltip: [
{ field: "heure", title: "Heure" },
{ field: "jour", title: "Jour" },
{ field: "accidents_count", title: "Accidents" }
]
},
width: 600,
height: 300
})
Insert cell
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: { values: accidents_de_voiture_chicago.objects() },
mark: { type: "bar" },
encoding: {
x: {
field: "conditions_atmospheriques",
title: "Conditions météo",
axis: { labelAngle: 40 } // Incliner les étiquettes avec angle
},
y: {
aggregate: "count",
title: "Nombre d'accidents"
},
color: {
field: "conditions_atmospheriques",
title: "Météo",
scale: { scheme: "category10" } // Palette de couleurs
},
tooltip: [
{ field: "conditions_atmospheriques" },
{ aggregate: "count", title: "Accidents" }
]
},
width: 600,
height: 400
})
Insert cell
Insert cell
Insert cell
Insert cell
// préparation des données
accidents_filtres = accidents_de_voiture_chicago
.filter(d => op.equal(d.hit_and_run, "Y") || op.equal(d.hit_and_run, "N"))
.groupby("hit_and_run")
.count()
.derive({
pourcentage: d => op.round(d.count / op.sum(d.count) * 100, 1)
})
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: { values: accidents_filtres.objects() },
mark: { type: "arc", outerRadius: 100 },
encoding: {
theta: {
field: "count",
title: "Pourcentage d'accidents",
type: "quantitative"
},
color: {
field: "hit_and_run",
title: "Départ de fuite",
scale: {
domain: ["Y", "N"],
range: ["orange", "green"]
}
},
tooltip: [
{ field: "hit_and_run", title: "Catégorie" },
{ field: "count", title: "Accidents" },
{ field: "pourcentage", title: "Pourcentage"}
]
},
width: 300,
height: 300
})
Insert cell
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: { values: accidents_de_voiture_chicago.objects() },
mark: { type: "bar", opacity: 0.8 },
encoding: {
x: {
field: "vitesse",
bin: { maxbins: 20 },
title: "Vitesse (mph)"
},
y: { aggregate: "count", title: "Nombre d'accidents" },
color: {
field: "hit_and_run",
title: "Départ de fuite",
scale: { range: ["red", "green", "blue"] }
}
},
width: 600,
height: 300
})
Insert cell
Insert cell
// Préparer les données
donnees_radar_long = accidents_de_voiture_chicago
.groupby("Side", "heure")
.count()
.rename({ count: "accidents" })
Insert cell
embed({
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": { "values": donnees_radar_long.objects() },
"mark": "area",
"encoding": {
"x": { "field": "heure", "type": "quantitative", "title": "Heure" },
"y": { "field": "accidents", "type": "quantitative", "stack": "center", "title": "Nombre d'accidents" },
"color": { "field": "Side", "type": "nominal", "scale": { "scheme": "category20b" } }
},
"width": 700,
"height": 400
})
Insert cell
Insert cell
// Préparation des données
accidents_groupes = aq.from(accidents_de_voiture_chicago.objects())
.groupby("conditions_atmospheriques", "conditions_luminosite")
.rollup({ nb_accidents: op.count() })
.objects()
Insert cell
embed({
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
width: 600,
height: 400,
data: { values: accidents_groupes },
mark: "bar",
encoding: {
x: { field: "conditions_atmospheriques", type: "nominal", title: "Conditions météo" },
y: { field: "nb_accidents", type: "quantitative", title: "Nombre d'accidents" },
color: { field: "conditions_luminosite", type: "nominal", title: "Luminosité" },
tooltip: [
{ field: "conditions_atmospheriques", title: "Météo" },
{ field: "conditions_luminosite", title: "Luminosité" },
{ field: "nb_accidents", title: "Accidents" }
]
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Compter le nombre d'accidents par quartier (La colonne "Side")
accidents_par_quartier = accidents_de_voiture_chicago
.groupby("Side")
.count()
.orderby(("count"))
.rename({ count: "Nombre_d_accidents"})
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
data: { values: accidents_par_quartier.objects() },
mark: { type: "bar" },
encoding: {
x: {
field: "Side",
title: "Quartier",
sort: "-y", // <-- Tri Desc
axis: { labelAngle: 40 } // Incliner les étiquettes
},
y: {
field: "Nombre_d_accidents",
title: "Nombre d'accidents"
},
color: {
field: "Nombre_d_accidents",
type: "quantitative",
scale: {
scheme: "reds",
reverse: false // dégradé clair vers foncé
}
},
tooltip: [
{ field: "Side" },
{ field: "Nombre_d_accidents" }
]
},
width: 600,
height: 400
})
Insert cell
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
width: 700,
height: 600,
layer: [
// Fond de carte des quartiers
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "lightgray", stroke: "white" }
},
// Points d'accidents
{
data: { values: accidents_de_voiture_chicago.objects() },
mark: { type: "circle", color: "red", opacity: 1, size: 5 },
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" }
}
}
]
})
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
width: 700,
height: 600,
layer: [
// Fond de carte des quartiers
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "lightgray", stroke: "white" }
},
// Points d'accidents
{
data: { values: accidents_de_voiture_chicago.objects() },
mark: { type: "circle", color: "red", opacity: 1, size: 5 },
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" },
color: {field: "conditions_luminosite", type: "nominal"}
}
}
]
})
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
title: "Accidents par condition de luminosité",
width: 700,
height: 400,
data: { values: accidents_de_voiture_chicago.objects() },
facet: {
column: {
field: "conditions_luminosite",
title: "Condition de luminosité",
header: { labelAngle: 0, labelAlign: "center" }
}
},
spec: {
layer: [
// Fond de carte
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "lightgray", stroke: "white" },
projection: { type: "mercator" }
},
// Points d'accidents
{
mark: {
type: "circle",
opacity: 0.7,
size: 8,
color: "#e41a1c"
},
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" }
}
}
]
},
columns: 3
})
Insert cell
Insert cell
Insert cell
FileAttachment("vitesse_accidents_3D_Kepler.JPG").image()
Insert cell
Insert cell
{
const url = await FileAttachment("gif_accodents_vitesse_date.gif").url();
return html`<iframe src=${url} width=500 height=285></iframe>`;
}
Insert cell
Insert cell
FileAttachment("accidents-vitesse-qgis.png").image()
Insert cell
FileAttachment("accidents-vitesse-qgis2@1.png").image()
Insert cell
FileAttachment("accidents-vitesse-qgis3.png").image()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
embed({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
width: 700,
height: 400,
hconcat: [
// Carte Y - Rougea
{
layer: [
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "#f0f0f0", stroke: "white" },
projection: { type: "mercator" }
},
{
data: { values: accidents_de_voiture_chicago.objects() },
transform: [ { filter: "datum.hit_and_run === 'Y'" } ],
mark: { type: "circle", color: "red", size: 6 },
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" }
}
}
],
title: "Délits de fuite (Y)"
},
// Carte N - Bleu
{
layer: [
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "#f0f0f0", stroke: "white" },
projection: { type: "mercator" }
},
{
data: { values: accidents_de_voiture_chicago.objects() },
transform: [ { filter: "datum.hit_and_run === 'N'" } ],
mark: { type: "circle", color: "blue", size: 6 },
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" }
}
}
],
title: "Pas de délit de fuite (N)"
},
// Carte NaN - Gris
{
layer: [
{
data: { url: "https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json", format: { type: "topojson", feature: "chicago_sides" } },
mark: { type: "geoshape", fill: "#f0f0f0", stroke: "white" },
projection: { type: "mercator" }
},
{
data: { values: accidents_de_voiture_chicago.objects() },
transform: [ { filter: "!datum.hit_and_run || (datum.hit_and_run !== 'Y' && datum.hit_and_run !== 'N')" } ],
mark: { type: "circle", color: "gray", size: 6 },
encoding: {
longitude: { field: "LONGITUDE" },
latitude: { field: "LATITUDE" }
}
}
],
title: "Données manquantes (NaN)"
}
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// defini bertin
bertin = require("bertin@latest")
Insert cell
// Charger le JSON des quartiers de Chicago
chicagoGeo = await fetch("https://mjlobo.github.io/teaching/mde/data/chicagosideswithid.json")
.then(res => res.json())
Insert cell
accidentsPoints = ({
type: "FeatureCollection",
features: accidents_de_voiture_chicago.objects().map(d => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [+d.LONGITUDE, +d.LATITUDE]
},
properties: {
CONDITIONS_METEO: d.conditions_atmospheriques,
CONDITIONS_LUMIERE: d.conditions_luminosite
}
}))
})
Insert cell
// Dessiner la carte de points avec Bertin.js
map4 = bertin.draw({
params: { projection: d3.geoMercator()},
layers: [
{
geojson: accidentsPoints,
type: "layer",
fill: "red", stroke: "white", strokewidth: 0.4, fillopacity: 0.7,
tooltip: ["CONDITIONS_METEO:", "$CONDITIONS_METEO","CONDITIONS_LUMIERE:", "$CONDITIONS_LUMIERE"]

},
{
geojson: chicagoGeo,
type: "layer",
fill: "lightblue", stroke: "black", strokewidth: 0.5
}
]
})

Insert cell
Insert cell
// Séparer les accidents de jour et de nuit via Arquero
dayAccidents = accidents_de_voiture_chicago.filter(d => d.conditions_luminosite === "DAYLIGHT")
Insert cell
nightAccidents = accidents_de_voiture_chicago.filter(d => d.conditions_luminosite == "DARKNESS")
Insert cell
dayPoints = ({
type: "FeatureCollection",
features: dayAccidents.objects().map(d => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [+d.LONGITUDE, +d.LATITUDE]
},
properties: {
conditions_atmospheriques: d.conditions_atmospheriques,
vitesse: d.vitesse
}
}))
})

Insert cell
nightPoints = ({
type: "FeatureCollection",
features: nightAccidents.objects().map(d => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [+d.LONGITUDE, +d.LATITUDE]
},
properties: {
conditions_atmospheriques: d.conditions_atmospheriques,
vitesse: d.vitesse
}
}))
})
Insert cell
// Dessiner la carte comparative jour/nuit
mapjournuit = bertin.draw({
params: { projection: d3.geoMercator()},
layers: [
// Accidents de jour : points orange
{ geojson: dayPoints, type: "layer",
fill: "orange", stroke: "white", strokewidth: 0.5, fillopacity: 0.7,
tooltip: ["Accident journalier", "$conditions_atmospheriques", "$vitesse"]},
// Accidents de nuit : points bleu acier
{ geojson: nightPoints, type: "layer",
fill: "steelblue", stroke: "white", strokewidth: 0.5, fillopacity: 0.7,
tooltip: ["accident de nuit", "$conditions_atmospheriques", "$vitesse"] },
// Fond : quartiers de Chicago
{ geojson: chicagoGeo, type: "layer",
fill: "lightblue", stroke: "black", strokewidth: 0.5}
]
})
Insert cell
Insert cell
// Dessiner la carte comparative jour
mapjour = bertin.draw({
params: { projection: d3.geoMercator()},
layers: [
// Accidents de jour : points orange
{ geojson: dayPoints, type: "layer",
fill: "orange", stroke: "white", strokewidth: 0.5, fillopacity: 0.7,
tooltip: ["Accident journalier", "$conditions_atmospheriques", "$vitesse"]},
// Fond : quartiers de Chicago
{ geojson: chicagoGeo, type: "layer",
fill: "lightblue", stroke: "black", strokewidth: 0.5}
]
})
Insert cell
// Dessiner la carte comparative jour/nuit
mapnuit = bertin.draw({
params: { projection: d3.geoMercator()},
layers: [
// Accidents de nuit : points bleu acier
{ geojson: nightPoints, type: "layer",
fill: "steelblue", stroke: "white", strokewidth: 0.5, fillopacity: 0.7,
tooltip: ["accident de nuit", "$conditions_atmospheriques", "$vitesse"] },
// Fond : quartiers de Chicago
{ geojson: chicagoGeo, type: "layer",
fill: "lightblue", stroke: "black", strokewidth: 0.5}
]
})
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