Cartograflow

Filtering Matrix for Thematic Flow Mapping

Françoise Bahoken, Sylvain Blondeau

2020-06-03

Cartograflow is designed to filter origin-destination matrix for thematic flow mapping purposes using {sf} objects and {Cartography} to design the map.

A - Description of functions

1. Preparing flow data sets

1.1 General functions

You can use long “L” or matrix “M” [n*n] flow dataset formats.

flowtabmat() is to transform “L” to “M” formats, also to build an empty square matrix from spatial codes.

flowcarre() is to square a matrix.

flowjointure() is to performs a spatial join between a flow dataset and a spatial features layer (as a map background) or an external matrix.

flowstructmat() fixes an unpreviously codes shift in the flow dataset “M” format. If necessary this function is to be used with flowjointure and flowtabmat.

1.2. Flow computing

flowtype() is to compute volumn and balance flow from observed flows - respectively to compute symetric and skewmetric matrix from an asymmetric one.

1.3. Flow reduction

flowreduct() is to reduce the flow dataset regarding another matrix, e.g. distances travelled.

  • metric is the metric of the distance matrix : continuous (e.g. for meters) or ordinal (e.g. for adjacency).

If the metric is continuous (e.g for filtering flows by kilometric distances travelled), use:

  • d.criteria is for selecting dmin or dmax distance criteria for “continuous” metric ; Argument dmin is for keeping only flows up to a dmin criterion in km ; Argument dmax for selecting values less than a dmax criterion in km.

  • d is the value of the selected dmin or dmax criteria.

Notice that these arguments can be used as a filter criterion in flowmap().

2. Filtering flows

2.1. Filtering flows from concentration analysis

Flow concentration analysis:

flowgini() performs a Gini’s concentration analysis of the flow features, by computing Gini coefficient and plotting interactive Lorenz curve.

To be use before flowanalysis()

Flow filtering according to a concentration criterion:

flowanalysis() computes filters criterions based on:

  • argument critflow is to filter the flows according to their significativity (% of total of flow information) ;
  • argument critlink is to filter the flows according to their density (% of total features)

These arguments can be used as filter criterion in flowmap().

2.2. Spatial / territorial filtering of flows

Flow filtering based on a continuous distance criterion

flowdist() computes a continous distance matrix from spatial features (area or points). The result is a matrix of the distances travelled between ODs, with flows filtered or not.

Flow filtering based on an ordinal distance / neighbourhood criterion:

flowcontig() compute an ordinal distance matrix from spatial features (area). The result is a matrix of adjacency or k-contiguity of the ODs.

  • background is the areal spatial features ;
  • code is the spatial features codes ;
  • k is to enter the number (k:1,2,…,k) of the contiguity matrix to be constructed : if (k=1), ODs places are adjacent, then the flow have to cross only 1 boundary, else (k=k) ODs places are distant from n borders ;
  • algo is the algorithm to use for ordinal distance calculation (also Default is “automatic” for “Dijkstra’s”) ;

Notice that the function automatically returns the maximum (k) number of the spatial layer.

3. Flow mapping

flowmap() is to plot flows as segments or arrows, by acting on the following arguments:

B- Examples of applications

Useful external packages are {dplyr} {sf} {igraph} {rlang} {cartography}.

1. Load datasets

Flow dataset

## 'data.frame':    121 obs. of  4 variables:
##  $ i    : chr  "T1" "T1" "T1" "T1" ...
##  $ j    : chr  "T1" "T10" "T11" "T12" ...
##  $ Fij  : num  291058 8297 3889 17064 12163 ...
##  $ count: num  351 43 13 77 52 55 134 63 53 14 ...

Select variable and change matrix format

## Using Fij as value column: use value.var to override.
## great:your matrix is square!
##         T1   T10   T11   T12
## T1  291058  8297  3889 17064
## T10  73743 19501 11707  4931
## T11  22408  9359 12108  6084
## T12  68625  1906  7269 46515
##     i  j    Fij
## 1  T1 T1 291058
## 2 T10 T1  73743
## 3 T11 T1  22408
## 4 T12 T1  68625
## 5  T2 T1  47427
## 6  T3 T1  45772

