Cartograflow

Filtering matrix for Thematic Flow Mapping

Françoise Bahoken, Sylvain Blondeau

2019-05-09

Introduction

Cartograflow is designed to filter origin-destination (OD) flow values before their thematic cartography.

This Vignette presents a selection of possible functions for filtering flows (see 5. Reference) that can be easily used to prepare the flow dataset. The spatial objects processing are those of {sf} (embedded) and the mapping elements are those of {Cartography}.

matrix format available

– List format “L” : is a .csv 3 column flow dataset (origin, destination, flow_value) ;

– matrix format “M” : is a .csv [n*n] flow dataset.

Use flowtabmat() in order to transform a “L” to “M” matrix format and vice versa.

In the case you only have a list of spatial units (code,X,Y), you can also generate an empty square matrix with flowtabmat()

Required datasets

a statistical dataset : a .csv “L” or “M” flow dataset ;

a geographical dataset :

Plan

  1. Preparing flow dataset

  2. Flow analysis

  3. Flow mapping

  4. Cartograflow : example of applications

  5. Reference

  6. Reproducibility

1. Preparing flow dataset

1-1. Pre-processing

flowcarre() is to transform an un-square to a square matrix from a list of spatial objets ID (code)

flowjointure() is to performs a spatial join between a flow dataset and a map background

flowtabmat() is to transform a “M” matrix format to a “L” format and vice versa

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

1-2. Computing flows

It is to decide firstly to zero or not the diagonal, see {base::diag}.

flowtype() is to compute the main types of flows from an asymmetric flow dataset (matrix or list format). The result is a bilateral gross or net flows matrix.

It is also possible to compute the matrix’s margins in order to calculate probabilities of sending and receiving flows or all kinds of indicators. Use for that the R {base} or {dplyr}.

2. Flow analysis

2.1. Concentration

flowgini() performs a concentration analysis of a flow dataset - to be use before flowanalysis()

flowanalysis() is to be used after flowgini() for computing a filter criterion based on a double criterion for selecting flows before mapping :

or

2.2. Distance travelled

You have two ways to consider the distance travelled by flows : – if you have a matrix distance, go directly to flowreduct() at §2.2.3 ;

– if not, you can continue here, and have to choose the type of metric (continous or ordinal)

2.2.1. Compute continuous distances matrix

flowjointure() performs an attribute spatial join - by origin (i) and by destination (j) - between a flow dataset and a spatial shape in order to transfert the origin-destination coordinates (Xi, Yi, Xj, Yj) of the base map to the flow matrix.

flowdist() Computes a continous distance matrix choosing metric (only euclidian for this first version)

Computes on the previrous continous distance matrix at least a {base::summary} in order to compute a simle distance filter criterion.

– Use flowreduct() to reduce the flow data set regarding distances tavelled. For filtering distances, use the select criterion and set :

2.2.2. Compute ordinal distances matrix

flowcontig() compute an ordinal distance distance matrix based on a k-contiguity matrix. (k) is the order parameter defined by the number of borders to be crossed between origins and destinations places.

– Use after that flowreduct() function and directly flowmap() without applying the filter parameter.

You can also map the neighbourhood spatial graph using flowmap() without applying the filter parameter.

2.2.3. Reduces a flow matrix by an external OD matrix

flowreduct() is to perform the reduction of the flow dataset according to another matrix (especially a matrix distance)

3. Flow mapping

flowmap() is to create a layer of lines, plot them, using a flow dataset (dataframe format) and a spatial shape (shapefile format).

3.1. Filtering flows (if necessary)

filter is to choose to map all or selected flow values.

3.2. Filtering flow values

If filter is “TRUE”, it is possible to threshold flow values.

threshold is to apply a numerical global (across the whole matrix) filter criterion.

3.3. Filtering flow value (dealing with strongest flows)

3.3. Filtering flow features (dealing with density)

3.4. Setting up the flow features

