Retour à la page d’accueil


Lors de cette séance nous allons apprendre:

  1. A ajouter des résultats de tests statistiques à des graphiques

  2. A ajouter des statistiques descriptives à des graphiques

  3. A sélectionner des lignes avec la fonction filter

  4. A représenter des données temporelles


Préparation de l’environnement de travail

Tout d’abord ouvrez le projet R, créez un nouveau script R et préparez votre environnement de travail:

# Chargez la librairie `tidyverse` (aide: utilisez la fonction `library()`)


# Importer `burghardt_et_al_2015_expt1.txt` et mettez le dans un objet appelé `expt1`
#(aide: utilisez la fonction `read_tsv()`)


1. Ajouter des résultats de tests statistiques à des graphiques

Pour pouvoir rajouter des résultats de tests statistiques à des graphiques, nous allons utiliser des fonctions de la librairie ggpubr.

library(ggpubr)

Comparaison de moyennes de deux (ou plusieurs) groupes

Afin de faire un test de comparaison de moyennes, nous utilisons la fonction stat_compare_means.

ggplot(expt1, aes(genotype, days.to.flower, colour = fluctuation)) +
  geom_boxplot() +
  stat_compare_means(label = "p.format", method="t.test")
## Warning: Removed 83 rows containing non-finite values (stat_boxplot).
## Warning: Removed 83 rows containing non-finite values (stat_compare_means).

Comme nous avons deux groupes à comparer (température fluctuante vs température constante), la fonction fait la comparaison de ces deux groupes automatiquement pour chaque génotype et donne la p-value associée.


Plutôt que d’ajouter les valeurs des p-values, il est aussi possible d’utiliser un code à base d’étoiles pour indiquer le niveau de significativité du test:

ns: p > 0.05

*: p <= 0.05

**: p <= 0.01

***: p <= 0.001

****: p <= 0.0001

ggplot(expt1, aes(genotype, days.to.flower, colour = fluctuation)) +
  geom_boxplot() +
  stat_compare_means(label = "p.signif", method="t.test")
## Warning: Removed 83 rows containing non-finite values (stat_boxplot).
## Warning: Removed 83 rows containing non-finite values (stat_compare_means).


Par contre, s’il n’y a pas deux groupes clairement identifiés, tous les groupes vont être comparés, en utilisant par défaut avec un test de Kruskal–Wallis:

ggplot(expt1, aes(genotype, days.to.flower)) +
  geom_boxplot() +
  stat_compare_means(label = "p.format")
## Warning: Removed 83 rows containing non-finite values (stat_boxplot).
## Warning: Removed 83 rows containing non-finite values (stat_compare_means).

Voir ce site pour en savoir plus sur les différentes options de tests de comparaison de moyennes (comparaison de deux groupes et de multiples groupes).


Tests de corrélation

Il est aussi possible d’ajouter le résultat d’un test de corrélation (spearman ou pearson) à un scatterplot en utilisant la fonction stat_cor():

ggplot(expt1, aes(blade.length.mm, rosette.leaf.num)) +
    geom_point()+
  stat_cor()
## Warning: Removed 333 rows containing non-finite values (stat_cor).
## Warning: Removed 333 rows containing missing values (geom_point).


Par défaut, un test de pearson est effectué. Pour utiliser un test de spearman, il faut utiliser method="spearman"

ggplot(expt1, aes(blade.length.mm, rosette.leaf.num)) +
    geom_point()+
  stat_cor(method="spearman")
## Warning: Removed 333 rows containing non-finite values (stat_cor).
## Warning: Removed 333 rows containing missing values (geom_point).


Si vous avez plusieurs groupes, stat_cor va calculer la corrélation pour chaque groupe.

ggplot(expt1, aes(blade.length.mm, rosette.leaf.num, colour = fluctuation)) +
    geom_point()+
  stat_cor()
## Warning: Removed 333 rows containing non-finite values (stat_cor).
## Warning: Removed 333 rows containing missing values (geom_point).

Il est aussi possible d’ajouter une ligne de régression (linéaire ou non), incluant un intervalle de confiance, au graphique avec geom_smooth(). Notez cependant, comme on peut le voir ci-dessous, que cette fonction fonctionne mieux pour des régressions linéaires et non complexes.

