--- title: Paradoxe de l’Animal Style toc: false --- # 🛸 Le Paradoxe de l’Animal Style > **Question absurde mais testable :** > Les OVNIs en Californie survolent-ils plus souvent des zones proches des In-N-Out ? ```js display(html` `); ``` ```js const [inNOut, ufoSightings] = await Promise.all([ FileAttachment("./data/in-n-out-ca-csv.json").json(), FileAttachment("./data/ufo-ca-sightings-v2.json").json(), ]); ``` ```js const [d3, topojson] = await Promise.all([ import("https://cdn.jsdelivr.net/npm/d3@7/+esm"), import("https://cdn.jsdelivr.net/npm/topojson-client@3/+esm"), ]); const usAtlasUrl = "https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json"; const us = await fetch(usAtlasUrl).then((r) => r.json()); const states = topojson.feature(us, us.objects.states); const california = states.features.find((s) => Number(s.id) === 6); ``` ```js function haversineKm(lat1, lon1, lat2, lon2) { const toRad = (deg) => (deg * Math.PI) / 180; const R = 6371; const dLat = toRad(lat2 - lat1); const dLon = toRad(lon2 - lon1); const a = Math.sin(dLat / 2) ** 2 + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2; return 2 * R * Math.asin(Math.sqrt(a)); } function nearestStore(ufo, stores) { let bestStore = null; let bestDistance = Infinity; for (const store of stores) { const distance = haversineKm( ufo.latitude, ufo.longitude, store.latitude, store.longitude, ); if (distance < bestDistance) { bestDistance = distance; bestStore = store; } } return { store: bestStore, distanceKm: bestDistance }; } ``` ```js const shapes = [ "all", ...d3 .sort(Array.from(new Set(ufoSightings.map((d) => d.shape || "unknown")))) .slice(0, 20), ]; const selectedShape = view( Inputs.select(shapes, { label: "Filtre de forme OVNI", value: "all", format: (d) => (d === "all" ? "Toutes les formes" : d), }), ); const hungerRadiusKm = view( Inputs.range([5, 80], { label: "Curseur de fringale extraterrestre (km)", value: 24, step: 1, }), ); const hexbinWidth = view( Inputs.range([8, 28], { label: "Largeur des hexagones radar", value: 14, step: 1, }), ); ``` ```js const filteredUfo = ufoSightings.filter((ufo) => selectedShape === "all" ? true : ufo.shape === selectedShape, ); const enrichedUfo = filteredUfo.map((ufo) => { const nearest = nearestStore(ufo, inNOut); return { ...ufo, nearestStoreId: nearest.store?.id ?? null, nearestStoreLat: nearest.store?.latitude ?? null, nearestStoreLon: nearest.store?.longitude ?? null, nearestDistanceKm: nearest.distanceKm, closeToBurger: nearest.distanceKm <= hungerRadiusKm, }; }); const hungerRate = enrichedUfo.length > 0 ? (enrichedUfo.filter((d) => d.closeToBurger).length / enrichedUfo.length) * 100 : 0; const byStore = d3.rollups( enrichedUfo, (rows) => ({ sightings: rows.length, avgDuration: d3.mean(rows, (d) => d.durationSeconds) ?? 0, medDistance: d3.median(rows, (d) => d.nearestDistanceKm) ?? 0, }), (d) => d.nearestStoreId, ); const storeHotspots = byStore .map(([storeId, stats]) => { const store = inNOut.find((d) => d.id === storeId); if (!store) return null; return { ...store, sightings: stats.sightings, avgDuration: stats.avgDuration, medDistance: stats.medDistance, }; }) .filter(Boolean) .sort((a, b) => b.sightings - a.sightings); const topHotspots = storeHotspots.slice(0, 12); ``` ```js display(html`
Dossier classifié: “Les zones de survol OVNI sont-elles alignées avec les territoires In-N-Out ?”
Apparitions OVNI (filtre actif)
${enrichedUfo.length.toLocaleString("fr-FR")}
In-N-Out en Californie
${inNOut.length.toLocaleString("fr-FR")}
Taux de faim extraterrestre
${hungerRate.toFixed(1)}%
Rayon de corrélation
${hungerRadiusKm} km
`); ``` ```js const map = Plot.plot({ width, height: 700, projection: { type: "albers", domain: california }, style: { background: "#0f0f0f", color: "#d8e1ff" }, color: { label: "Proximité burger", domain: ["≤ rayon", "> rayon"], range: ["#39FF14", "#00F3FF"], }, marks: [ Plot.geo(california, { fill: "#0f0f0f", stroke: "#303847", strokeWidth: 0.8, }), Plot.dot(enrichedUfo, { x: "longitude", y: "latitude", r: (d) => (d.closeToBurger ? 2.4 : 1.8), fill: (d) => (d.closeToBurger ? "≤ rayon" : "> rayon"), fillOpacity: 0.38, stroke: "#0f0f0f", strokeOpacity: 0.15, tip: true, title: (d) => `OVNI — ${d.city}\nForme: ${d.shape}\nDistance In-N-Out: ${d.nearestDistanceKm.toFixed(2)} km`, }), Plot.dot(inNOut, { x: "longitude", y: "latitude", fill: "#E31837", stroke: "#FFFFFF", strokeOpacity: 0.45, strokeWidth: 0.5, symbol: "star", r: 2.8, tip: true, title: (d) => `${d.name}\nLat: ${d.latitude.toFixed(3)}\nLon: ${d.longitude.toFixed(3)}`, }), ], }); display(map); ``` ```js const scatter = Plot.plot({ width, height: 420, style: { background: "#0f0f0f", color: "#d8e1ff" }, x: { label: "Distance au In-N-Out le plus proche (km)", grid: true }, y: { label: "Durée observation OVNI (secondes)", type: "log", grid: true }, color: { legend: true, range: ["#00F3FF", "#39FF14"], }, marks: [ Plot.ruleX([hungerRadiusKm], { stroke: "#FFCC00", strokeDasharray: "4,4" }), Plot.dot(enrichedUfo, { x: "nearestDistanceKm", y: (d) => Math.max(1, d.durationSeconds), fill: (d) => (d.closeToBurger ? "≤ rayon" : "> rayon"), r: 2.4, fillOpacity: 0.65, tip: true, title: (d) => `Ville: ${d.city}\nForme: ${d.shape}\nDistance In-N-Out: ${d.nearestDistanceKm.toFixed(2)} km\nDurée: ${d.durationSeconds}s`, }), ], }); display(scatter); ``` ```js display( Plot.plot({ width, height: 420, marginLeft: 260, style: { background: "#0f0f0f", color: "#d8e1ff" }, x: { label: "Apparitions OVNI (cellule de Voronoï)", grid: true }, y: { label: null }, marks: [ Plot.barX(topHotspots, { x: "sightings", y: (d) => `${d.name} (${d.latitude.toFixed(2)}, ${d.longitude.toFixed(2)})`, sort: { y: "x", reverse: true }, fill: "#E31837", fillOpacity: 0.85, tip: true, title: (d) => `In-N-Out hotspot\nApparitions OVNI: ${d.sightings}\nDistance médiane: ${d.medDistance.toFixed(2)} km\nDurée moyenne: ${Math.round(d.avgDuration)} s`, }), ], }), ); ``` ```js const conclusion = hungerRate >= 75 ? "👽 Corrélation CRITIQUE : les aliens semblent avoir le menu secret." : hungerRate >= 50 ? "🛸 Corrélation ÉLEVÉE : suspicion de fascination pour le Double-Double." : hungerRate >= 30 ? "🛰️ Corrélation MODÉRÉE : possible coïncidence spatio-burger." : "🔬 Corrélation FAIBLE : les aliens préfèrent peut-être les tacos."; display(html`

Conclusion du laboratoire absurde

${hungerRate.toFixed(1)}% des apparitions OVNI en Californie se produisent à moins de ${hungerRadiusKm} km d’un In-N-Out.

${conclusion}

`); ```