Use flowtabmat() for setting graphic parameters for arrows

taille is to modify the width of the origin-destination lines.

a.head is to add a head of the line (transform it to arrows) to be drawn from places (in, out, in and out).

a.length is to parameter the length of the arrow head in relation to the body of the arrow.

a.angle is to parameter an angle from the shaft of the arrow to the edge of the arrow head.

a.col is to parameter the color of the arrows.

4. Cartograflow : example of applications

4.1 Load packages

4.2 Data

– Statistical dataset : extraction from the nationale file : “Mobilités professionnelles en 2015 : déplacements domicile - lieu de travail” from the french census (Recensement de la population) - Base flux de mobilité.

-URL : https://www.insee.fr/fr/statistiques/fichier/3566008/rp2015_mobpro_txt.zip

– Geographical dataset :

4.2.1 Load Statistical information

data<-read.csv2("./data/MOBPRO_ETP.csv",
                header=TRUE,
                sep=";",
                stringsAsFactors=FALSE,
                encoding="UTF-8",
                dec=".",
                check.names=FALSE)
head(data)
##    i   j    Fij count
## 1 T1  T1 291058   351
## 2 T1 T10   8297    43
## 3 T1 T11   3889    13
## 4 T1 T12  17064    77
## 5 T1  T2  12163    52
## 6 T1  T3  32682    55
str(data)
## 'data.frame':    121 obs. of  4 variables:
##  $ i    : chr  "T1" "T1" "T1" "T1" ...
##  $ j    : chr  "T1" "T10" "T11" "T12" ...
##  $ Fij  : int  291058 8297 3889 17064 12163 32682 81129 16622 25317 1962 ...
##  $ count: int  351 43 13 77 52 55 134 63 53 14 ...
# Variable typing
data$i<-as.character(data$i)
data$j<-as.character(data$j)
data$Fij<-as.numeric(data$Fij)
data$count<-as.numeric(data$count)


# Loading a list of geo codes
ID_CODE<-read.csv2("./data/COD_GEO_EPT.csv",
                   header=TRUE,
                   sep=";",
                   stringsAsFactors=FALSE,
                   encoding="UTF-8",
                   dec=".",
                   check.names=FALSE)
head(ID_CODE)
##   COD_GEO_EPT
## 1          T1
## 2          T2
## 3          T3
## 4          T4
## 5          T5
## 6          T6
CODE<-ID_CODE%>% dplyr::select(COD_GEO_EPT)

colnames(CODE)<-c("CODGEO")

head(CODE)
##   CODGEO
## 1     T1
## 2     T2
## 3     T3
## 4     T4
## 5     T5
## 6     T6

4.2.2 Pre-processing flow dataset

tabflow<-data%>%select(i,j,Fij)

# Change matrix format (if necessary)
matflow <-flowtabmat(tabflow,matlist="M")
## Using Fij as value column: use value.var to override.
## great:your matrix is square!
head(matflow[1:4,1:4])
##         T1   T10   T11   T12
## T1  291058  8297  3889 17064
## T10  73743 19501 11707  4931
## T11  22408  9359 12108  6084
## T12  68625  1906  7269 46515
dim(matflow)
## [1] 12 12

The Warning said that the matrix is square (dimension is : 12*12). If it was not, Use {flowcarre}to square it (and to close it)

4.2.3 Computing flow dataset

Zero the diagonal and change matrix format (list to matrix)

# Zero the diagonal of matrix format (if necessary)
diag(matflow) <- 0
head(matflow[1:4,1:4])
##        T1  T10   T11   T12
## T1      0 8297  3889 17064
## T10 73743    0 11707  4931
## T11 22408 9359     0  6084
## T12 68625 1906  7269     0
# Change matrix to list format
tabflow<-flowtabmat(tab=matflow,
                    matlist="L")
head(tabflow)
##     i  j ydata
## 1  T1 T1     0
## 2 T10 T1 73743
## 3 T11 T1 22408
## 4 T12 T1 68625
## 5  T2 T1 47427
## 6  T3 T1 45772
colnames(tabflow)<-c("i","j","Fij")