ggplot(expt1, aes(blade.length.mm, rosette.leaf.num, colour = fluctuation)) +
    geom_point()+
  stat_cor() +
  geom_smooth()
## Warning: Removed 333 rows containing non-finite values (stat_cor).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 333 rows containing non-finite values (stat_smooth).
## Warning: Removed 333 rows containing missing values (geom_point).

Comme vous pouvez le voir, la ligne de régression ne représente pas bien les données. Il faudrait ici utiliser une méthode plus compliquée pour pouvoir extrapoler une ligne de régression. Ce n’est pas parce qu’il est possible de faire quelque chose avec R, que cela est forcément judicieux. Soyez critique et assurez vous que ce que vous faites soit pertinent!


Exercice 1:

Ajouter le test statistique le plus approprié aux deux graphiques suivant:

ggplot(expt1, aes(fluctuation, rosette.leaf.num)) +
  geom_violin() 
## Warning: Removed 95 rows containing non-finite values (stat_ydensity).

ggplot(expt1, aes(days.to.bolt, days.to.flower)) +
    geom_point() 
## Warning: Removed 83 rows containing missing values (geom_point).

BONUS: Ajoutez une ligne de régression (pour le graphique où cela est possible). Déplacez le résultat du test statistique pour qu’il soit au meilleur endroit sur le graphique. Qu’est ce que vous pouvez conclure pour chacun de ces graphiques?


2. Ajouter des statistiques descriptives à des graphiques

Créer des chaînes de commandes avec les pipes %>%

Les “pipes” (%>%) permettent de faire une séquence d’opération sur des données, sans avoir besoin de créer des objets intermédiaires (ou de faire des commandes imbriquées très compliquées)

Grace au symbole %>% pipe, nous pouvons créer une chaîne de commandes. Pour cela nous devons d’abord faire une commande et ajouter %>% à la fin de la ligne qui va utiliser le résultat de cette commande comme input pour la fonction à la ligne suivante. Nous allons utiliser les pipes à partir de maintenant pour créer des chaines de commandes.

Extraire les statistiques descriptives avec group_by() et summarise()

Parfois nous voulons résumer nos données dans une table plus petite et en extraire des statistiques descriptives (moyenne, médiane, nombre d’observations …).

Ce type d’opération peut être fait avec la combinaison de deux fonctions: group_by() et summarise().

Notez que group_by() ne change pas le format de la table de données. Cette fonction liste des lignes qui doivent être groupées. Nous pouvons ensuite utiliser summarise() pour extraire des statistiques descriptives de chaque groupe.

Par exemple, nous pouvons extraire la moyenne pour le temps de floraison de chaque génotype:

group_by(expt1, genotype) %>% 
summarise(mean.days.to.flower = mean(days.to.flower, na.rm = TRUE))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 10 x 2
##    genotype   mean.days.to.flower
##    <chr>                    <dbl>
##  1 Col Ama                   55.8
##  2 Col FRI                   70.2
##  3 fca-6                     70.4
##  4 flc-3 FRI                 53.1
##  5 flk-1                     77.6
##  6 fve-3                     81.2
##  7 ld-1                      89.8
##  8 Ler-1                     55.6
##  9 prmt5 FRI                 88.7
## 10 vin3-4 FRI                95.7

L’output contient deux colonnes:

  • genotype qui est la colonne qui a servi à grouper les données

  • mean.days.to.flower qui est la colonne crée par la fonction summarise

Il n’y a que 10 lignes dans cette table, une par génotype.

Il est possible de grouper les données par plus d’une variable.

Par exemple nous pouvons mesurer la moyenne, la médiane et l’écart type pour chaque génotype aux différentes températures:

group_by(expt1, genotype, temperature) %>% 
summarise(mean.days.flower = mean(days.to.flower, na.rm = TRUE),
          sd.days.flower = sd(days.to.flower, na.rm = TRUE),
          median.days.flower = median(days.to.flower, na.rm = TRUE))
