Dessine moi un arbre…

Auteur : Murielle Delmotte
Tags : Ressources
Date :

Si vous cherchez à dessiner un arbre sur R, que ce soit un arbre de décision ou un arbre généalogique … vous trouverez ici une méthode simple pour le réaliser.

Qu’est ce qu’un arbre?

Les arbres sont des graphes connexes et sans cycle.

  • Connexe signifie qu’il existe toujours un chemin pour relier les différents points de l’arbre.
  • Sans cycle car on ne peut pas partir et aboutir à un même point sans emprunter deux fois le même chemin.

Les arbres sont composés de sommets et d’arêtes. Un arbre de n sommets comporte donc exactement n-1 arêtes.

Les packages utilisés

Pour réaliser ces arbres, nous allons utiliser {igraph} et {ggraph}:

  • {igraph} met à disposition un ensemble de données et de fonctions pour la manipulation de graphes
  • {ggraph} est une extension de {ggplot2} adaptée à la création d’arbres.
library(igraph)
library(ggraph)

Un premier arbre avec {igraph} et {ggraph}

Considérons un jeu de données précisant le chainage Parent/Enfant:

library(tibble)
tbl_edges <- tibble(parent = c("Origin", "Origin", "Resp_1", "Resp_1", "Resp_2"), 
                    child = c("Resp_1", "Resp_2","Resp_1_1", "Resp_1_2", "Resp_2_1")
  )

La 1ere étape consistera à transformer ce jeu de données en un graphe de type igraph.
Il contiendra la liste des arêtes et des sommets ainsi que leurs attributs.
Pour cela nous utilisons la fonction graph_from_data_frame() du package {igraph}

myigraph <- graph_from_data_frame(d = tbl_edges)
myigraph
## IGRAPH ac441fc DN-- 6 5 -- 
## + attr: name (v/c)
## + edges from ac441fc (vertex names):
## [1] Origin->Resp_1   Origin->Resp_2   Resp_1->Resp_1_1
## [4] Resp_1->Resp_1_2 Resp_2->Resp_2_1

L’igraph est composé de sommets (vertices) :

V(myigraph)
## + 6/6 vertices, named, from ac441fc:
## [1] Origin   Resp_1   Resp_2   Resp_1_1 Resp_1_2 Resp_2_1

et d’arêtes (edges):

E(myigraph)
## + 5/5 edges from ac441fc (vertex names):
## [1] Origin->Resp_1   Origin->Resp_2   Resp_1->Resp_1_1
## [4] Resp_1->Resp_1_2 Resp_2->Resp_2_1

Pour visualiser l’arbre, nous utiliserons la fonction ggraph() du package {ggraph}

Le choix de la mise en page est à définir selon 2 paramètres:

  • layout: le type de mise en page.
    Pour un arbre standard, il convient d’utiliser "igraph".
  • algorithm: le type d’algorithme de mise en page à appliquer.
    Ici "tree" permet de spécifier que le parent devra être centré au-dessus de ses enfants.
ggraph(myigraph, layout = "igraph", algorithm = "tree") +
      geom_edge_link() +
      geom_node_label(aes(label = name))

Il existe un grand nombre d’algorithme permettant une mise en page différente.
Par exemple l’algorithme "circle" place les nœuds dans un cercle dans l’ordre de leur index.

 

Modifier l’apparence des arêtes en fonction d’une variable

Pour modifier l’apparence de chaque arête (par exemple leurs couleurs), il faut leur ajouter des attributs.

Cela peut se faire avant ou après la création du igraph.

Avant : dans le jeu de données initial

Toute nouvelle colonne de votre jeu de données sera considérée comme des attributs des arêtes.

tbl_edges <- tibble(parent = c("Origin", "Origin", "Resp_1", "Resp_1", "Resp_2"), 
                    child = c("Resp_1", "Resp_2","Resp_1_1", "Resp_1_2", "Resp_2_1"),
                    col_edge = c("blue", "blue","red","violet", "green")
                    )
graph_from_data_frame(d = tbl_edges)
## IGRAPH d29424a DN-- 6 5 -- 
## + attr: name (v/c), col_edge (e/c)
## + edges from d29424a (vertex names):
## [1] Origin->Resp_1   Origin->Resp_2   Resp_1->Resp_1_1
## [4] Resp_1->Resp_1_2 Resp_2->Resp_2_1

Après : directement à partir du igraph

En utilisant la fonction set_edge_attr() :

myigraph_with_color<- myigraph %>% 
set_edge_attr("col_edge", 
              value = c("blue", "blue","red","violet", "green"))

Utiliser la variable pour les arêtes sur le graph

Quelque soit la méthode utilisée, les attributs sont ensuite utilisables dans les fonctions de {ggraph}:

ggraph(myigraph_with_color, 
             layout = "igraph", 
             algorithm = "tree") +
      geom_edge_link(aes(colour = col_edge)) +
      scale_edge_colour_identity() +
      geom_node_label(aes(label = name))

 