Geographical dataset

2. Flow computing

Compute bilateral flows : volum, balance and asymetry

##    i   j    Fij    Fji   FSij  FBij      FAij minFij maxFij rangeFij      FDij
## 1 T1  T1 291058 291058 582116     0 0.0000000 291058 291058        0 0.0000000
## 2 T1 T10   8297  73743  82040 65446 0.7977328   8297  73743    65446 0.7977328
## 3 T1 T11   3889  22408  26297 18519 0.7042248   3889  22408    18519 0.7042248
## 4 T1 T12  17064  68625  85689 51561 0.6017225  17064  68625    51561 0.6017225
## 5 T1  T2  12163  47427  59590 35264 0.5917771  12163  47427    35264 0.5917771
## 6 T1  T3  32682  45772  78454 13090 0.1668494  32682  45772    13090 0.1668494

3. General Flow mapping

Plot all origin-destination links without any filtering criterion will reveal a graphic complexity (“spaghetti-effect”). So it is better to plot flow up to a simple global paramet (eg. mean).

Above-average flowmap

## Reading layer `MGP_TER' from data source `/tmp/RtmpdHbt5z/Rinst23906be61812/cartograflow/shape/MGP_TER.shp' using driver `ESRI Shapefile'
## Simple feature collection with 12 features and 14 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 637297.4 ymin: 6838629 xmax: 671752.1 ymax: 6879246
## projected CRS:  Lambert_Conformal_Conic

4. Concentration analysis for Flow mapping

Main functions

flowgini() and flowanalysis()

Compute the concentration of flow values

## Gini's coefficent =73.16 %

Plot the corresponding interactive Lorenz’ curve

##      i  j    Fij link   flowcum     linkcum
## 1   T1 T1 291058    1 0.1819563 0.008264463
## 73  T1 T4  81129    1 0.2326745 0.016528926
## 2  T10 T1  73743    1 0.2787752 0.024793388
## 4  T12 T1  68625    1 0.3216765 0.033057851
## 7   T4 T1  66223    1 0.3630761 0.041322314
## 11  T8 T1  58770    1 0.3998165 0.049586777

Compute the “critflow” parameter (ex. significance)

## [1] "threshold =  13442  ---  flows =  80 % ---  links =  23.14 %"

Flowmap filtered according to flows values significance

Using the flowanalysis() “critflow” value to select flows.

Flowmap filtered according to flow features’ density

Using the flowanalysis() “critlink value” to select flows and then flowmap.

5. Filtering flows by continous distance travelled

Filtering an Origin-Destination matrix with a continuous distance matrix (in kilometers). The aim is to plot flow 1) less than a maximum distance value, 2) above a minimum distance travelled criterion or 3) on a range of distances.

Main function

flowdist()

Useful additional functions

flowjointure() and flowreduct() with the metric parameter:" continuous".

Compute distance matrix

Function aims first to compute a distance matrix then to reduce the matrix and finally to plot the (filtered) flows. Example is for euclidian distance.

##     i  j    Fij
## 1  T1 T1 291058
## 2 T10 T1  73743
## 3 T11 T1  22408
## 4 T12 T1  68625
## 5  T2 T1  47427
## 6  T3 T1  45772
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
##     i  j  distance
## 1  T1 T1     0.000
## 2 T10 T1 11367.443
## 3 T11 T1 17285.787
## 4 T12 T1 12460.261
## 5  T2 T1  9367.284
## 6  T3 T1  9951.666

Flow reduction according to a maximum distance travelled

Using for mapping flow less than the maximum distance travelled criterion.

##     i   j flowfilter
## 1  T1  T8      18756
## 2 T10 T11      11707
## 3 T10  T8       6236
## 4 T10  T9       3497
## 5 T11 T10       9359
## 6 T12  T2       5728

Flowmap filtered according to a maximum distance travelled parameter

Using the flowreduct() d.criteria as “dmax” distance parameter to plot flows less than the maximum distance criterion (here : 8,5 km).

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique

## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
## you use the default threshold= 1

Flowmap filtered according to a minimum distance travelled parameter

Using the flowreduct() d.criteria as “dmin” distance parameter to plot flows above the minimum distance criterion (here : 20 km).

Flowmap reduction and filtering according to distance matrix

Using the flowreduct() *d.criteria as “dmax” distance parameter in association with a flowmap() _“threshold”_** value to map flows between two values (here between the first and third quartiles [Q1 - Q3]) - Not show.

6. Filtering flows by ordinal distance travelled

Filtering an Origin-Destination matrix with an ordinal distance matrix. This matrix describes a neighborhood space defined by a number (k) of boundaries to be crossed in order to reach a place of destination from a place of origin. The aim is to map local flows that are either adjacent or located at low (k).

Main function

flowcontig()

Useful additional function

flowreduct() with the metric parameter: “ordinal”.

Computes the neighbouring graph

Example is for neighbouring areas which share a common boundary (k=1)

## [1] "ordre max = 3"

Plot the neighbouring graph (k=1)

Flow reduction according to the neighbouring graph

Reducing flow matrix by the neighbouring graph (k=1)

##    i   j  flow ordre.c
## 1 T1 T10  8297       1
## 2 T1 T12 17064       1
## 3 T1  T2 12163       1
## 4 T1  T3 32682       1
## 5 T1  T4 81129       1
## 6 T1  T5 16622       1

Flowmap between adjacent areas

Using (k=1) parameter

Flowmap between non adjacent areas

Using for example (k=3) parameter.

Flowmap reducing and filtering according to ordinal matrix

Using the flowcontig() (k) parameter in association to the flowmap() threshold parameter to map above-average flows that occur between adjacent areas. - Not show.

## [1] "ordre max = 3"

C- Sample datasets

Statistical dataset :
- INSEE - Base flux de mobilité (2015) - URL : https://www.insee.fr/fr/statistiques/fichier/3566008/rp2015_mobpro_txt.zip

Geographical dataset : - municipalities : IGN, GEOFLA 2015 v2.1 - Greater Paris : APUR, UMS 2414 RIATE, 2018.

Reproducibility

sessionInfo()
## R Under development (unstable) (2020-01-27 r77729)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
## 
## locale:
##  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=C              
##  [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
##  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] igraph_1.2.5       rlang_0.4.6        cartography_2.4.1  cartograflow_1.0.2
## [5] dplyr_0.8.99.9003  sf_0.9-3          
## 
## loaded via a namespace (and not attached):
##  [1] tidyselect_1.1.0   xfun_0.13          purrr_0.3.4        reshape2_1.4.4    
##  [5] lattice_0.20-41    colorspace_1.4-1   vctrs_0.3.0        generics_0.0.2    
##  [9] htmltools_0.4.0    viridisLite_0.3.0  yaml_2.2.1         plotly_4.9.2.1    
## [13] e1071_1.7-3        pillar_1.4.4       foreign_0.8-79     glue_1.4.1        
## [17] DBI_1.1.0          sp_1.4-1           lifecycle_0.2.0    plyr_1.8.6        
## [21] stringr_1.4.0      rgeos_0.5-3        munsell_0.5.0      gtable_0.3.0      
## [25] htmlwidgets_1.5.1  evaluate_0.14      labeling_0.3       knitr_1.28        
## [29] crosstalk_1.1.0.1  maptools_1.0-1     class_7.3-17       Rcpp_1.0.4.6      
## [33] KernSmooth_2.23-17 scales_1.1.1       classInt_0.4-3     jsonlite_1.6.1    
## [37] ggplot2_3.3.0      digest_0.6.25      stringi_1.4.6      grid_4.0.0        
## [41] tools_4.0.0        magrittr_1.5       lazyeval_0.2.2     tibble_3.0.1      
## [45] crayon_1.3.4       tidyr_1.0.3        pkgconfig_2.0.3    ellipsis_0.3.0    
## [49] data.table_1.12.8  rmarkdown_2.1      httr_1.4.1         R6_2.4.1          
## [53] units_0.6-6        compiler_4.0.0