kurven = FileAttachment("kurven_daten.json").json()
farben = ({
"Villo": "#F5C800",
"Dott": "#00C2E8",
"Bolt": "#34D186"
})
function kurvenPlot(anbieter_liste, stunde, titel) {
const daten = kurven.filter(d =>
anbieter_liste.includes(d.anbieter) && d.stunde === stunde
)
return Plot.plot({
width: 580,
height: 400,
marginLeft: 65,
marginBottom: 55,
style: {
fontFamily: "'Source Sans 3', sans-serif",
fontSize: "13px",
background: "transparent"
},
x: {
label: "Gehzeit in Minuten →",
domain: [0, 15],
grid: false,
tickSize: 0
},
y: {
label: "↑ Bevölkerungsanteil mit Zugang (%)",
domain: [0, 100],
grid: true,
tickSize: 0
},
marks: [
Plot.ruleX([5], {
stroke: "#dddddd",
strokeDasharray: "5,4",
strokeWidth: 1.5
}),
Plot.text([{x: 5, y: 6}], {
x: "x", y: "y",
text: () => ["5 Min"],
fill: "#aaaaaa",
fontSize: 11,
dx: 7
}),
...anbieter_liste.map(anb =>
Plot.line(
daten.filter(d => d.anbieter === anb),
{
x: "schwelle",
y: "anteil",
stroke: farben[anb],
strokeWidth: 2.5,
curve: "monotone-x"
}
)
),
...anbieter_liste.map(anb => {
const punkt = daten.find(d => d.anbieter === anb && d.schwelle === 5)
return punkt ? Plot.dot([punkt], {
x: "schwelle",
y: "anteil",
fill: farben[anb],
r: 5
}) : null
}).filter(Boolean),
...anbieter_liste.map(anb => {
const punkt = daten.find(d => d.anbieter === anb && d.schwelle === 5)
return punkt ? Plot.text([punkt], {
x: "schwelle",
y: "anteil",
text: d => `${d.anteil.toFixed(1)}%`,
fill: farben[anb],
fontWeight: "600",
fontSize: 13,
dy: -13
}) : null
}).filter(Boolean),
Plot.text(
anbieter_liste.map((anb, i) => ({anb, i})),
{
x: () => 13,
y: d => 18 + d.i * 9,
text: d => d.anb,
fill: d => farben[d.anb],
fontWeight: "600",
fontSize: 13,
textAnchor: "start"
}
)
],
caption: titel
})
}Wie weit ist es morgens zum nächsten Mietrad?
Wie weit ist es morgens zum nächsten Mietrad?
Brüssel hat drei Anbieter von Mietfahrrädern. Aber wie nah ist das nächste Rad wirklich — morgens, wenn die Stadt aufwacht?
Diese Analyse untersucht 24 Tage im Sommer 2026 und berechnet für jede bewohnte 100×100m-Rasterzelle die Gehzeit zum nächsten verfügbaren Fahrzeug — auf dem realen Straßennetz.
Plot.plot({
width: 580,
height: 400,
style: { fontFamily: "'Playfair Display', serif", background: "transparent" },
marks: [
Plot.text([
{x: 0.5, y: 0.62, t: "Wie weit ist es"},
{x: 0.5, y: 0.50, t: "zum nächsten"},
{x: 0.5, y: 0.38, t: "Mietrad?"}
], {
x: "x", y: "y",
text: "t",
fontSize: 38,
fontWeight: "700",
fill: "#111111",
textAnchor: "middle"
}),
Plot.text([{x: 0.5, y: 0.22}], {
x: "x", y: "y",
text: () => ["Brüssel · 24 Tage · 6–9 Uhr"],
fontSize: 13,
fill: "#888888",
textAnchor: "middle"
})
],
x: { axis: null, domain: [0, 1] },
y: { axis: null, domain: [0, 1] }
})So sah Brüssel aus — 27. Juni 2026, 7 Uhr
Drei Anbieter, rund 14.800 Fahrzeuge im Stadtgebiet. Villo-Stationen in Gelb, Dott in Türkis, Bolt in Grün.
Die freie Verteilung von Dott und Bolt füllt die gesamte Stadt. Villo konzentriert sich auf das innere Stadtgebiet.
Villo — stationsbasiert
Villo betreibt 338 Stationen mit rund 3.700 Rädern. Das Netz ist dicht im Zentrum — aber es endet dort, wo die inneren Stadtteile aufhören.
Um 7 Uhr morgens erreichen nur 56,5% der Brüsseler Bevölkerung eine Villo-Station in unter 5 Gehminuten.
Dott & Bolt — Free-Floating
Dott und Bolt verteilen zusammen rund 11.100 Fahrzeuge frei im Stadtgebiet — ohne feste Stationen.
Der Unterschied ist dramatisch: die Kurven steigen fast senkrecht an. Nahezu die gesamte Bevölkerung hat innerhalb von 2 Minuten Zugang zu einem Mietrad.
Der Unterschied in Zahlen
Bei 5 Gehminuten — dem stadtplanerischen Richtwert für fußläufige Erreichbarkeit:
56,5% :::{.kennzahl-label}der Bevölkerung erreicht Villo in 5 Minuten:::
99,7% :::{.kennzahl-label}der Bevölkerung erreicht Dott in 5 Minuten:::
100% :::{.kennzahl-label}der Bevölkerung erreicht Bolt in 5 Minuten:::
Nicht die Flottengröße entscheidet. Das Modell entscheidet.
Wie ist dein Viertel versorgt?
Die interaktive Karte zeigt die Erreichbarkeit für jede Rasterzelle in Brüssel — nach Anbieter und Uhrzeit. Klick auf eine Zelle für den Tagesverlauf.
Plot.plot({
width: 580,
height: 400,
style: { fontFamily: "'Source Sans 3', sans-serif", background: "transparent" },
marks: [
Plot.text([{x: 0.5, y: 0.55, t: "mietfahrraeder-bruessel.de"}], {
x: "x", y: "y",
text: "t",
fontSize: 20,
fontWeight: "600",
fill: "#111111",
textAnchor: "middle"
}),
Plot.text([{x: 0.5, y: 0.42, t: "Interaktive Karte →"}], {
x: "x", y: "y",
text: "t",
fontSize: 14,
fill: "#888888",
textAnchor: "middle"
})
],
x: { axis: null, domain: [0, 1] },
y: { axis: null, domain: [0, 1] }
})