Transcarto
Création et visualisation de champs vectoriels pour l’analyse de matrice Origine-Destination

Etienne Côme @comeetie

19 Octobre 2021

Tobler et le mouvement

Geographical Movement

is critically important.

This is because much change in the world is due to geographical movement.

The movement of ideas, people, disease, money, energy, material, etc.

W. Tobler

Travaux de tobler sur ODs et champs vectoriels

Quelques pointeurs :

Champ et données ponctuelle

  • Tobler s’intéresse très tôt à ces questions et propose de résumer une matrice OD spatialisée à l’aide d’un champ de vecteurs.

  • Il propose par exemple de calculer les vecteurs suivants en chacun des lieux:

\[\vec{c_i} = \frac{1}{n-1}\sum_{j\neq i}\frac{1}{dist(i,j)}\frac{M_{ij}-M_{ji}}{M_{ij}+M_{ji}}(\vec{x_j}-\vec{x_i})\]

Champ

Il cherche a construire et représenter le champ vectoriel (le vent) qui permettrait d’expliquer au mieux les mouvements observés. La métaphore physique est déjà utilisée.

Munich

  • Exemple avec les données de Munich (ttt vise aussi a faciliter la ré-utilisation des données historique de W. Tobler)
data(munich)
sf=ttt:::mean_od_vectors(munich$coords,munich$OD)
arr = arrow(angle=15,length = unit(0.3,"cm"),type = "closed")
ggplot(sf)+geom_segment(aes(x=x,y=y,xend=x+dx*100,yend=y+dy*100),
                        arrow = arr)+
  theme_void()

Munich

Munich

Attractivité et données ponctuelles

Premiers travaux (données ponctuelles + ODs)

Ces travaux s’articulent et se formalisent au travers de l’introduction de deux objets :

  • un champ potentiel (qui associe un chiffre a chaque lieu synthétisant son attractivité)
  • un champ vectoriel (dérivée du champ potentiel et décrivant le mouvement)

Attractivité et données ponctuelles

Hypothèse


La disymétrie entre deux flux \(M_{ij}\) et \(M_{ji}\) est proportionelle à la différence d’attractivité entre \(i\) et \(j\) modulé par la distance entre \(i\) et \(j\).

\[M_{ij}-M_{ji}\propto\frac{(A_i-A_j)}{dist(i,j)}\]

Attractivité et données ponctuelles

Données ponctuelles + ODs

\[\color{blue}{D}.\color{red}{A}=\color{green}{\Delta}\] avec :

  • \(\color{blue}{D}\) matrice modélisant l’influence des distances \(D_{ij}=-\frac{1}{dist(i,j)}\) et \(D_{kk}=\sum_{i,i\neq k}\frac{1}{dist(i,k)}\),
  • \(\color{red}{A}\) le vecteur d’attractivité recherché
  • \(\color{green}{\Delta}\) le vecteur de balance \(\Delta_{k}=\sum_iM_{ik} - \sum_jM_{kj}\).

Solution unique à un facteur additif près.

Construction d’un champ continu

Même modèle, même hypothèses mais les déplacements ne peuvent se faire qu’entre nœuds voisins positionnés sur une grille régulière :

Construction d’un champ continu

On obtient pour chaque noeuds 4 équations reliant les flux aux attractivités :

Construction d’un champ continu

Qui une fois combinées lient les \(\color{green}{\Delta}\) aux attractivités :

et forment un système d’équation linéaire avec des liens fort avec la physique (équation de poisson).

Rmq : Manque juste les équations au bord du domaine qui encoderont le fait que le système est clos (pas de fuites)

Construction d’un champ continu

Pour utiliser cette approche il suffit d’affecter un \(\color{green}{\Delta}\) à chaque nœuds de la grille.

Solution proposée par Tobler avec des données spatiales zonales affectation uniforme (ou pondéré) des \(\color{green}{\Delta}\) :

Construction d’un champ

En résumé :

  • Rasteriser les polygones sur une grille régulière,
  • i.e. affecter à chaque nœud de la grille le \(\color{green}{\Delta}\) du polygone qui le contient pondéré par le nombre de nœud à l’interieur du polygone
  • Résoudre l’équation de poisson pour obtenir le champ potentiel i.e. l’attracivité de chaque nœud
  • Calculer le champs vectoriel en différenciant l’attractivité

Exemple historique

Exemple historique (dollars)

# chargement des données
data("dollars")
# calcul des deltas (balance)
delta = rowSums(dollars$OD)-colSums(dollars$OD)
dollars$polygones$delta=delta

# un jolie petit cadre
vintage_frame(dollars$polygones)
# affichage des contours
plot(st_geometry(dollars$polygones),add=TRUE)
# affichage des balances +/-
plus_minus_map(dollars$polygones,"delta")

Exemple historique (dollars)

Exemple historique (dollars)

pot.dollars = compute_poisson_potential(dollars$polygones,
                                varname = "delta",
                                method = "jacobi",
                                nb_it=1000)
pot.dollars = compute_poisson_potential(dollars$polygones,cellsize = 5000)
## Classes 'sf' and 'data.frame':   1614 obs. of  10 variables:
##  $ grid_in     :sfc_POLYGON of length 1614; first list element: List of 1
##   ..$ : num [1:5, 1:2] 33.4 34.5 34.5 33.4 33.4 ...
##   ..- attr(*, "class")= chr [1:3] "XY" "POLYGON" "sfg"
##  $ i           : num  1 1 2 2 2 2 3 3 3 3 ...
##  $ j           : num  31 32 29 30 31 32 29 30 31 32 ...
##  $ attractivity: num  281 281 277 277 280 ...
##  $ residuals   : num  0.24 0.203 0.194 0.234 0.2 ...
##  $ b           : num  2.66 2.66 2.66 2.66 2.66 ...
##  $ dx          : num  0 0 0 1.49 1.35 ...
##  $ dy          : num  0 0 0 0 -1.88 ...
##  $ x           : num  33.9 35 31.9 32.9 33.9 ...
##  $ y           : num  4.51 4.51 5.52 5.52 5.52 ...
##  - attr(*, "sf_column")= chr "grid_in"
##  - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA
##   ..- attr(*, "names")= chr [1:9] "i" "j" "attractivity" "residuals" ...

Visualisation du potentiel d’attractivité

plot(pot.dollars %>% select(attractivity))

Visualisation du potentiel d’attractivité

Visualisation du champ vectoriel

par(mar=c(0,0,0,0))
vintage_frame(dollars$polygones)
plot(st_geometry(dollars$polygones),add=TRUE)
poisson_flows(pot.dollars,normfact = 0.01)

Visualisation du champ vectoriel

Visualisation du champ vectoriel

Droplets

Pour finir de filer la métaphore

et faire une carte de mouvements en mouvement

il est possible d’utiliser les droplets

Droplets

Confession, j’ai longtemps admirer earth.nullschool.net :

Droplets

Recette :

  • lâcher quelques centaine de particules dans le champs,
  • à chaque pas de temps faire évoluer leurs positions suivant le champ
  • mettre à jour la visualisation avec les nouvelles positions
  • en gardant la visualisation précédente mais en l’atténuant pour créer un effet de traînée
  • à partir d’un certains temps ré-initialiser la position de la particule de manière aléatoire

Wind

Limites // discussion

  • Territoire continu quid des îles
  • Pas de fuites ?
  • Utilisation uniquement des \(\color{green}{\Delta}\)
  • Neutralité de la représentation ?
  • Légende à la fois inutile et importante