## `summarise()` regrouping output by 'genotype' (override with `.groups` argument)
## # A tibble: 20 x 5
## # Groups:   genotype [10]
##    genotype   temperature mean.days.flower sd.days.flower median.days.flower
##    <chr>            <dbl>            <dbl>          <dbl>              <dbl>
##  1 Col Ama             12             66.6          25.5                62  
##  2 Col Ama             22             46.0          20.5                51  
##  3 Col FRI             12             81.1          26.2                80  
##  4 Col FRI             22             57.8          25.9                59.5
##  5 fca-6               12             76.2          20.9                72.5
##  6 fca-6               22             63.9          34.6                40  
##  7 flc-3 FRI           12             64.7          25.2                46  
##  8 flc-3 FRI           22             43            17.5                50  
##  9 flk-1               12             87.8          27.9                87  
## 10 flk-1               22             61.2          29.2                47  
## 11 fve-3               12             96.1          26.3                92  
## 12 fve-3               22             51.5           5.96               49  
## 13 ld-1                12             99.8          27.8               100  
## 14 ld-1                22             72.9          36.5                60  
## 15 Ler-1               12             67.4          22.7                64  
## 16 Ler-1               22             45.2          18.3                51.5
## 17 prmt5 FRI           12            103.           22.0               102  
## 18 prmt5 FRI           22             67.2          26.6                62  
## 19 vin3-4 FRI          12            111.           40.0                83  
## 20 vin3-4 FRI          22             72.5          29.7                69

Il y a maintenant 20 lignes dans la table, car chaque génotype apparaît deux fois (12 et 22 degrés)

Une autre information utile que nous pouvons extraire est le nombre d’observation pour chaque groupe. Pour cela nous devons utiliser la fonction n(), dans summarise() qui compte le nombre de ligne pour chaque groupe.

Par exemple, pour connaitre le nombre d’observations pour chaque génotype:

group_by(expt1, genotype) %>% 
summarise(n.obs = n())
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 10 x 2
##    genotype   n.obs
##    <chr>      <int>
##  1 Col Ama      135
##  2 Col FRI      128
##  3 fca-6         64
##  4 flc-3 FRI    136
##  5 flk-1         60
##  6 fve-3         60
##  7 ld-1          60
##  8 Ler-1         68
##  9 prmt5 FRI    125
## 10 vin3-4 FRI   121

Attention: Quand vous utilisez la fonction group_by(), les lignes du tableau restent groupées en fonction de la variable utilisée. Les opérations suivantes vont utiliser ces groupes, ce qui peut poser problème. Pensez à utiliser la fonction ungroup() pour enlever les groupes quand vous avez fini avec group_by() et summarise()

Exercice 2:

Calculez la médiane et l’écart-type de blade.length.mm et total.leaf.length.mm pour chaque genotype aux différentes day.length. Calculez aussi le nombre d’observations de chaque groupe.


Insérer les statistiques descriptives à un graphique

Une autre possibilité est d’ajouter les statistiques descriptives à un graphique contenant les données.

Pour cela, nous devons:

  • Utiliser group_by() et summarise() pour extraire les statistiques descriptives

  • Utiliser une fonction de la famille *_join() pour les combiner avec nos données

  • Nous pouvons maintenant faire un graphique contenant les données et les statistiques descriptives.

Par exemple, prenons ce boxplot:

  ggplot( expt1, aes(genotype, rosette.leaf.num)) +
  geom_boxplot()
## Warning: Removed 95 rows containing non-finite values (stat_boxplot).

Si nous voulons y ajouter le nombre d’observations pour chaque groupe, nous utilisons le script suivant:

group_by(expt1, genotype) %>% 
  summarise(n.obs=n()) %>% 
  mutate(n.obs=paste("n =",n.obs)) %>% 
  full_join(expt1, by="genotype") %>% 
  ggplot( aes(genotype, rosette.leaf.num)) +
  geom_boxplot() +
  geom_text(aes(label=n.obs, x=genotype, y=0))
## `summarise()` ungrouping output (override with `.groups` argument)
## Warning: Removed 95 rows containing non-finite values (stat_boxplot).


Exercice 3

Faites un voilin plot de total.leaf.length.mm pour chaque génotype et ajoutez la médiane pour chaque groupe (avec un point coloré) ainsi que le nombre d’observation de chaque groupe

BONUS: Modifiez le graphique que vous venez de créer pour ajouter les comparaison de moyenne de chaque génotype avec Col Ama (comme sur le graphique ci-dessous)


Avec cette même méthode il est aussi possible d’ajouter des informations pour des groupes formés à partir de deux variables.