4.2.4 Computing main types of flow dataset

Compute bilateral flow volume and bilateral flow balance from a matrix or a list format of observed flows,

# Compute bilateral flow volume - from a "M" format
matflow_vol<-flowtype(matflow,
                      format="M",
                      "bivolum")

# Compute bilateral flow volume - from a "L" format

# FSij will be the gross Fij flow values
tabflow_vol<-flowtype(tabflow,
                     format="L",
                     "bivolum")
head(tabflow_vol)
##    i   j  FSij
## 1 T1  T1     0
## 2 T1 T10 82040
## 3 T1 T11 26297
## 4 T1 T12 85689
## 5 T1  T2 59590
## 6 T1  T3 78454
# Compute bilateral flow balance - from a "L" format

# FDij will be the net Fij flow values
tabflow_net<-flowtype(tabflow,
                      format="L",
                      "bisold")
head(tabflow_net)
##    i   j  FDij
## 1 T1  T1     0
## 2 T1 T10 65446
## 3 T1 T11 18519
## 4 T1 T12 51561
## 5 T1  T2 35264
## 6 T1  T3 13090
# Compute all types of bilateral flows, in one 6 columns "L"format matrix
tabflow_all<-flowtype(tabflow, 
                      format="L", 
                      x="all")
head(tabflow_all) 
##    i   j   Fij   Fji  FSij  FDij
## 1 T1  T1     0     0     0     0
## 2 T1 T10  8297 73743 82040 65446
## 3 T1 T11  3889 22408 26297 18519
## 4 T1 T12 17064 68625 85689 51561
## 5 T1  T2 12163 47427 59590 35264
## 6 T1  T3 32682 45772 78454 13090
# Compute flow asymetry
tabflow_all$FAsy<-(tabflow_all$FDij / tabflow_all$FDij)*100

4.3 Flow mapping

4.3.1 Direct flow mapping

Plot all origin-destination links without any filtering criterion.

knitr::opts_chunk$set(fig.width=6, fig.height=6)

par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

# Plot all theoretical OD links 
flowmap(tab = tabflow,
        format="L",
        fdc="./data/MGP_TER.shp",
        code="EPT_NUM",
        filter=FALSE) #no filter criterion
## All theorical links are plotted
mtext("All theoretical relations - no filter",side = 3)

Plot valued origin-destination links (> 1000)

par(mar=c(0,0,1,0))

#Plot existing relations (up to 1000 commuters)
flowmap(tab = tabflow,
        format="L",
        fdc="./data/MGP_TER.shp",
        code="EPT_NUM",
        filter=TRUE,        #add filter
        a.col="#3f4247",
        threshold=1000,     
        taille=8,           
        a.head = 1,
        a.length = 0.11)

mtext("Flows up to 1000 commuters (~ 50%)",side = 3)

4.5 Mapping a robust flow selection

4.5.1 Statistical parameter

# Plot flow value up to a global filter criterion 

par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

# Mapping filtered observed commuters
flowmap(tab = tabflow,
              format="L",
              fdc="./data/MGP_TER.shp",
              code="EPT_NUM",
              filter=TRUE,
              a.col="#3f4247",
              threshold=7406,  # Mean=7406 
              taille=8,        
              a.head = 1,      
              a.length = 0.11)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
mtext("Flows up to mean value (7406 commuters)",side = 3)

# Bilateral flow volum of commuters
flowmap(tab = tabflow_vol,
              format="L",
              fdc="./data/MGP_TER.shp",
              code="EPT_NUM",
              filter=TRUE,
              a.col="#3f4247",
              threshold=14812.4,  # Mean=14812.4
              taille=14,        
              a.head = 0,      
              a.length = 0.11)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
mtext("Bilateral flow volume of commuters up to mean (14812 commuters)",side = 3)

