Représentation graphique avec R
Tour d’horizon personnel des fonctionnalités graphiques disponibles
Hugues Pecout (CNRS, UMR Géographie-Cités)
Journées annuelles SO-MATE 2023, Limoges
Hugues Pecout, ingénieur d’études CNRS en sciences de l’information géographique
2012-2022 : FR CIST (Collège international des sciences territoriales)
Depuis 2022 : UMR Géographie-Cités
Travail dans le domaine de la géographie humaine et quantitative (et un peu quali !) : collecte, gestion, traitement, enrichissement, analyse (statistique, spatiale, de réseau, textuelle…), représentation graphique et cartographie de données géographiques hétérogènes (données conventionnelles, données d’enquête, IGV, webscraping…).
Spécialisé dans l’utilisation de R depuis 2015
Depuis 2018 : Coordination du projet Rzine
Depuis 2022 : Co-animateur du groupe d’utilisateur·rices ElementR
Depuis 2021 : Membre du Groupe de travail Notebook
✅ Rapide
✅ Facile
Fonctionnalités disponibles :
❌ Graphiques par défault
❌ Types de graphiques
❌ Interactivité
Gestion des données :
❌ Manipulation des données
❌ Statistiques
❌ Données volumineuses
Reproductibilité :
❌ Automatisation du pipeline
❌ Collaboration
❌ Versioning
Mais la représentation graphiques avec Excel connaît des limites…
Des fonctionnalités avancées et des sorties graphiques très élégantes, mais des logiciels payants.
Bon outils si on ne pratique pas R régulièrement, mais limité notamment en matière de reproductibilité.
La version 1.0 de R a été publiée en 2000, mais ce langage est distribué en tant que logiciel Open Source et avec des fonctions graphiques depuis 1995. Au centre de l’ecosystème graphique du R-base : la fonction plot()
Une fonction générique très pratique pour l’exploration, qui s’adapte aux différents types des données.
1 variable quantitative - Nuage de points ordonnés
2 variables quantitatives - Nuage de points
1 variable quanti vs 1 variable quali - Boîte à moustache
Un tableau de données complet - Un seul type de graphique
hist()
: histogramme de distributionstripchart()
: diagrammes de dispersiondotchart()
: diagramme en points de Clevelandboxplot()
: diagramme en boîteqqnorm()
: diagramme quantile-quantile théorique normalqqplot()
: diagramme quantile-quantile empiriquebarplot()
: diagramme à barrespie()
: diagramme en secteursmosaicplot()
: diagramme en mosaïquespineplot()
: diagrammes en épine (entre l’histogramme et le mosaic plot)curve()
: Représentation d’une expression mathématiquematplot()
: Dispersions de toutes le variables d’un tableau (un graphique)pairs()
: Matrice de nuage de point pour l’ensemble des variables d’un tableauNote
En fonction du type de variable, la fonction plot()
renvoie vers les fonctions barplot()
, spineplot()
, stripchart()
, boxplot()
, curve()
, pairs()
…
Histogramme de distribution
Diagrammes de dispersion
Diagrammes en épine
Boîte à moustache
Diagramme en points de Cleveland
Camembert
Une multitude d’arguments permettent de paramétrer la mise en page d’un graphique.
plot(y ~ x,
type = "o", # type de tracé: points ("p"), lignes ("l"), les deux ("b" ou "o"), ...
col = "red", # couleur, tapez `colours()` pour la liste complète
pch = 20, # type de symboles, un chiffre entre 0 et 25, tapez `?points`
cex = 1.1, # taille des symboles
lty = 1, # type de lignes, un chiffre entre 1 et 6
lwd = 1.4, # taille de lignes
xlim = c(-2.5, 2.5), # limites de l'axe des x
ylim = c(-1.5, 1.5), # limites de l'axe des y)
xlab = "La variable x", # titre pour l'axe des x
ylab = "Le sinus de x", # titre pour l'axe des y
main = "La fonction sinus entre -pi et pi" # titre général pour le graphique
)
Plusieurs fonctions permettent d’ajouter des éléments sur un graphique existant.
legend()
: légendetitle()
: titredensity()
: courbe de densité à noyaupoints()
: pointrug()
: représentation stripchart le long de l’axe des xlines()
: segments de droites reliant des pointsmatlines()
: segments de droites reliant des points (utiliser avec matplot()
)abline()
: droites traversant toute la zone graphiquetext()
: texte dans la zone graphiquemtext()
: texte dans la margeplot(y ~ x,
type = "o", # type de tracé: points ("p"), lignes ("l"), les deux ("b" ou "o"), ...
col = "red", # couleur, tapez `colours()` pour la liste complète
pch = 20, # type de symboles, un chiffre entre 0 et 25, tapez `?points`
cex = 1.1, # taille des symboles
lty = 1, # type de lignes, un chiffre entre 1 et 6
lwd = 1.4, # taille de lignes
xlim = c(-2.5, 2.5), # limites de l'axe des x
ylim = c(-1.5, 1.5), # limites de l'axe des y)
xlab = "La variable x", # titre pour l'axe des x
ylab = "Le sinus de x") # titre pour l'axe des y)
# Ajout d'un TITRE
title("Titre de mon graphique",
cex.main = 1.2,
font.main= 4,
col.main= "red4")
# Ajout d'une LEGENDE
legend(x = 0.9, # Emplacement de la légende (coin haut gauche)
y = -1.1, # Emplacement de la légende (coin haut gauche)
legend = "Fonction sinus entre -pi et pi",
bg = "lightgoldenrod",
col = "red",
pch = 20,
cex = 0.7, # Taille de lé lagende
lty = 1,
lwd = 1.4)
# Ajout d'une LIGNE (horizontale)
abline(h = 0, # Coupe l'axe des y à cette valeur
lty = 2, # Type de ligne
lwd = 0.5, # épaisseur
col = "grey50")
# Ajout d'un POINT
points(x = -0,
y = 0,
col = "red4",
pch = 20,# Type de symbol
cex = 4)
# Ajout de TEXTE
text("x = 0 = y", # Texte à afficher
x = 0.4, # Emplacement du texte (centre)
y = -0.16, # Emplacement du texte (centre)
col = "red4")
# Ajout de TEXTE dans la marge
mtext(text = "Source : données complétement fictives", # Texte à afficher
side = 4, # Emplacement (1 = bottom, 2 = left, 3 = top...)
cex = 0.9, # Taille de la police
col = "grey")
Trois fonctions permettent de gérer les paramètres de la fenêtre graphique.
I. par()
pour définir ou interroger les paramètres de la fenêtre graphique.
par(bg = "royalblue1", # Couleur de fond
col= "white", # couleur du graphique
mfrow = c(2,2), # Fenêtre découper en deux lignes / deux colonnes (4 graphiques)
mar = c(5,5,5,5)) # Gestion des marges pour chaque graphique (B,L,T,R)
plot(x = log(1:10), y = 10:1, main = "plot 1")
plot(x = exp(1:10), y = log(1:10), main = "plot 2")
plot(x = sin(1:10), y = 1:10, main = "plot 3")
plot(x = 1:10, y = exp(1:10), main = "plot 4")
II. layout()
propose moins d’arguments mais permet un meilleur ajustement de la disposition des figures.
Avec la matrice ci-dessus, la fenêtre graphique sera paramétrée pour contenir trois graphiques. Le graphique 1 occupera toute la première ligne. le graphique 2 occupera les deux dernières lignes de la première colonne, et le 3e sera situé dans les deux dernières lignes de la dernière colonne.
II. dev.off()
ferme le graphique en cours et réinitialise par défault la fenêtre graphique.
locator()
Attention
Ne fonctionne pas avec tous les packages qui proposent des représentations graphiques sur un système de référence orthonormé différent de celui proposé par défault par la fénétre graphique.
Si il existe déjà un certains nombre de fonctionnalités pour la représentation graphique en R-base, ce socle commun présente des limites. Ces fonctions sont très simples d’utilisation, mais sont à privilégier dans un contexte d’exploration des données car :
Les extensions graphiques
Il existe de nombreux packages qui offrent une palette importante de fonctionnalités pour la production de graphiques spécifiques et élégants, en seulement quelques lignes de code…
ggplot2
ggplot2
Le package lattice
(Sarkar 2008), sortie en 2001, vise à améliorer les graphiques de base de R en fournissant des valeurs par défaut améliorées et une visualisation simplifiée des relations multivariées.
L’une de ses principales caractéristiques est la prise en charge de la création de graphiques en treillis, qui permettent d’afficher des variables ou des relations entre variables, conditionnées par une ou plusieurs autres variables.
Note
Ce package apporte des fonctionnalités supplémentaires aux fonctions graphiques R-base. Cependant, le rendu graphique reste rudimentaire.
ggplot2
(2007 - 2012)le package ggplot2
(Wickham 2016) est une véritable révolution en matière de représentation graphique, qui dépasse le périmètre de la communauté R. Ce package :
ggplot2
, au delà de R…La syntaxe de la grammaire des graphiques, implementée dans un premier temps en langage R, a été reprise et adaptée dans plusieurs langages de programmation.
La grammaire des graphiques avec ggplot2
:
altair
)vegalite
)Plot
)ggplot2
De nombreuses extensions de ggplot2
ont été développées et offrent de nouvelles fonctionnalités en matière de mise en forme, de types de représentation graphique, d’animation, d’intéractivité, d’objet pris en compte…
esquisse
, pour se lancer !esquisse
est un package français (Meyer et Perrier 2022). C’est l’une des extensions ggplot2
les plus téléchargées. Il s’agit d’un addin (shiny) pour créer des graphiques ggplot2
de manière interactive, puis récupérer le code R généré automatiquement.
ggplot2
, de la customization avancée…X-Men Characters, by Cedric Scherer
Best selling Authors, by Tania Shapiro
Spatio-temporal Wikidata. Exploration de données ouvertes et liées du web 3.0, par R. Krummeich, H. Pecout & S. Rey-Coyrehourcq
https://rzine-reviews.github.io/wikidata_sparql_rzine/#content
Thomas Lin Pedersen (Rstudio)
De nombreuses palettes de couleurs sont directement disponibles en R-base :
Au cas où, près de 70 (!) packages proposent des palettes de couleurs
paletteer
(Hvitfeldt 2021) propose 2587 palettes (compilation)cols4all
(Tennekes 2023), une application shiny pour les explorerFactoMineR
(Lê, Josse, et Husson 2008)
Et ses packages d’exploration et de visualisation associés : FactoInvestigate
, factoextra
, Factoshiny
# Compute PCA on the iris data set
# The variable Species (index = 5) is removed
# before PCA analysis
iris.pca <- PCA(iris[,-5], graph = FALSE)
# Visualize
# Use habillage to specify groups for coloring
fviz_pca_ind(iris.pca,
label = "none", # hide individual labels
habillage = iris$Species, # color by groups
palette = c("#00AFBB", "#E7B800", "#FC4E07"),
addEllipses = TRUE # Concentration ellipses
)
explor
(Barnier 2023)
wordcoud
(Fellows 2018)
wordcoud2
(Lang et Chien 2018)
Ou ggwordcloud
et ggwordcloud2
si vous préférez la syntaxe ggplot.
igraph
(Csárdi et al. 2023)
# Mise en page d
plot(karate,
vertex.color = V(karate)$Faction, # couleur des sommets
vertex.frame.color = "white", # couleur des contours des sommets
vertex.shape = "square", # forme des sommets
vertex.size = degree(karate), # taille des sommets
vertex.label = NA, # étiquettes des sommets
vertex.label.degree = 0, # position / au centre du sommet (0 = droite, "pi"= gauche)
edge.color = "goldenrod3", # couleur des arêtes
edge.curved=.1, # courbure des arêtes (0 = droit)
# arrow.mode = 3, # type de flèche
# edge.arrow.size = 12, # taille de la pointe de la flèche
edge.width = E(karate)$weight, # largeur des arêtes
edge.lty = 1, # type de trait (1=plein, 2=pointillés, 3=points...)
margin = c(0,0,0.2,0), # marges
main = graph_attr(karate, "name"), # titre principal
sub = graph_attr(karate, "Author"), # sous-titre
layout = layout_(karate, with_lgl())) # sous-titre
ggraph
(Pedersen 2022)
library(ggraph)
library(tidygraph)
library(tidyverse)
# Create graph of highschool friendships
graph <- as_tbl_graph(highschool) %>%
mutate(Popularity = centrality_degree(mode = 'in'))
# plot using ggraph
ggraph(graph, layout = 'kk') +
geom_edge_fan(aes(alpha = after_stat(index)), show.legend = FALSE) +
geom_node_point(aes(size = Popularity)) +
facet_edges(~year) +
theme_graph(foreground = 'steelblue', fg_text_colour = 'white')
TraMineR
library(TraMineR)
data(mvad)
mvad.alphabet <- c("employment", "FE", "HE", "joblessness", "school", "training")
mvad.labels <- c("employment", "further education", "higher education", "joblessness", "school", "training")
mvad.scodes <- c("EM", "FE", "HE", "JL", "SC", "TR")
mvad.seq <- seqdef(mvad, 17:86,
alphabet = mvad.alphabet,
states = mvad.scodes,
labels = mvad.labels,
xtstep = 6)
par(mfrow = c(2, 2))
seqiplot(mvad.seq, with.legend = FALSE, border = NA, main = "The first 10 sequences in the mvad.seq sequence object")
seqIplot(mvad.seq, sortv = "from.start", with.legend = FALSE, main = "All the sequences in the data set, sorted by states from start")
seqfplot(mvad.seq, with.legend = FALSE, border = NA, main ="The 10 most frequent sequences.")
seqlegend(mvad.seq)
superheat
(Barter et Yu 2017)
ComplexHeatmap
(Gu 2022)
circlize
(Gu et al. 2014)
Scatterplot3D
(Ligges et Mächler 2003)
library(scatterplot3d)
shapes = c(16, 17, 18)
shapes <- shapes[as.numeric(iris$Species)]
colors <- c("#999999", "#E69F00", "#56B4E9")
colors <- colors[as.numeric(iris$Species)]
s3d <- scatterplot3d(iris[,1:3],
pch = shapes,
color= colors )
legend("bottom", legend = levels(iris$Species),
col = c("#999999", "#E69F00", "#56B4E9"),
pch = c(16, 17, 18),
inset = -0.25, xpd = TRUE, horiz = TRUE)
sf
(Pebesma 2018)
Pour importer, manipuler, traiter et afficher des données géographiques vectorielles.
Reading layer `mtq' from data source
`C:\Users\HP\Desktop\SO_MATE_2023\data\mtq.gpkg' using driver `GPKG'
Simple feature collection with 34 features and 7 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 690574 ymin: 1592536 xmax: 735940.2 ymax: 1645660
Projected CRS: WGS 84 / UTM zone 20N
terra
(Hijmans 2023)
Pour importer, manipuler, traiter et afficher des données géographiques raster (avec vecteur).
mapsf
(Giraud 2022)
Pour produire des cartes thématiques.
mf_theme("agolalight", bg = "ivory1")
mf_export(
x = mtq, filename = "images/mtq.png",
width = 600, res = 120,
expandBB = c(0, 0, 0, .3)
)
mf_shadow(mtq, col = "grey90", add = TRUE)
mf_map(
x = mtq, var = "MED", type = "choro",
pal = "Dark Mint",
breaks = "quantile",
nbreaks = 6,
leg_title = "Median Income\n(euros)",
leg_val_rnd = -2,
add = TRUE
)
mf_inset_on(x = "worldmap", pos = "right")
mf_worldmap(mtq, col = "#0E3F5C")
mf_inset_off()
mf_title("Wealth in Martinique, 2015")
mf_credits("T. Giraud\nSources: INSEE & IGN, 2018")
mf_scale(size = 5)
mf_arrow("topleft")
dev.off()
tmap
(Tennekes 2018)
Pour produire des cartes thématiques statique ou intéractive avec la syntaxe ggplot.
Ou encore ggplot2
& ggmap
(Kahle et Wickham 2013)
Il est possible de crée un GIF ou une vidéo à partir de plusieurs images avec R. L’étendue des possibilités de réaliser des animation graphique est donc large… Mais il faut être prêt à bricoler !
Heureusement, plusieurs packages facilitent la création de représentations graphiques animées, en mettant des fonctions simple d’utilisation à disposition.
gganimate
(Pedersen et Robinson 2022)
library(gganimate)
ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +
geom_point(alpha = 0.7, show.legend = FALSE) +
scale_colour_manual(values = country_colors) +
scale_size(range = c(2, 12)) +
scale_x_log10() +
facet_wrap(~continent) +
labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') +
transition_time(year) +
ease_aes('linear')
t_map
(Tennekes 2018)
library(tmap)
data(World, metro)
m4 <- tm_shape(World) +
tm_polygons() +
tm_shape(metro) +
tm_bubbles(col = "red") +
tm_text("name", ymod = -1) +
tm_facets(by = "name", free.coords = F, nrow = 1, ncol = 1) +
tm_layout(panel.show = FALSE, frame = FALSE)
tmap_animation(m4,
filename = "World_cities.mp4",
width=1200,
height = 600,
fps = 1,
outer.margins = 0)
Exemple personnel ggplot2
+ gganimate
https://gitlab.huma-num.fr/hpecout/courbe_rotative
Le langage R, seul, ne permet pas de produire de représentation graphique interactive. Cette fonctionnalité est accessible grâce au langage javascript (+ un navigateur web). Il est possible de créer des htmlwidgets, des packages qui permettent de faire un lien avec des librairies javascript…
Quelques exemples :
leaflet
(Cheng, Karambelkar, et Xie 2023)
Reading layer `mtq' from data source
`C:\Users\HP\Desktop\SO_MATE_2023\data\mtq.gpkg' using driver `GPKG'
Simple feature collection with 34 features and 7 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 690574 ymin: 1592536 xmax: 735940.2 ymax: 1645660
Projected CRS: WGS 84 / UTM zone 20N
mapview
(Appelhans et al. 2022)
mapdeck
(Cooley 2020)
networkD3
(Allaire et al. 2017)
data <- data.frame(
from=c("A", "A", "B", "D", "C", "D", "E", "B", "C", "D", "K", "A", "M"),
to=c("B", "E", "F", "A", "C", "A", "B", "Z", "A", "C", "A", "B", "K")
)
library(networkD3)
simpleNetwork(data , height="100px", width="100px",
Source = 1, # column number of source
Target = 2, # column number of target
linkDistance = 10, # distance between node. Increase this value to have more space between nodes
charge = -900, # numeric value indicating either the strength of the node repulsion (negative value) or attraction (positive value)
fontSize = 14, # size of the node names
fontFamily = "serif", # font og node names
linkColour = "#666", # colour of edges, MUST be a common colour for the whole graph
nodeColour = "#69b3a2", # colour of nodes, MUST be a common colour for the whole graph
opacity = 0.9, # opacity of nodes. 0=transparent. 1=no transparency
zoom = T # Can you zoom on the figure?
)
visNetwork
(Almende B.V. and Contributors et Thieurmel 2022)
rgl
(Murdoch et Adler 2023)
plotly
(Sievert 2020)
Ce package est également compatible avec les graphiques ggplot2
, qu’il peut rendre intéractif.
Et aussi :
rbokeh
(Hafen et Continuum Analytics, Inc. 2021)
highcharter
(Kunst 2022)
echarts4r
(Coene 2023)
robservable
(Barnier et Russell 2022)
eps, ps, tex, pdf, jpeg, tiff, png, bmp, svg, wmf
En clic-bouton avec Rstudio :
L’export de GIF, de mp4, html… pour les représentations animées s’effectue automatiquement via des fonctions mis à disposition pas des packages.
Rmarkdown & Quarto
shiny
Le réseau des routes de poste en France de 1632 à 1833
Nicolas Verdier, Anne Bretagnolle. L’extension du réseau des routes de poste en France, de 1708 à 1833. Histoire des réseaux postaux en Europe du XVIIIe au XXIe siècle, May 2007, Paris, France. pp.155-193. ⟨halshs-00144693⟩
Les relais de poste
Couche de points géoréférencés x 8
Les routes postales
Couche de lignes géoréférencées x 8
Soit 8 cartographie du réseau des routes de poste en France entre 1632 et 1833.
Des relais caractérisés par des variables (attributs)
Ex: Relais de 1833
Des routes caractérisées par des variables (attributs)
Ex: Routes de 1833
1. Représentation de réseau avec igraph
2. Cartographie avec mapsf
Télécharger le projet Rstudio (.zip)
igraph
Pour aller plus loin :
Documentation du package igraph
(Csárdi et al. 2023) :
mapsf
Pour aller plus loin :
Documentation du package mapsf
(Giraud 2022) :
Une remarque ? Une question ? Une proposition d’amélioration pour mapsf
?
Plusieurs passages sont fortement inspirés de supports existant, mis gracieusement en ligne par leur auteurs. Trois supports de communication ont principalement été utilisés :
R dans l’univers de la Dataviz, Yan Holtz, RencontresR 2023, Avignon, 2023 - Disponible en ligne, Enregistrement vidéo disponible sur Youtube
Représentation graphique avec R, ggplot2 et la grammaire graphique, Robin Cura, Léa Cristophe, Groupe ElementR, Aubervilliers, 2023 - Disponible en ligne
L’écosystème spatial de R, Timothée Giraud, RencontresR 2023, Avignon, 2023 - Disponible en ligne, Enregistrement vidéo disponible sur Youtube
Merci de votre attention
hugues.pecout@cnrs.fr
Diaporama : https://HuguesPecout.github.io/SO_MATE_2023/
Code source : https://github.com/HuguesPecout/SO_MATE_2023
Journées annuelles SO-MATE 2023 - Représentations graphiques avec R