Par exemple, si nous voulons faire un boxplot rosette.leaf.num pour chaque génotype en fonction de la température et y ajouter le nombre d’observations des différents groupes, nous utilisons le script suivant:

group_by(expt1, genotype, fluctuation) %>% 
  summarise(n.obs=n()) %>% 
  mutate(n.obs=paste("n =",n.obs)) %>% 
  full_join(expt1, by=c("genotype", "fluctuation")) %>% 
  ggplot( aes(genotype, rosette.leaf.num, fill=fluctuation)) +
  geom_boxplot() +
  geom_text(aes(label=n.obs, x=genotype, y=-2),position=position_dodge(0.8), angle=45)
## `summarise()` regrouping output by 'genotype' (override with `.groups` argument)
## Warning: Removed 95 rows containing non-finite values (stat_boxplot).

3. Sélectionner des lignes avec la fonction filter

Avec la fonction filter(), nous pouvons garder toutes les lignes de notre table qui correspondent à des plantes qui ont subies une vernalisation.

Tout d’abord, nous devons connaitre les différentes valeurs de la colonne vernalization. Comme nous pouvons voir, il y a deux options: ‘NV’ et ‘V’.

unique(expt1$vernalization)
## [1] "NV" "V"

(note: $ permet de sélectionner une colonne en particulier de la table)

Comme nous voulons garder les plantes qui ont subies une vernalisation, nous devons filtrer les données pour garder les lignes pour lesquelles il y a “V” dans la colonne vernalization:

filter(expt1, vernalization == "V")
## # A tibble: 330 x 15
##    plant_nb genotype background temperature fluctuation day.length vernalization
##       <dbl> <chr>    <chr>            <dbl> <chr>            <dbl> <chr>        
##  1        1 Col Ama  Col                 12 Con                 16 V            
##  2        2 Col Ama  Col                 12 Con                 16 V            
##  3        3 Col Ama  Col                 12 Con                 16 V            
##  4        4 Col Ama  Col                 12 Con                 16 V            
##  5        5 Col Ama  Col                 12 Con                 16 V            
##  6        6 Col Ama  Col                 12 Con                 16 V            
##  7        7 Col Ama  Col                 12 Con                 16 V            
##  8        8 Col Ama  Col                 12 Con                 16 V            
##  9        1 Col Ama  Col                 12 Con                  8 V            
## 10        2 Col Ama  Col                 12 Con                  8 V            
## # … with 320 more rows, and 8 more variables: survival.bolt <chr>, bolt <chr>,
## #   days.to.bolt <dbl>, days.to.flower <dbl>, rosette.leaf.num <dbl>,
## #   cauline.leaf.num <dbl>, blade.length.mm <dbl>, total.leaf.length.mm <dbl>

Nous pouvons utiliser les opérateurs suivant pour définir les conditions pour filtrer les données:

Opérateur Condition de sélection Exemple
< inférieur à filter(expt1, days.to.bolt < 20)
<= inférieur ou égal à filter(expt1, days.to.bolt <= 20)
> supérieur à filter(expt1, days.to.bolt > 20)
>= supérieur ou égal à filter(expt1, days.to.bolt >= 20)
== égal à filter(expt1, days.to.bolt == 20)
!= différent de filter(expt1, days.to.bolt != 20)
%in% est contenu dans filter(expt1, genotype %in% c("Col FRI", "Ler-1"))

Il est aussi possible de combiner plusieurs conditions de sélection avec les opérateurs suivant:

Opérateur Signification Exemple
& ET filter(expt1, days.to.bolt == 20 & genotype == "Ler-1")
| OU filter(expt1, rosette.leaf.num < 8 | rosette.leaf.num > 100)

Nous pouvons aussi identifier les données manquantes (NA) avec la fonction is.na() ou sa négation (en utilisant !):

Opérateur Signification Exemple
is.na() données manquante filter(expt1, is.na(rosette.leaf.num))
!is.na() donnée non manquante filter(expt1, !is.na(rosette.leaf.num))

source de l’image

Par exemple, nous pouvons sélectionner les plantes qui ont été vernalisées ET qui ont poussées avec une température fluctuante:

filter(expt1, vernalization == "V" & fluctuation == "Var")

Il est aussi possible de sélectionner les plantes qui ont poussées avec 8h de jours OU qui fleurissent tardivement:

filter(expt1, day.length == "8" | days.to.bolt > 85)

Exercice 4: Filtrez les données pour garder les plantes selon les 3 cas de figures suivant (indépendants les uns des autres):

  1. Plantes qui ne sont pas du background Ler et qui ont été traitées avec une température fluctuante.
  2. Plantes qui ont fleuries (bolt) en moins de 57 jours et qui ont moins de 40 feuilles de rosette
  3. Plantes du génotype fca-6 pour qui le blade.length.mm n’est pas manquant

4. Représenter des données temporelles

Pour représenter des données temporelles avec une ligne par individu mesuré, nous allons utiliser un autre jeu de données qui contient des transcriptomes effectués sur des plantes d’Arabidopsis thaliana ayant été traités pour 15 minutes, 1 heure ou 4 heures avec une température de 17°C ou 27°C.

Tout d’abord, chargeons les données et gardons les dans l’objet RNAseq:

RNAseq <- read_tsv("../data/data_expression_cortijo2017.txt")
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   gene = col_character(),
##   Log2FoldToZero_17c_15min = col_double(),
##   TLog2FoldToZero_17c_1hr = col_double(),
##   Log2FoldToZero_17c_4hr = col_double(),
##   Log2FoldToZero_27c_15min = col_double(),
##   Log2FoldToZero_27c_1hr = col_double(),
##   Log2FoldToZero_27c_4hr = col_double(),
##   cluster = col_character()
## )

L’objectif est d’obtenir un graphique de ce type:

Pour cela nous devons d’abord filtrer les données pour ne garder que l’expression pour les gènes AT1G04520 et AT3G12580

filter(RNAseq, gene%in%c("AT1G04520","AT3G12580")) 
## # A tibble: 2 x 8
##   gene  Log2FoldToZero_… TLog2FoldToZero… Log2FoldToZero_… Log2FoldToZero_…
##   <chr>            <dbl>            <dbl>            <dbl>            <dbl>
## 1 AT1G…          -0.0924           -0.595           -1.44            -0.447
## 2 AT3G…           1.46              0.951           -0.421            6.22 
## # … with 3 more variables: Log2FoldToZero_27c_1hr <dbl>,
## #   Log2FoldToZero_27c_4hr <dbl>, cluster <chr>

Nous obtenons une table avec deux lignes, une par gène; et 8 colonnes, une par condition, plus une avec le cluster. Afin de pouvoir faire le graphique voulu, il nous faut un tableau avec une colonne contenant la durée de traitement, une autre avec la température de traitement et une troisième avec le niveau d’expression des gènes. Comme le tableau ci-dessous:

## # A tibble: 12 x 6
##    gene      cluster   normalisation   temperature temps expression
##    <chr>     <chr>     <chr>           <chr>       <chr>      <dbl>
##  1 AT1G04520 cluster1  Log2FoldToZero  17c         15min    -0.0924
##  2 AT3G12580 cluster6A Log2FoldToZero  17c         15min     1.46  
##  3 AT1G04520 cluster1  TLog2FoldToZero 17c         1hr      -0.595 
##  4 AT3G12580 cluster6A TLog2FoldToZero 17c         1hr       0.951 
##  5 AT1G04520 cluster1  Log2FoldToZero  17c         4hr      -1.44  
##  6 AT3G12580 cluster6A Log2FoldToZero  17c         4hr      -0.421 
##  7 AT1G04520 cluster1  Log2FoldToZero  27c         15min    -0.447 
##  8 AT3G12580 cluster6A Log2FoldToZero  27c         15min     6.22  
##  9 AT1G04520 cluster1  Log2FoldToZero  27c         1hr      -1.78  
## 10 AT3G12580 cluster6A Log2FoldToZero  27c         1hr       6.24  
## 11 AT1G04520 cluster1  Log2FoldToZero  27c         4hr      -1.93  
## 12 AT3G12580 cluster6A Log2FoldToZero  27c         4hr       2.95

Or ces informations sont dans le titre des colonnes de notre tableau. Pour changer le format et créer une colonne qui contient l’information du titre des colonnes, nous devons utiliser la fonction gather()

Voici comment la fonction gather() marche:

source de l’image

Essayons sur nos données:

filter(RNAseq, gene%in%c("AT1G04520","AT3G12580")) %>% 
  gather(key="condition", value="expression", Log2FoldToZero_17c_15min:Log2FoldToZero_27c_4hr)  
## # A tibble: 12 x 4
##    gene      cluster   condition                expression
##    <chr>     <chr>     <chr>                         <dbl>
##  1 AT1G04520 cluster1  Log2FoldToZero_17c_15min    -0.0924
##  2 AT3G12580 cluster6A Log2FoldToZero_17c_15min     1.46  
##  3 AT1G04520 cluster1  TLog2FoldToZero_17c_1hr     -0.595 
##  4 AT3G12580 cluster6A TLog2FoldToZero_17c_1hr      0.951 
##  5 AT1G04520 cluster1  Log2FoldToZero_17c_4hr      -1.44  
##  6 AT3G12580 cluster6A Log2FoldToZero_17c_4hr      -0.421 
##  7 AT1G04520 cluster1  Log2FoldToZero_27c_15min    -0.447 
##  8 AT3G12580 cluster6A Log2FoldToZero_27c_15min     6.22  
##  9 AT1G04520 cluster1  Log2FoldToZero_27c_1hr      -1.78  
## 10 AT3G12580 cluster6A Log2FoldToZero_27c_1hr       6.24  
## 11 AT1G04520 cluster1  Log2FoldToZero_27c_4hr      -1.93  
## 12 AT3G12580 cluster6A Log2FoldToZero_27c_4hr       2.95

Nous avons maintenant une colonne condition, qui contient le nom des colonnes que nous avons regroupées et une colonne expression qui contient les valeurs des colonnes (le niveau d’expression des gènes). Ce n’est pas encore exactement ce dont nous avons besoin car la colonne condition contient toutes les informations de l’expérience, mais nous voulons une colonne pour chacune de ces informations: méthode de normalisation, température, durée de traitement.

Pour cela nous allons utiliser la fonction separate, qui permet de séparer une colonne en plusieurs colonnes:

## # A tibble: 12 x 6
##    gene      cluster   normalisation   temperature temps expression
##    <chr>     <chr>     <chr>           <chr>       <chr>      <dbl>
##  1 AT1G04520 cluster1  Log2FoldToZero  17c         15min    -0.0924
##  2 AT3G12580 cluster6A Log2FoldToZero  17c         15min     1.46  
##  3 AT1G04520 cluster1  TLog2FoldToZero 17c         1hr      -0.595 
##  4 AT3G12580 cluster6A TLog2FoldToZero 17c         1hr       0.951 
##  5 AT1G04520 cluster1  Log2FoldToZero  17c         4hr      -1.44  
##  6 AT3G12580 cluster6A Log2FoldToZero  17c         4hr      -0.421 
##  7 AT1G04520 cluster1  Log2FoldToZero  27c         15min    -0.447 
##  8 AT3G12580 cluster6A Log2FoldToZero  27c         15min     6.22  
##  9 AT1G04520 cluster1  Log2FoldToZero  27c         1hr      -1.78  
## 10 AT3G12580 cluster6A Log2FoldToZero  27c         1hr       6.24  
## 11 AT1G04520 cluster1  Log2FoldToZero  27c         4hr      -1.93  
## 12 AT3G12580 cluster6A Log2FoldToZero  27c         4hr       2.95

Nous avons maintenant le format de tableau qui nous permet de faire le graphique voulu, montrant le changement d’expression au cours du temps en réponse au traitement de température pour nos deux gènes d’intérêt.

filter(RNAseq, gene%in%c("AT1G04520","AT3G12580")) %>% 
  gather(key="condition", value="expression", Log2FoldToZero_17c_15min:Log2FoldToZero_27c_4hr) %>% 
  separate(condition, into=c("normalisation", "temperature", "temps")) %>% 
  ggplot(aes(x=temps, y=expression,color=temperature, group=temperature)) +
  geom_line() +
  facet_wrap(~gene, scales="free_y")

Attention: quand nous utilisons geom_line(), l’argument group= est essentiel pour savoir comment relier les points ensemble en une (ou plusieurs) ligne(s).



Vous avez vu aujourd’hui, qu’il est possible de rajouter de nombreuses informations à des graphiques, et de réorganiser vos données pour pouvoir faire la représentation la plus appropriée de vos données