# Bilateral flow balance of commuters
flowmap(tab = tabflow_net,
              format="L",
              fdc="./data/MGP_TER.shp",
              code="EPT_NUM",
              filter=TRUE,
              a.col="#3f4247",
              threshold=8547,  # Mean=8547
              taille=8,        
              a.head = 1,      
              a.length = 0.11)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
mtext("Bilateral flow balance of commuters up to mean (8547 commuters)",side = 3)

4.5.2 Concentration analysis

head(tabflow,3)
##     i  j   Fij
## 1  T1 T1     0
## 2 T10 T1 73743
## 3 T11 T1 22408
# 1- Computes Gini's coefficent
#--------------------
tab_gini<-flowgini(tabflow,
                   format="L",
                   origin="i",
                   dest="j",
                   valflow="Fij",
                   fdc = "./data/MGP_TER.shp",
                   code="EPT_NUM",
                   lorenz.plot = FALSE)
## Gini's coefficent =71.75 %
#Interpretation ; The flows are quite concentrated on a few links, the Gini coefficent is equal to 71% 

# 2- Plot Lorenz curve
#--------------------
#head(tab_gini)

flowgini(tab_gini, 
         format="L",
         origin="i",
         dest="j",
         valflow="ydata",
         fdc = "./data/MGP_TER.shp",
         code="EPT_NUM",
         lorenz.plot = TRUE)

4.5.3 Compute critflow parameter and flowmap

#critflow = 0.8
flowanalysis(tab_gini,
             critflow = 0.8,
             result = "signif")
## [1] "threshold =  11238  ---  flows =  80 % ---  links =  22.94 %"
# Interpretation : Flow values up to 11238 are the 80% largest one corresponding to 22,94% of the total links.

#threshold = 11238

par(mar=c(0,0,1,0))
flowmap(tabflow,
        format="L",
        fdc="./data/MGP_TER.shp",
        code="EPT_NUM",
        filter=TRUE,
        threshold=11238,
        taille=8,
        a.head = 1,
        a.length = 0.11,
        a.angle = 30,
        a.col="#3f4247")
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
mtext("Significative flowmap : values up to 11238 - 80% flow information - 22.9% total links",side = 3)

4.5.5 Final concentration’s Flowmap

par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

# Final flowmap customized
flowmap(tabflow,
        format="L",
        fdc="./data/MGP_TER.shp",
        code="EPT_NUM",
        filter=TRUE,
        threshold=7343, 
        taille=5,   
        a.head = 1,
        a.length = 0.11,
        a.angle = 30,
        a.col="#138913"
        )
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
# Legend
legendPropLines(pos="topleft",
                title.txt="Number of commuters up to 11238 (the 80% largest flows)",
                title.cex=1,   
                cex=0.8,
                values.cex= 0.7,  
                var=c(11238,max(tabflow$Fij)), 
                lwd=5, 
                frame = FALSE,
                col="#138913",
                values.rnd = 0
                )

layoutLayer(title = "Professional mobility in Greater Paris",
           coltitle ="black",
           author = "Cartograflow, 2019",
           sources = "Sources : data : INSEE, RP, MOBPRO, 2017 ; basemap : IGN, APUR, UMS 2414 RIATE, 2018.",
           scale = 2,
           tabtitle = TRUE,
           frame = TRUE,
           #north(pos = "topright"),
           col = "grey"
            )

4.6 Thresholding flows by distance travelled

4.6.1 Continuous distance

head(tabflow)
##     i  j   Fij
## 1  T1 T1     0
## 2 T10 T1 73743
## 3 T11 T1 22408
## 4 T12 T1 68625
## 5  T2 T1 47427
## 6  T3 T1 45772
tab<-flowjointure(tabflow,
                  "./data/MGP_TER.shp",
                  "EPT_NUM")

tab.distance<-flowdist(tab,
                       dist.method = "euclidian",
                       result = "dist")