Modifier l’apparence des sommets en fonction d’une variable

Pour modifier l’apparence de chaque sommet, il suffit de leur ajouter des attributs.
Encore une fois, cela peut se faire avant ou après la création du igraph.

Avant : dans le jeu de données initial.

Les attributs des sommets doivent être passé dans le paramètre vertice de la fonction graph_from_data_frame.

Ce paramètre sera un dataframe dont :

  • la 1ere colonne correspond au nom du sommet (tel que retrouvé dans le jeu de données passé en paramètre d de la fonction graph_from_data_frame).
  • un ensemble de colonnes supplémentaires pour chaque attributs
tbl_vertices <- tibble(
  "node" = c("Origin","Resp_1", "Resp_2","Resp_1_1", "Resp_1_2", "Resp_2_1"),
  "label" = c("Origin","Response 1", "Response 2","Response 1 1", "Response 1 2", "Response 2 1"),
  "fill" = terrain.colors(6)
  )
graph_from_data_frame(d = tbl_edges, vertice = tbl_vertices)
## IGRAPH d4ce6e1 DN-- 6 5 -- 
## + attr: name (v/c), label (v/c), fill (v/c), col_edge (e/c)
## + edges from d4ce6e1 (vertex names):
## [1] Origin->Resp_1   Origin->Resp_2   Resp_1->Resp_1_1
## [4] Resp_1->Resp_1_2 Resp_2->Resp_2_1

Après : directement à partir du igraph

En utilisant la fonction set_vertex_attr() :

myigraph_with_fill<- myigraph_with_color %>% 
  set_vertex_attr("label" , value = c("Origin","Response 1", "Response 2","Response 1 1", "Response 1 2", "Response 2 1")) %>% 
  set_vertex_attr("fill" ,
                  value = terrain.colors(6))

Utiliser la variable pour les sommets sur le graph

ggraph(myigraph_with_fill, layout = "igraph", algorithm = "tree") +
geom_edge_link() +
geom_node_label(aes(label = label, fill = fill))+
scale_fill_identity()

 

Pimpez votre arbre

Pour améliorer le rendu de votre arbre, vous pouvez utiliser toutes les fonctionnalités de {ggraph} et vos connaissances {ggplot2}. Si vous voulez un rappel de la construction d’un {ggplot2}, c’est dans “Guide de survie ggplot2 à destination des datajournalistes (et des autres aussi)“.

Par exemple, ici, on peut mettre l’arbre à l’horizontale et jouer sur l’apparence du texte et des espaces:

ggraph(myigraph_with_fill, layout = "igraph", algorithm = "tree") +
geom_edge_diagonal(edge_width = 0.5) +
geom_node_label(aes(label = label, fill = fill),
    fontface = "bold",
    size = 3,
    label.padding = grid::unit(0.5, "lines"),
    label.r = grid::unit(0.5, "lines")
  ) +
scale_fill_identity() +
scale_color_identity()+
guides(fill = "none") +
scale_y_reverse() +
scale_x_reverse() +
coord_flip() +
theme_void()

 

Bonus: changer la couleur du texte en fonction de celle du fond

Une fonction qui permet de gérer la couleur d’écriture des sommets en fonction de la couleur du background.
Le seuil utilisé est de 60 % pour la luminosité..

#' Returns the text color
#'
#' A function that returns the text color to use on a fill color using HSL.
#' If the lightness of the node is greater than 60, we use the color black, otherwise white
#'
#' @param colour a fill colour (text or hex)
#' @importFrom dplyr case_when
#' @importFrom plotwidgets col2hsl
#' @return a color
#'
define_colour_text <- function(colour) {
  vec <- case_when(
    col2hsl(colour)[3, ] > 0.60 ~ "black",
    TRUE ~ "white"
  )
  return(vec)
}
ggraph(myigraph_with_fill, 
             layout = "igraph", 
             algorithm = "tree") +
  geom_edge_diagonal(edge_width = 0.5) +
      geom_node_label(aes(label = label, 
                          fill = fill,
                          color =  define_colour_text(fill)),
    fontface = "bold",
    size = 3,
    label.padding = grid::unit(0.5, "lines"),
    label.r = grid::unit(0.5, "lines")
  ) +
      scale_fill_identity() +
      scale_color_identity()+
  guides(fill = "none") +
  scale_y_reverse() +
  scale_x_reverse() +
  coord_flip() +
  theme_void()

 

C’est à vous !


À propos de l'auteur

Murielle Delmotte

Murielle Delmotte

DATA SCIENTIST – Joueuse de R passionnée


Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *


À lire également

Nos formations Certifiantes à R sont finançables à 100% via le CPF

Nos formations disponibles via moncompteformation.gouv.fr permettent de délivrer des Certificats reconnues par l’état, enregistrées au répertoire spécifique de France Compétences. 3 niveaux de certifications existent :

Contactez-nous pour en savoir plus.

Calendrier

04/06/2024

14/05/2024

14/05/2024