9. Quelques outils de visualisation dynamique/interactive
Tout comme leaflet pour les cartes, il existe de nombreux outils R dédiés à la visualisation interactive. Nous en présentons quelques uns dans cette partie.
Représentations classiques avec rAmCharts, plotly et highcharter
Le package rAmCharts est très utile pour donner un caractère interactif à des représentations graphiques standards (nuages de points, séries temporelles, histogrammes…). Ce package a été fait dans l’esprit d’utiliser les fonctions graphiques de R en ajoutant le préfixe am. La syntaxe est très proche de celle des fonctions graphiques standards. On a par exemple :
library(rAmCharts)
amHist(iris$Petal.Length)amPlot(iris, col = colnames(iris)[1:2], type = c("l", "st"),
zoom = TRUE, legend = TRUE)amBoxplot(iris)plotly permet de faire des choses semblables avec avec une syntaxe spécifique. Les commandes plotly se décomposent essentiellement en 3 parties :
- le type de représentation graphique (plot_ly}) ;
- les ajouts que l’on souhaite effectuer (add_trace) ;
- la gestion de la fenêtre graphique (axes, titres…) (layout).
On trouvera un descriptif complet de ces 3 composantes ici. On propose de tracer un nuage de points en dimension 2 et d’y ajouter la droite de régression. On commence par générer le nuage et ajuster le modèle linéaire :
library(plotly)
n <- 100
X <- runif(n,-5,5)
Y <- 2+3*X+rnorm(n,0,1)
D <- data.frame(X,Y)
model <- lm(Y~X,data=D)On effectue maintenant le tracé
D |> plot_ly(x=~X,y=~Y) |>
add_markers(type="scatter",mode="markers",
marker=list(color="red"),name="Nuage") |>
add_trace(y=fitted(model),type="scatter",mode='lines',
name="Régression",line=list(color="blue")) |>
layout(title="Régression",xaxis=list(title="abscisse"),
yaxis=list(title="ordonnées"))Contrairement à ggplot, plotly permet de faire de la 3D. Par exemple
plot_ly(z = volcano, type = "surface")plot_ly(z = volcano, type = "contour")Il est possible de convertir des graphes ggplot au format plotly avec la fonction ggplotly :
p <- ggplot(iris)+aes(x=Species,y=Sepal.Length)+geom_boxplot()+theme_classic()
ggplotly(p)highcharter est un package R basé sur la librairie JavaScript Highcharts. Il pproduit des graphiques interactifs, élégants et hautement personnalisables, et est très bien adapté pour des applications web, dashboards (Shiny, Flexdashboard, quarto), ou rapports interactifs.
On peut par exemple faire un nuage de points avec
library(highcharter)
hchart(iris, "scatter",
hcaes(x = Sepal.Length, y = Sepal.Width,
group = Species))Pour un diagramme en barres
data <- iris |> count(Species)
highchart() |>
hc_chart(type = "column") |>
hc_xAxis(categories = data$Species) |>
hc_add_series(name = "Effectif", data = data$n) |>
hc_title(text = "Nombre d'individus par espèce") |>
hc_add_theme(hc_theme_google())Highcharter est également souvent utilisé pour des séries temporelles :
library(forecast)
airforecast <- forecast(auto.arima(AirPassengers), level = 95)
hchart(airforecast)Exercice 1 (Graphes standards avec rAmCharts et plotly) Pour le jeu de données iris on effectuera les graphes suivants en rAmCharts et plotly.
Nuage de points représentant les longueurs et largeurs de Sépales. On utilisera une couleur différente en fonction de l’espèce.
Boxplot permettant de visualiser la distribution de la variable
Petal.Lengthen fonction de l’espèce.
Exercice 2 (Plotly pour visualiser espérance de vie vs PIB) On considère les données gapminder :
library(gapminder)
head(gapminder)# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
Pour une année de votre choix, faire un nuage de points représentant l’espérance de vie en fonction du PIB par habitant, en utilisant
plot_lyetadd_markers.Animer le graphe précédent en faisant bouger les points en fonctions de l’année.
Exercice 3 (Highcharter)
Faire le diagramme en barres de la variable
cutdu jeu de donnéesdiamondsen utilisant le packagehighcharter.Faire le même graphe en utilisant les fonctions
highchartethc_add_serieset ajouter un tooltip qui affiche l’effectif de chaque modalité decut.Ajouter un graphique en secteurs (pie chart) représentant la répartition des modalités de
cutdans le même graphique.
Exercice 4 (Séries temporelles avec highcharter) On reprend les données gapminder et on calcule l’espérance de vie moyenne en fonction du continent et de l’année avec
don <- gapminder |>
group_by(year,continent) |>
summarize(lifeExp = mean(lifeExp)) |>
mutate(year=ymd(paste0(year,"01-01")))
head(don)# A tibble: 6 × 3
# Groups: year [2]
year continent lifeExp
<date> <fct> <dbl>
1 1952-01-01 Africa 39.1
2 1952-01-01 Americas 53.3
3 1952-01-01 Asia 46.3
4 1952-01-01 Europe 64.4
5 1952-01-01 Oceania 69.3
6 1957-01-01 Africa 41.3
Représenter l’évolution de l’espérance de vie pour chaque continent avec
highcharter.Ajouter l’option
type=stockdanshighchartet analyser la sortie.
Dynamiser ggplot2 avec gganimate et ggiraph.
ggiraph est une extension de ggplot2 qui produit des graphes interactifs. On pourra trouver une documentation complète à l’url https://www.ardata.fr/ggiraph-book/. D’une façon générale, les graphes s’obtiennent en utilisant la syntaxe de ggplot2 et en ajoutant le suffixe _interactive aux fonctions geom. Par exemple
library(ggiraph)
p <- ggplot(data=iris) +
aes(x=Sepal.Length,y=Sepal.Width,
tooltip=Petal.Width,data_id=Species) +
geom_point_interactive(size=3,hover_nearest=TRUE)On visualise le graphe avec la fonction girafe :
girafe(ggobj = p)Le graphe est dynamique dans le sens où lorsque la souris approche un point
- les points de la même espèce que le point où se trouve la souris se colorie (option
data_id) ; - la largeur de pétale du point s’affiche (option
tooltip).
Il est bien entendu possible de personnaliser le caractère dynamique. On peut par exemple introduire du css pour changer la couleur (ou les autres attributs) des points qui se colorient lorsque la souris parcourt le graphe :
girafe(ggobj = p,
options=list(
opts_hover(css="fill:yellow;stroke:black;stroke-width:2px;")
)
)Le coté interactif peut s’obtenir en permettant à l’utilisateur de sélectionner des parties du graphe, par exemple des individus sur une nuage de points
preselection <- iris$Species[1]
girafe(ggobj = p,
options=list(
opts_selection(
selected = preselection,
css="fill:yellow;stroke:black;stroke-width:1px;",
type="single",only_shiny = FALSE
)
))gganimate est un package qui permet de faire des animations à partir de graphes ggplot2. Il est très utile pour visualiser l’évolution d’une variable au cours du temps ou d’une autre variable. On pourra trouver une documentation complète à l’url https://gganimate.com/.
On peut par exemple animer un nuage de points des iris en faisant bouger les points en fonction de l’espèce avec :
library(gganimate) #nécessite le package gikski
ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
geom_point() +
transition_states(Species, transition_length = 2,
state_length = 1) +
labs(title = "Espèce : {closest_state}")
Exercice 5 (Diagramme en barres dynamique) On considère le graphe diagramme en barres suivant
ggplot(diamonds)+aes(x=cut,fill=color)+geom_bar()
Créer un graphe dynamique qui permet de visualiser la valeur de la variable
color(la lettre) lorsque la souris parcourt sur le graphe.Faire la même chose en affichant cette fois les effectifs de la classe à la place de la valeur de
color. On pourra utiliser la fonctionafter_statAjouter au graphe précédent une sélection qui identifie toutes les barres d’une même valeur de
color(en les coloriant en rouge).
Exercice 6 (gganimate : syntaxe)
Crée un tibble avec trois colonnes :
x(allant de 1 à 10),y(égal à 1) ettime(identique à x).Utilise ggplot pour afficher le point (
geom_point), etgganimatepour animer le déplacement du point au fil du temps.Arrangez-vous pour que la frame de l’animation suive la colonne
time: c’est à dire qu’on passe directement du point 1 au point 2 puis 3…
Exercice 7 (Animations sur un nuage de points) On considère les données gapminder :
library(gapminder)
head(gapminder)# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
et le graphe suivant
big_countries <- c("China", "India", "United States", "Brazil", "Russia")
p <- ggplot(gapminder, aes(
x = gdpPercap,
y = lifeExp,
size = pop,
color = continent
)) +
geom_point(alpha = 0.7, show.legend = TRUE) +
scale_x_log10() +
scale_size(range = c(2, 14), guide = "none") +
geom_text(
data = filter(gapminder, country %in% big_countries),
aes(label = country),
color = "black", size = 3, vjust = -1, show.legend = FALSE
) +
labs(
title = "Espérance de vie vs PIB par habitant",
x = "PIB par habitant (log)",
y = "Espérance de vie (années)",
color = "Continent"
)
p
qui permet de visualiser l’espérance de vie en fonction du PIB pour toutes les années.
Créer un graphique similaire à celui ci-dessus en animant le graphique pour chaque année.
Contrôler la vitesse de l’animation avec
animate.
Graphes pour visualiser des réseaux avec visNetwork
De nombreuses données peuvent être visualisées à l’aide d’un graphe, notamment lorsqu’il s’agit de représenter des connexions entre individus. Un individu est alors représentés par un noeud et les individus connectés sont reliés par des arêtes. Le package igraph propose une visualisation statique d’un réseau. Pour donner un caractère dynamique à ce type de représentation, on pourra utiliser le package visNetwork. Une représentation standard visNetwork s’effectue en spécifiant les nœuds et connexions d’un graphe, par exemple :
nodes <- tibble(id = 1:15, label = paste("Id", 1:15),
group=sample(LETTERS[1:3], 15, replace = TRUE))
edges <- tibble(from = trunc(runif(15)*(15-1))+1,to = trunc(runif(15)*(15-1))+1)
library(visNetwork)
visNetwork(nodes,edges)visNetwork(nodes, edges) |> visOptions(highlightNearest = TRUE)visNetwork(nodes, edges) |> visOptions(highlightNearest = TRUE,
nodesIdSelection = TRUE)
visNetwork(nodes, edges) |> visOptions(selectedBy = "group")Exercice 8 (Interactions entre media) On considère un graphe qui représente des liens entre différents médias. Les données sont présentées ici et on peut les importer avec
nodes <- read_csv("data/Dataset1-Media-Example-NODES.csv")
links <- read_csv("data/Dataset1-Media-Example-EDGES.csv")
head(nodes)# A tibble: 6 × 5
id media media.type type.label audience.size
<chr> <chr> <dbl> <chr> <dbl>
1 s01 NY Times 1 Newspaper 20
2 s02 Washington Post 1 Newspaper 25
3 s03 Wall Street Journal 1 Newspaper 30
4 s04 USA Today 1 Newspaper 32
5 s05 LA Times 1 Newspaper 20
6 s06 New York Post 1 Newspaper 50
head(links)# A tibble: 6 × 4
from to weight type
<chr> <chr> <dbl> <chr>
1 s01 s02 10 hyperlink
2 s01 s02 12 hyperlink
3 s01 s03 22 hyperlink
4 s01 s04 21 hyperlink
5 s04 s11 22 mention
6 s05 s15 21 mention
L’objet nodes représente les nœuds du graphe et l’objet links les arêtes. On définit l’objet graphe avec
library(igraph)
media <- graph_from_data_frame(d=links, vertices=nodes, directed=T)
V(media)$name <- nodes$mediaet on peut le visualiser en faisant un plot de cet objet
plot(media)
Visualiser ce graphe avec VisNetwork. On pourra utiliser la fonction toVisNetworkData.
Ajouter une option qui permette de sélectionner le type de media (Newspaper, TV ou Online).
Utiliser une couleur différente pour chaque type de media.
Faire des flèches d’épaisseur différente en fonction du poids (weight). On pourra également ajouter l’option visOptions(highlightNearest = TRUE).
Dashboard
Un tableau de bord permet de visualiser “facilement” et “rapidement” divers graphes et/ou résumés statistiques en lien avec une problématique donnée. Sur R le package flexdashboard permet de construire de tels tableaux de bord. On trouvera un descriptif précis de ce package à cette url : https://rmarkdown.rstudio.com/flexdashboard/. Quarto vient également de proposer de construire des dashboard en utilisant l’entête
---
title: "Mon dashboard"
author: "LR"
format: dashboard
--- La documentation est disponible à cet url : https://quarto.org/docs/dashboards/. On utilisera cette documentation pour faire l’exercice suivant.
Exercice 9 (Dashboard pour modèles linéaires) On considère le jeu de données ozone.txt. Le problème est d’expliquer la concentration maximale en ozone quotidienne (variable maxO3) par d’autres variables météorologiques (températures et indicateurs de nébulosité relevés à différents moments de la journée…). On souhaite faire un tableau de bord qui permettra de :
visualiser les données : la base de données ainsi qu’un ou deux graphes descriptifs sur la variable à expliquer ;
visualiser les modèles linéaires simples : on choisit une variable explicative et on visualise le graphe de la régression ainsi que le modèle ;
visualiser le modèle linéaire complet : on affiche le résultat de la régression avec toutes les variables et on représente le graphe des résidus ;
choisir les variables explicatives du modèle et afficher les sorties;
Avant de réaliser le dashboard, on propose d’écrire quelques commandes pour calculer les différentes sorties :
On considère uniquement les variables quantitatives du jeu de données. Visualiser les corrélations entre ces variables à l’aide de la fonction
corrplotdu packagecorrplot.Représenter l’histogramme de la variable maxO3, on fera le graphe avec
ggplot,rAmCharts,plotly(en utilisantggplotlypar exemple) etggiraph.Construire le modèle linéaire permettant d’expliquer maxO3 par les autres variables. Calculer les résidus studentisés (
rstudent) et visualiser ces résidus en fonction de la variable maxO3. Là encore on pourra ajouter un lisseur sur le graphe.
On peut maintenant passer au tableau de bord. Créer un document quarto et y insérer l’entête pour faire le tableau de bord et cnstruire un premier onglet permettant de visualiser
le jeu de données sur une colonne (on pourra utiliser la fonction datatable du package DT).
l’histogramme de la variable
maxO3ainsi que la matrice des corrélations entre les variables quantitatives sur une deuxème colonne.
On pourra utiliser la structure suivante :
# Statistiques descriptives ## column {width=60%} ### Données ``{r} #| title: Les données ... ``` ## column {width=40%} ### Row ``{r} #| title: Matrice des corrélations ``` ### Row ``{r} #| title: La variable à expliquer ```Ajouter un nouvel onglet qui permet de visualiser le summary du modèle linéaire complet. On pourra utiliser la fonction datatable du package
DT. Indication : ce nouvel onglet peut se créer avec``` markdown Name of the tab ===================================== ```Ajouter un nouvel onglet qui permet de visualiser un modèle linéaire simple avec la variable explicative de votre choix. On pourra afficher dans cet onglet le summary du modèle ainsi que le nuage de points et la droite de régression.
Pour aller plus loin : ajouter un dernier onglet qui permette à l’utilisateur de choisir la variable explicative du modèle simple. Indications : on pourra utiliser les commandes
ShinyChoix de la variable
radioButtons("variable1", label="Choisir la variable explicative", choices=names(df)[-1], selected=list("T9"))Mise à jour du résumé et du graphe interactif. Il faut définir un chunk server avec l’otion
#| context: serverpour calculer les sorties :mod1 <- reactive({ XX <- paste(input$variable1,collapse="+") form <- paste("maxO3~",XX,sep="") |> formula() lm(form,data=df) } ) output$sum1 <- DT::renderDT({ mod.sum1 <- summary(mod1())$coefficients |> round(3) |> as.data.frame() DT::datatable(mod.sum1,options = list(dom = 't')) }) output$resplotly <- renderPlotly({ (ggplot(df)+ aes(x=!!as.name(input$variable1),y=maxO3)+ geom_point()+geom_smooth(method="lm")) %>% ggplotly() })
Enfin il ne faudra pas oublier d’ajouter
server: shinyAjouter un dernier onglet permettant de choisir les variables explicatives dans le modèle linéaire. Là encore on pourra utiliser des commandes Shiny, par exemple
checkboxGroupInput("variable", label="Choisir la variable", choices=names(df)[-1], selected=list("T9"))Pour les variables choisies, on affichera dans ce nouvel onglet les coefficients du modèle linéaire ainsi que le graphe des résidus studentisés.
Le tableau de bord finalisé pourra ressembler à
Il est disponible à l’url https://lrouviere.shinyapps.io/dashboard/.