head(tab.distance)
##     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
#reduce the flow dataset from a selected distance travelled < 8.5 km
library(rlang)

tab.flow<-flowreduct(tab,
                     tab.distance,
                     metric = "continous",
                     select = "dmax", #max distance parameter 
                     d = 8567)        #max distance value - Q1 : 8567 km
## your dataset must be have three columns : origine, destination and flow or another data
#select for all i,j flow values up to 0
flow.d<-tab.flow%>%
       select(i,j,flowfilter)%>%
        filter(flowfilter !=0)

#Flowmap : flow travelled less than 8.5 km  (Q1)

par(mar=c(0,0,1,0))

extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

flowmap(flow.d,format="L",
       "./data/MGP_TER.shp",
       "EPT_NUM",
        filter = TRUE,
        taille = 5,
        a.col="#138913",
        a.length = 0.11,
        a.head =1)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
## warning : you use the default threshold= 1
legendPropLines(pos="topleft",
                title.txt="Number of commuters (distance travelled less than 8,5 km)",
                title.cex=1,    
                cex=0.8,
                values.cex= 0.8,  
                var=c(min(flow.d$flowfilter),8567), 
                col="#138913",
                lwd=5,
                frame = FALSE,
                values.rnd = 0
                )
# Habillage
layoutLayer(title = "Professional mobility in Greater Paris : short distance travelled",
            author = "Cartograflow, 2019",
            sources = "Sources : data : INSEE, RP, MOBPRO, 2017 ; basemap : IGN, APUR, UMS 2414 RIATE, 2018",
            scale = 5,
            tabtitle = TRUE,
            frame = TRUE,
            #north(pos = "topright"),
            col = "grey",
            coltitle ="black"
            )

head(tabflow)
##     i  j   Fij
## 1  T1 T1     0
## 2 T10 T1 73743
## 3 T11 T1 22408
## 4 T12 T1 68625
## 5  T2 T1 47427
## 6  T3 T1 45772
tab<-flowjointure(tabflow,
                  "./data/MGP_TER.shp",
                  "EPT_NUM")

tab.distance<-flowdist(tab,
                       dist.method = "euclidian",
                       result = "dist")

tab.flow<-flowreduct(tab,
                     tab.distance,
                     metric = "continous",
                     select = "dmin",  
                     d = 14518)        #Q2 : 14518 km - Q3:19234 km
## your dataset must be have three columns : origine, destination and flow or another data
#select for all i,j flow values up to 0
flow.d<-tab.flow%>%
       select(i,j,flowfilter)%>%
        filter(flowfilter !=0)


#Flowmap : flow travelled up to (Q3)

par(mar=c(0,0,1,0))

extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

flowmap(flow.d,format="L",
       "./data/MGP_TER.shp",
       "EPT_NUM",
        filter = TRUE,
        taille = 5,
        a.col="#138913",
        a.length = 0.11,
        a.head =1)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
## warning : you use the default threshold= 1
legendPropLines(pos="topleft",
                title.txt="Number of commuters (distance travelled more than 14.5 km)",
                title.cex=1,    
                cex=0.8,
                values.cex= 0.8,  
                var=c(14518, max(flow.d$flowfilter)), 
                col="#138913",
                lwd=5, 
                frame = FALSE,
                values.rnd = 0
                )
# Habillage
layoutLayer(title = "Professional mobility in Greater Paris : mean distance travelled",
            author = "Cartograflow, 2019",
            sources = "Sources : data : INSEE, RP, MOBPRO, 2017 ; basemap : IGN, APUR, UMS 2414 RIATE, 2018",
            scale = 5,
            tabtitle = TRUE,
            frame = TRUE,
            #north(pos = "topright"),
            col = "grey",
            coltitle ="black")

4.6.2 Ordinal distance

