Compétence Patterns de Visualisation de Données
Patterns complets pour visualiser des données sur des cartes Mapbox. Couvre les cartes choroplèthes, les cartes thermiques, les extrusions 3D, le style piloté par les données, les visualisations animées et l'optimisation des performances pour les applications avec beaucoup de données.
Quand utiliser cette compétence
Utilisez cette compétence quand :
- Visualiser des données statistiques sur des cartes (population, ventes, démographie)
- Créer des cartes choroplèthes avec des régions codées par couleur
- Construire des cartes thermiques ou du clustering pour la visualisation de densité
- Ajouter des visualisations 3D (hauteurs de bâtiments, élévation du terrain)
- Implémenter un style piloté par les données basé sur les propriétés
- Animer des données de séries temporelles
- Travailler avec de grands jeux de données nécessitant une optimisation
Types de Visualisation
Cartes Choroplèthes
Idéal pour : Données régionales (États, comtés, codes postaux), comparaisons statistiques
Pattern : Coder par couleur les polygones en fonction des valeurs de données
map.on('load', () => {
// Ajouter la source de données (GeoJSON avec propriétés)
map.addSource('states', {
type: 'geojson',
data: 'https://example.com/states.geojson' // Features avec propriété population
});
// Ajouter un calque de remplissage avec couleur pilotée par les données
map.addLayer({
id: 'states-layer',
type: 'fill',
source: 'states',
paint: {
'fill-color': [
'interpolate',
['linear'],
['get', 'population'],
0,
'#f0f9ff', // Bleu clair pour population faible
500000,
'#7fcdff',
1000000,
'#0080ff',
5000000,
'#0040bf', // Bleu foncé pour population élevée
10000000,
'#001f5c'
],
'fill-opacity': 0.75
}
});
// Ajouter un calque de bordure
map.addLayer({
id: 'states-border',
type: 'line',
source: 'states',
paint: {
'line-color': '#ffffff',
'line-width': 1
}
});
// Ajouter un effet de survol avec popup réutilisable
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mousemove', 'states-layer', (e) => {
if (e.features.length > 0) {
map.getCanvas().style.cursor = 'pointer';
const feature = e.features[0];
popup
.setLngLat(e.lngLat)
.setHTML(
`
<h3>${feature.properties.name}</h3>
<p>Population: ${feature.properties.population.toLocaleString()}</p>
`
)
.addTo(map);
}
});
map.on('mouseleave', 'states-layer', () => {
map.getCanvas().style.cursor = '';
popup.remove();
});
});
stepvsinterpolate: L'exemple ci-dessus utiliseinterpolatepour des dégradés de couleur lisses. Pour des buckets de couleur discrets (par exemple, « faible / moyen / élevé »), utilisez à la place['step', ['get', 'population'], '#f0f0f0', 500000, '#fee0d2', 2000000, '#fc9272', 10000000, '#de2d26']. Préférezstepquand les données ont des catégories naturelles ou quand les valeurs limites exactes sont importantes.
Stratégies d'Échelle de Couleur :
// Interpolation linéaire (échelle continue)
'fill-color': [
'interpolate',
['linear'],
['get', 'value'],
0, '#ffffcc',
25, '#78c679',
50, '#31a354',
100, '#006837'
]
// Intervalles par étapes (buckets discrets)
'fill-color': [
'step',
['get', 'value'],
'#ffffcc', // Couleur par défaut
25, '#c7e9b4',
50, '#7fcdbb',
75, '#41b6c4',
100, '#2c7fb8'
]
// Basé sur des cas (données catégoriques)
'fill-color': [
'match',
['get', 'category'],
'residential', '#ffd700',
'commercial', '#ff6b6b',
'industrial', '#4ecdc4',
'park', '#45b7d1',
'#cccccc' // Défaut
]
Cartes Thermiques
Idéal pour : Densité de points, localisation d'événements, clustering d'incidents
Pattern : Visualiser la densité de points
map.on('load', () => {
// Ajouter la source de données (points)
map.addSource('incidents', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.4194, 37.7749]
},
properties: {
intensity: 1
}
}
// ... plus de points
]
}
});
// Ajouter un calque heatmap
map.addLayer({
id: 'incidents-heat',
type: 'heatmap',
source: 'incidents',
maxzoom: 15,
paint: {
// Augmenter le poids basé sur la propriété intensity
'heatmap-weight': ['interpolate', ['linear'], ['get', 'intensity'], 0, 0, 6, 1],
// Augmenter l'intensité à mesure que le niveau de zoom augmente
'heatmap-intensity': ['interpolate', ['linear'], ['zoom'], 0, 1, 15, 3],
// Palette de couleurs pour la heatmap
'heatmap-color': [
'interpolate',
['linear'],
['heatmap-density'],
0,
'rgba(33,102,172,0)',
0.2,
'rgb(103,169,207)',
0.4,
'rgb(209,229,240)',
0.6,
'rgb(253,219,199)',
0.8,
'rgb(239,138,98)',
1,
'rgb(178,24,43)'
],
// Ajuster le rayon par niveau de zoom
'heatmap-radius': ['interpolate', ['linear'], ['zoom'], 0, 2, 15, 20],
// Diminuer l'opacité aux niveaux de zoom plus élevés
'heatmap-opacity': ['interpolate', ['linear'], ['zoom'], 7, 1, 15, 0]
}
});
// Ajouter un calque de cercles pour les points individuels aux niveaux de zoom élevés
map.addLayer({
id: 'incidents-point',
type: 'circle',
source: 'incidents',
minzoom: 14,
paint: {
'circle-radius': ['interpolate', ['linear'], ['zoom'], 14, 4, 22, 30],
'circle-color': '#ff4444',
'circle-opacity': 0.8,
'circle-stroke-color': '#fff',
'circle-stroke-width': 1
}
});
});
Bonnes Pratiques
Accessibilité des Couleurs
// Utiliser les échelles ColorBrewer pour l'accessibilité
// https://colorbrewer2.org/
// Bon : Séquentiel (teinte unique)
const sequentialScale = ['#f0f9ff', '#bae4ff', '#7fcdff', '#0080ff', '#001f5c'];
// Bon : Divergent (deux teintes)
const divergingScale = ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'];
// Bon : Qualitatif (catégories distinctes)
const qualitativeScale = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00'];
// À éviter : Rouge-vert pour l'accessibilité daltonisme
// Utiliser : Bleu-orange ou violet-vert à la place
Gestion des Erreurs
// Gérer les données manquantes ou invalides
map.on('load', () => {
map.addSource('data', {
type: 'geojson',
data: dataUrl
});
map.addLayer({
id: 'data-viz',
type: 'fill',
source: 'data',
paint: {
'fill-color': [
'case',
['has', 'value'], // Vérifier si la propriété existe
['interpolate', ['linear'], ['get', 'value'], 0, '#f0f0f0', 100, '#0080ff'],
'#cccccc' // Couleur par défaut pour les données manquantes
]
}
});
// Gérer les erreurs de carte
map.on('error', (e) => {
console.error('Map error:', e.error);
});
});
Règle de Taille de Données
- < 1 MB : Utiliser GeoJSON directement
- 1–10 MB : Considérer soit GeoJSON soit vector tiles selon la complexité
- > 10 MB : Utiliser vector tiles (télécharger sur Mapbox comme tileset)
Voir references/performance.md pour les détails d'implémentation.
Fichiers de Référence
Pour des patterns de visualisation supplémentaires, charger le fichier de référence pertinent :
- references/clustering.md — Clustering de points, propriétés de cluster personnalisées, comparaison clustering vs heatmap
- references/3d-extrusions.md — Extrusions de bâtiments 3D, sources de données personnalisées, hauteurs pilotées par les données
- references/circles-lines.md — Cartes de cercles/bulles, visualisation de données linéaires, style de flux de trafic
- references/animation.md — Animation de séries temporelles, mises à jour de données en temps réel, transitions lisses
- references/performance.md — Vector tiles vs GeoJSON, feature state, filtrage, chargement progressif
- references/legends-use-cases.md — Légende UI, inspecteur de données, prétraitement de données, exemples élections/COVID/immobilier
Ressources
- Mapbox Expression Reference
- ColorBrewer - Échelles de couleurs pour les cartes
- Turf.js - Analyse spatiale
- Simple Statistics - Classification de données
- Data Visualization Tutorials