---
title: "Visualisation de données avec R"
author: François Pelletier
date: 15 octobre 2016
runtime: shiny
output: 
  html_document: 
    fig_caption: no
    highlight: tango
    keep_md: yes
    number_sections: yes
    theme: cerulean
    toc: yes
---

# Leaflet
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

## Introduction
[Leaflet](http://leafletjs.com/) est une bibliothèque en JavaScript permet de créer des cartes géographiques interactives avec différents langages de programmation dont R. On peut retrouver une introduction à Leaflet pour R sur le site de RStudio: [Leaflet for R](https://rstudio.github.io/leaflet/).

Les différentes caractéristiques de Leaflet:

- Zoom et déplacement dans la carte
- Utilisation de plusieurs types de couches dont:
    - Tuiles de cartes ([OpenStreetMap](http://openstreetmap.org/) et autres)
    - Marqueurs
    - Polygones
    - Lignes
    - Bulles d'information
    - Toute autre information représentée dans le format [GeoJSON](http://leafletjs.com/examples/geojson/)

Cette bibliothèque s'utilise aussi dans le cadre des documents [R Markdown](http://rmarkdown.rstudio.com/) (tel que ce document que vous consultez en ce moment) et des applications web [Shiny](http://shiny.rstudio.com/gallery/). Elle permet d'utiliser les formats de données de la bibliothèque [`sp`](https://cran.r-project.org/web/packages/sp/index.html) ou des data.frmee avec deux colonnes contenant la longitude et la latitude.

## Installation
Pour installer cette bibliothèque dans R, utiliser la commande suivante:
```{r, echo=TRUE, eval=FALSE}
install.packages("leaflet")
```

Pour la charger, utilisez
```{r, echo=TRUE}
library("leaflet")
```

## Autres bibliothèques

Ces autres bibliothèques nous seront utiles dans cet atelier
```{r pkgs, cache = FALSE, echo=TRUE}
library("rgdal")
library("dplyr")
library("webshot")
library("shiny")
library("htmltools")
library("reshape2")
require(XML)
require(stringr)
library(gganimate)
library(animation)
```

## La composition d'une carte
Une carte peut être composée de plusieurs éléments:

- Le fond de la carte est composé de tuiles
- Les différentes régions géographiques peuvent être représentées par des polygones et des lignes
- Les éléments de données peuvent être représentés par des marqueurs
- On peut y ajouter divers autres éléments informatifs ou décoratifs

## Acquisition des données
Les données géographiques vectorielles (polygones, lignes, points) sont souvent représentées sous forme de fichiers KML, geoJSON ou ESRI Shapefiles. Les tuiles de données ou raster sont souvent au format geoTIFF.

L'objet data de la vignette peut accueillir différentes structures de données, mais il faut au préalablement les créer à partir des données sources

Nous utiliserons la bibliothèque `rgdal` our lire les données et créer ces structures

## Données utilisées dans cet atelier
Dans cet atelier, nous cherchons à représenter la couverture Wifi du réseau [ZAP Québec](http://www.zapquebec.org/) à l'aide de la localisation des différents points d'accès contenus dans le fichier "WIFI.KML" téléchargé sur[le portail Données Québec](https://www.donneesquebec.ca/recherche/fr/dataset/vque_29). Ce fichier est partagé sous la licence [Creative Commons - Attribution 4.0](https://www.donneesquebec.ca/fr/licence/#cc-by).

## KML
Le format de fichiers KML est un standard ouvert [développé par Google](https://developers.google.com/kml/documentation/) pour l'application Google Earth. C'est un fichier XML avec des caractéristiques particulières. 

## Acquisition des données (1/2)
Pour lire le fichier de données, on utilise la fonction `readOGR()` de `rgdal`.
```{r, echo=TRUE}
WIFI_DATA <- readOGR("./DATA/WIFI.KML", "WIFI")
```

On obtient un objet de la classe `SpatialPointsDataFrame`.
```{r, echo=TRUE}
class(WIFI_DATA)
```

Cette classe est un type de données complexer qui inclut entre autres un data.frame `data` contenant les données extraites du fichier KML. La structure complète de notre exemple se présente comme suit.

```{r}
str(WIFI_DATA)
```

## Attributs
Chaque point présente 6 attributs:

- ARROND : Nom de l'arrondissement où se situe le réseau Wifi.
- NO_CIV : Numéro d'immeuble du réseau Wifi.
- NOM_BATI : Nom de l'édifice où se situe le réseau Wifi.
- RUE : Nom de la rue où se situe le réseau Wifi.
- LONGITUDE : Longitude du réseau Wifi.
- LATITUDE : Latitude du réseau Wifi.

## La vignette interactive Leaflet
La création d'une carte débute avec la vignette interactive (widget) `leaflet()`:
```{r, echo=TRUE,eval=FALSE}
leaflet()
```

Cette vignette peut être modifiée à l'aide de différentes propriétés et différents opérateurs que nous explorerons dans cet atelier. 

## Ajout des données à la carte

On associe à la propriété data les données que nous avons importées. On utilise la fonction `addTiles` pour ajouter des tuiles de fond et `addMarker` pour ajouter des marqueurs basés sur les coordonnées géographiques. Enfin, on utilise l'argument `popup` pour inclure une description qui sera affichée en cliquant sur un marqueur. Les données que nous utilisons incluent déjà une description en HTML. L'argument `group` sert a attribuer un identifiant pour chaque élément composant la carte. Il n'est pas affiché sur la carte sauf si on le demande explicitement, dans un menu par exemple.

```{r, echo=TRUE}
l1 <- leaflet(data=WIFI_DATA) %>% 
  addTiles(group = "Tuiles OSM") %>% 
  addMarkers(popup = ~ description, 
             group = "Points d'accès")
```
```{r, echo=TRUE}
renderLeaflet(l1)
```

## Ajout d'une couleur de marqueur pour chaque arrondissement

```{r, echo=TRUE}
palette_arrond <- colorFactor(rainbow(levels(WIFI_DATA$ARROND) %>% length()), 
                       WIFI_DATA$ARROND)

l2 <- leaflet(data=WIFI_DATA) %>%
  addTiles() %>% 
  addCircleMarkers(popup = ~ description, 
                   color = ~palette_arrond(ARROND),
                   group = "cerclepointsacces")
```

```{r, echo=TRUE}
renderLeaflet(l2)
```

## Ajout des polygones des arrondissements

On importe les données des limites des arrondissements à partir du fichier "ARROND.KML" téléchargé sur[le portail Données Québec](https://www.donneesquebec.ca/recherche/fr/dataset/vque_2). Ce fichier est partagé sous la licence [Creative Commons - Attribution 4.0](https://www.donneesquebec.ca/fr/licence/#cc-by).
```{r, echo=TRUE}
ARROND <- readOGR("DATA/ARROND.KML","ARRONDISSEMENT")
```

On crée ensuite une palette de couleurs qui associe une couleur à chaque arrondissement.
```{r, echo=TRUE}
palette_arrondissement <- colorFactor(rainbow(levels(ARROND$NOM) %>% length()), 
                       ARROND$NOM)
```

Enfin, on affiche la carte avec les polygones coloriés selon la palette définie précédemment.
```{r, echo=TRUE}
l1 %>% addPolygons(data=ARROND, color = ~palette_arrondissement(NOM), group="Arrondissements")
```

Il est aussi possible d'ajouter plusieurs éléments à la carte pour en augmenter la facilité d'utilisation. Ici, on ajoute une légende ainsi qu'une boîte de contrôle qui permet de gérer l'affichage des différents éléments.

```{r}
l1 %>% 
  addPolygons(data=ARROND, color = ~palette_arrondissement(NOM), group="Arrondissements") %>% 
  addLegend("bottomright", pal = palette_arrondissement, values = ARROND$NOM,
    title = "Arrondissements",
    opacity = 1,
  ) %>%
  addLayersControl(
    baseGroups = c("Tuiles OSM"),
    overlayGroups = c("Points d'accès", "Arrondissements"),
    options = layersControlOptions(collapsed = FALSE)
  )
```


# Plotly

## Introduction

[Plotly](https://plot.ly/) est une bibliothèque de graphiques interactifs en JavaScript. Tout comme Leaflet, on peut l'utiliser via des interfaces dans plusieurs langages de programmation, dont R. L'interface de programmation est documentée [sur ce site](https://plot.ly/r/).

Plotly permet de créer plusieurs types de graphiques (statistiques, scientifiques, cartes, 3d) et permet aussi de convertir des graphiques créés à partir de `ggplot2`.


## Installation

On installe `plotly` avec cette commande:
```{r, eval=FALSE}
install.packages(plotly)
```

On charge ensuite la bliblothèque:
```{r, echo=TRUE}
library(plotly)
```

## Données sélectionnées
Nous utiliserons les données suivantes: [Enquête sur les dépenses des ménages (EDM), dépenses des ménages, selon le mode d'occupation du logement](http://ouvert.canada.ca/data/fr/dataset/ffd02f84-1b13-479f-83a9-35f6d17296c7) provenant du tableau CANSIM 203-0024 de Statistiques Canada. Cette source contient de l'information visée par la [Licence du gouvernement ouvert – Canada](http://ouvert.canada.ca/fr/licence-du-gouvernement-ouvert-canada).

```{r, echo=TRUE}
emd_2016 <- read.table("DATA/02030024-fra.csv",sep=";", header=TRUE, dec = ",", na.strings = c("..","F"), stringsAsFactors = FALSE)
```

Le jeu de données contient les variables suivantes:

- Date_Ref: La date de référence (année)
- GEO: Canada, Province/Territoire
- STAT: Le nom de la statistique
- TENURE: Mode d’occupation du logement
- SUMMARY: Certaines dépenses des ménages (catégorie)
- Vecteur: Un identifiant interne à Statistique Canada
- Coordonnée: Un identifiant interne à Statistique Canada
- Valeur: Le montant de la dépense

La documentation complète se trouve dans le [Guide de l’utilisateur, Enquête sur les dépenses des ménages, 2014](http://www.statcan.gc.ca/pub/62f0026m/2016001/chap4-fra.htm)

## Sélection

On identifie les 20 catégories avec le plus de dépenses, peu importe le mode d'occupation du logement, en excluant les sommaires.
```{r, echo=TRUE}
Top20Summary <- emd_2016 %>% group_by(SUMMARY) %>% 
  summarise(Valeur_totale = sum(Valeur)) %>% 
  arrange(Valeur_totale %>% desc) %>%
  filter(!(SUMMARY %in% list("Dépenses totales","Consommation courante totale"))) %>% 
  head(20) %>%
  select(SUMMARY)
```

## Aggrégation

On sélectionne les valeurs correspondant aux catégories identifiées précédemment, on supprime les sommaires
```{r, echo=TRUE}
agg_emd_2016 <- emd_2016 %>% 
  merge(Top20Summary, all=FALSE) %>% 
  select(Date_Ref, TENURE, SUMMARY, Valeur) %>%
  filter(!(TENURE %in% list("Toutes les classes","Propriétaire"))) %>%
  group_by(TENURE,SUMMARY) %>%
  summarise(m_valeur = mean(Valeur))
```

## Préparation des données

Cette étape permet de créer des colonnes de valeurs séparées par type d'occupation du logement. On utilise la bibliothèque `reshape2`

```{r, echo=TRUE}
cast_agg_emd_2016 <- agg_emd_2016 %>% dcast(SUMMARY ~ TENURE, value.var = "m_valeur")
names_col <- names(cast_agg_emd_2016)
names(cast_agg_emd_2016) <- c("SUMMARY","loc","pah","psh")
top_labels <- names_col[-1]
```
## Graphiques

La fonction `plot_ly()`permet de créer tous les types de graphiques disponibles dans plotly. Il s'agit d'une syntaxe unifiée qui est une approche différente des autres approches de visualisation de données avec R. Pour ajouter des éléments à un graphique existant, on utilise la fonction `add_trace()`. Pour définir les paramètres généraux d'affichage, on utilise la fonction `layout()` qui permet entre autres de définir l'orientation du graphique, les axes, les marges et l'orientation du texte.

### Graphique à barres groupées
On crée un [graphique à barres groupées](https://plot.ly/r/bar-charts/#grouped-bar-chart), qui permetta de comparer la dépense pour le même sommaire par mode d'occupation du logement.

```{r, echo=TRUE}
plot_ly(data = cast_agg_emd_2016, 
        y = ~loc, 
        x = ~SUMMARY, 
        type = 'bar', 
        orientation = 'v', 
        marker = list(color = 'rgba(38, 24, 74, 0.8)',
                      line = list(color = 'rgb(248, 248, 249)',
                                  width = 1.5)),
        name=top_labels[1]) %>%
  add_trace(y = ~pah,
            marker = list(color = 'rgba(71, 58, 131, 0.8)'),
            name=top_labels[2]) %>%
  add_trace(y = ~psh,
            marker = list(color = 'rgba(71, 58, 131, 0.8)'),
            name=top_labels[3]) %>%
  layout(barmode = 'grouped',
         xaxis = list(title = "",
                      tickangle = -45),
         yaxis = list(title = "Montant en $"),
         margin = list(l = 100, b = 100))
```

### Graphiques en pointes de tarte

On fait un graphique en pointes de tarte par mode d'occupation du logement.

**`r top_labels[1]`**
```{r, echo=TRUE}
plot_ly(data = cast_agg_emd_2016, 
        labels = ~SUMMARY, 
        values = ~loc, 
        type = 'pie', 
        marker = list(color = 'rgba(38, 24, 74, 0.8)',
                      line = list(color = 'rgb(248, 248, 249)')),
        name=top_labels[1]) %>% layout(showlegend = FALSE)
```

**`r top_labels[2]`**
```{r, echo=TRUE}
plot_ly(data = cast_agg_emd_2016, 
        labels = ~SUMMARY, 
        values = ~pah, 
        type = 'pie', 
        marker = list(color = 'rgba(38, 24, 74, 0.8)',
                      line = list(color = 'rgb(248, 248, 249)')),
        name=top_labels[1]) %>% layout(showlegend = FALSE)
```

**`r top_labels[3]`**
```{r, echo=TRUE}
plot_ly(data = cast_agg_emd_2016, 
        labels = ~SUMMARY, 
        values = ~psh, 
        type = 'pie', 
        marker = list(color = 'rgba(38, 24, 74, 0.8)',
                      line = list(color = 'rgb(248, 248, 249)')),
        name=top_labels[1]) %>% layout(showlegend = FALSE)
```

# ggplot2

[ggplot2](http://ggplot2.org/) est une bibliothèque développée spécifiquement pour R qui permet de créer des graphiques de qualité professionnelle en utilisant une syntaxe décrivant la "grammaire des graphiques" de Leland Wilkinson: [The Grammar of Graphics](https://www.springer.com/us/book/9780387245447).

ggplot2 est complexe et demande une courbe d'apprentissage par rapport à d'autres outils de visualisation. Par contre, il est possible de construire des graphiques exactement comme on les souhaite avec beaucoup de travail et de patience. Il est aussi possible de construire des thèmes élaborés pouvant être réutilisés dans des publications ou en entreprise. Le meilleur moyen d'apprendre ggplot2 est de consulter la [documentation en ligne](http://docs.ggplot2.org/current/) qui inclut de nombreux exemples.

## Installation

On installe ggplot2 avec cette commande:
```{r, echo=TRUE, eval=FALSE}
install.packages("ggplot2")
```

On importe ggplot2 avec cette commande:
```{r}
library("ggplot2")
```
## Vocabulaire et fonctionnement

Un graphique comprend plusieurs types d'éléments:

- Geoms: Objets géométriques qui définissent le type de graphique
- Statistics: Permettent une transformation des données
- Scales: Permettent de changer l'échelle de l'affichage, que ce soit au niveau des dimensions ou des couleurs
- Coordinate systems: Change la correspondance entre les coordonnées pour un affichage à l'écran
- Faceting: Affiche différentes portions de données dans différents panneaux.
- Position adjustments: Permettent de gérer les superpositions ou d'ajouter du flou dans les données
- Annotation: Ajout d'annotations à un graphique
- Fortify: Utiliser des données qui ne sont pas sous la forme de tables
- Themes: Éléments qui définissent un thème d'affichage, indépendamment du type de graphique
- Aesthetics: Permets d'associer les données à des caractéristiques du graphique: les axes, les couleurs, les épaisseurs de traits ...
- Other: Autres outils

## Exemple

Pour cet exemple, on utilise le jeu de données [Effectif de la fonction publique fédérale par ministère et région](http://open.canada.ca/data/en/dataset/933f8f6e-daee-4368-a7dc-4eadc8b5ecfa) provenant de Secrétariat du Conseil du Trésor du Canada. Cette source contient de l'information visée par la [Licence du gouvernement ouvert – Canada](http://ouvert.canada.ca/fr/licence-du-gouvernement-ouvert-canada).

```{r, echo=TRUE}
ssa_pop2 <- read.csv("DATA/ssa-pop2-fra.csv", sep=",", stringsAsFactors = FALSE) %>% 
  filter(!Province %in% c("À l'étranger","Non disponible")) %>%
  mutate(new_date = ISOdate(floor(Date/100),Date %% 100,1)) %>%
  select(Province,new_date,Employés) %>%
  group_by(Province,new_date) %>%
  summarise(total_employes = sum(Employés)) %>% 
  arrange(Province,new_date)
```

## Graphique à lignes brisées
Nous définissons la structure de bases pour créer notre graphique. Nous identifions les données qui seront utilisées ainsi que les "esthétiques" du graphique.
```{r, echo=TRUE}
g1 <- ggplot(ssa_pop2, aes(x=new_date,y=total_employes))
```

Nous désirons tracer un graphique à à lignes brisées pour représenter ces données, avec une ligne par province.

```{r, echo=TRUE}
g1+geom_line(aes(group=Province))
```

On aimerait plutôt avoir de la couleur !

```{r, echo=TRUE}
g1+geom_line(aes(group=Province, colour=Province))
```

On aimerait aussi mieux séparer les valeurs au bas du tableau. On va donc utiliser une échelle verticale logarithmique.

```{r, echo=TRUE}
g2 <- g1+geom_line(aes(group=Province, colour=Province))+scale_y_log10()
g2
```

On a aussi la possibilité de convertir ce graphique en version interactive avec plotly.
```{r, echo=TRUE}
ggplotly(g2)
```

## Graphique à boîte et moustaches

Un autre type de graphique qui permet d'observer la variation d'une variable (ici par rapport au temps) est le graphique à boîte et moustaches.
```{r, echo=TRUE}
g3 <- ggplot(ssa_pop2, aes(Province, total_employes))
```

On convertis l'axe vertical en échelle logarithmique:
```{r, echo=TRUE}
g3+geom_boxplot(aes(colour=Province))+scale_y_log10()
```

Ce type de graphique n'est pas géré par plotly, nous ne pouvons donc pas le convertir en version interactive.

# ggplot2 et gganimate

L'utilisation combinée des bibliothèques ggplot2 et gganimate nous permettra de créer une animation.

On installe `gganimate` avec la commande suivante, qui nécessite la bibliothèque `devtools` ainsi que le nécessaire pour compiler (le paquet `r-base-dev` sur Debian, R-Tools sur Windows):
```{r, eval=FALSE, echo=TRUE}
devtools::install_github("dgrtwo/gganimate")
```

On charge gganimate
```{r, echo=TRUE}
library(gganimate)
```

## Données

Nous reproduisons ici la [pyramide des âges animée](https://www.donneesquebec.ca/recherche/fr/dataset/pyramide-des-ages-animee) de l'Institut de la statistique du Québec. Les données téléchargées se trouvent dans le fichier [`tbl_bord_0001_35.xml`](http://www.bdso.gouv.qc.ca/docs-ken/flex/xml/tbl_bord_0001_35.xml).

## Transformation des données

On extrait les données d'un fichier XML, puis on prépare les données sur le bon format pour faire une pyramide des âges.
```{r, echo=TRUE}
df_tbl_bord_0001_35 <- xmlToDataFrame("DATA/tbl_bord_0001_35.xml")
df_tbl_bord_0001_35_2 <- df_tbl_bord_0001_35 %>% 
  mutate(AGE = DE_CODFC_REFRN %>% str_extract("([0-9]+)")) %>% 
  select(-c(DE_CODFC_REFRN,DE_DIMNS_UNIT_MESR)) %>% 
  melt(id.vars=c("DE_TERTR_REFRN","DE_TEMPS_REFRN","AGE"),
       measure.vars=c("HOMME","FEMME"),
       variable.name="GENRE",
       value.name = "NOMBRE") %>%
  mutate(NOMBRE = NOMBRE %>% as.integer() %>% ifelse(is.na(.),0,.),
         AGE = AGE %>% as.integer(),
         DE_TEMPS_REFRN = DE_TEMPS_REFRN %>% as.integer())
```

On construit la pyramide des âges. La variable `frame` sera utilisée pour créer chacune des images de l'animation.
```{r, echo=TRUE}
pyramide_ages <- df_tbl_bord_0001_35_2 %>% 
  ggplot(aes(frame = DE_TEMPS_REFRN)) + 
  geom_bar(data=subset(df_tbl_bord_0001_35_2,GENRE=="FEMME"),
           aes(x=AGE,y=NOMBRE,fill=GENRE,group=DE_TEMPS_REFRN),
           stat = "identity", 
           position = "identity") + 
  geom_bar(data=subset(df_tbl_bord_0001_35_2,GENRE=="HOMME"),
           aes(x=AGE,y=-NOMBRE,fill=GENRE,group=DE_TEMPS_REFRN),
           stat = "identity", 
           position = "identity") + 
  scale_y_continuous(breaks=seq(-40000,40000,40000),
                     labels=abs(seq(-40000,40000,40000))) + 
  coord_flip()
```

On l'anime.

```{r interval, echo = FALSE, cache = FALSE}
ani.options(autobrowse = FALSE, interval = .2)
```

```{r, echo = TRUE}
gg_animate(pyramide_ages,"pyramide_ages.gif")
```

![](pyramide_ages.gif)