## Neighbouring graph (ordre 1)
graph_ckij_1<-flowcontig("./data/MGP_TER.shp",
                         "EPT_NUM",
                         ordre =1)

  flowmap(graph_ckij_1,
          format="L",
          "./data/MGP_TER.shp",
          "EPT_NUM",
          filter = TRUE, 
          taille = 0.5)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
## warning : you use the default threshold= 1
mtext("Neighbouring graph (order 1)",
      side=3)

## Reducing flow matrix by the neighbouring graph (order= 1)
reduc<-flowreduct(tabflow,
                  graph_ckij_1,
                  metric = "ordinal")

flow.c<-reduc %>%
  select(i,j,flux)%>%
  filter(flux!=0)

#Plot adjacent flowmap 
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-190

flowmap(flow.c,
        format="L",
        "./data/MGP_TER.shp",
        "EPT_NUM",
        filter = TRUE,
        taille = 5,
        a.col="#138913",
        a.length = 0.1,
        a.head =1)
## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique

## Warning in polypath(x = mcrds[, 1], y = mcrds[, 2], border = border, col =
## col, : Path drawing non disponible pour ce périphérique
## warning : you use the default threshold= 1
# Legend
legendPropLines(pos="topleft",
                title.txt="Number of commuters (one border distance)",
                title.cex=1,    
                cex=0.8,
                values.cex= 0.8,  
                var=c(min(flow.c$flux),max(flow.c$flux)), 
                col="#138913",
                lwd=5, 
                frame = FALSE,
                values.rnd = 0
                )
# Habillage
layoutLayer(title = "Professional mobility in Greater Paris between neighbouring municipalities",
            author = "Cartograflow, 2019",
            sources = "Sources : data : INSEE, RP, MOBPRO, 2017 ; basemap : IGN, APUR, UMS 2414 RIATE, 2018",
            scale = 5,
            tabtitle = TRUE,
            frame = TRUE,
            #north(pos = "topright"),
            col = "grey",
            coltitle ="black")

5. Reference

– Bahoken Francoise (2016), Programmes pour R/Rtudio annexés, in : Contribution à la cartographie d’une matrix de flux, Thèse de doctorat, Université Paris 7, pp. 325-346. URL : https://halshs.archives-ouvertes.fr/tel-01273776, pp. 480-520.

6. Reproducibility

sessionInfo()
## R Under development (unstable) (2019-04-25 r76423)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.2 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1
## 
## 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] rlang_0.3.4        cartography_2.2.0  cartograflow_1.0.0
## [4] dplyr_0.8.0.1     
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.1        later_0.8.0       pillar_1.3.1     
##  [4] compiler_3.7.0    plyr_1.8.4        tools_3.7.0      
##  [7] digest_0.6.18     lattice_0.20-38   viridisLite_0.3.0
## [10] jsonlite_1.6      evaluate_0.13     tibble_2.1.1     
## [13] gtable_0.3.0      pkgconfig_2.0.2   shiny_1.3.2      
## [16] crosstalk_1.0.0   rgdal_1.4-3       yaml_2.2.0       
## [19] xfun_0.6          stringr_1.4.0     httr_1.4.0       
## [22] knitr_1.22        rgeos_0.4-3       htmlwidgets_1.3  
## [25] grid_3.7.0        tidyselect_0.2.5  glue_1.3.1       
## [28] data.table_1.12.2 R6_2.4.0          plotly_4.9.0     
## [31] foreign_0.8-71    rmarkdown_1.12    sp_1.3-1         
## [34] reshape2_1.4.3    ggplot2_3.1.1     purrr_0.3.2      
## [37] tidyr_0.8.3       magrittr_1.5      promises_1.0.1   
## [40] maptools_0.9-5    scales_1.0.0      htmltools_0.3.6  
## [43] assertthat_0.2.1  xtable_1.8-4      mime_0.6         
## [46] colorspace_1.4-1  httpuv_1.5.1      labeling_0.3     
## [49] stringi_1.4.3     lazyeval_0.2.2    munsell_0.5.0    
## [52] crayon_1.3.4