7  Limitations

Ce chapitre expose les limites de animint2 pour certaines tâches de visualisation de données interactives, et propose quelques solutions de contournement à utiliser dans ces situations. Après avoir lu ce chapitre, vous saurez comment :

Toute idée visant à améliorer animint2 et à contourner l’une de ces limites est la bienvenue. Les développeurs de animint2 seraient plus qu’heureux d’accepter votre Pull Request.

7.1 Variables normalisées avec showSelected

Nous implémentons les axes et les légendes de la même manière que dans ggplot2 : en les calculant une seule fois lors de la première génération du graphique. Par conséquent, les axes et les légendes de chaque graphique animint ne sont pas interactifs. Pour la plupart des visualisations de données animées, les axes fixes permettent de comprendre facilement comment les données changent simultanément à la variable time.

Dans certaines situations, il serait utile d’avoir des axes qui se mettent à jour de manière interactive ; par exemple, lorsque différents sous-ensembles showSelected ont des valeurs très différentes pour les variables affichées sur un axe ou une légende. Dans ce cas, il serait utile d’avoir des axes interactifs qui se mettent à jour et changent en même temps que les données. Nous disposons d’une prise en charge expérimentale pour cela, voir la mise à jour axestest pour plus de détails.

7.2 Calcul des statistiques pour chaque sous-ensemble

Dans animint2, nous évitons d’utiliser les statistiques et les positions avec showSelected. Par exemple, considérons le ggplot à facettes ci-dessous :

set.seed(1)
library(data.table)
random.counts <- data.table(
  lettre = c(replicate(4, LETTERS[1:5])),
  comptage = c(replicate(4, rbinom(5, 50, 0.5))),
  groupe = rep(rep(factor(
    c("bas","haut"), c("haut","bas")
  ), each = 5), 2),
  facette = rep(1:2, each = 10))
library(animint2)
ggstat <- ggplot() +
  geom_bar(aes(
    lettre, comptage, key=paste(lettre, groupe), fill = groupe),
    showSelected="facette",
    data = random.counts,
    stat = "identity",
    position="stack")
ggstat+facet_grid(facette ~ .)

Dans le graphique ci-dessus, on constate que position="stack" aligne le groupe bas avec comptage=0 dans chaque facette. Utiliser showSelected au lieu des facettes ne donne pas le même résultat.

animint(ggstat, duration = list(facette = 1000))
mapping: x = lettre
y = comptage
key = paste(lettre, groupe)
fill = groupe
showSelected1 = facette
showSelected2 = groupe 
geom_bar: width = NULL
na.rm = FALSE
stat_identity: na.rm = FALSE
position_stack 
Warning in f(...): showSelected only works with position=identity, problem:
geom1_bar_plot1

Dans le graphique ci-dessus, si vous cliquez sur le menu de sélection pour changer facette=2, vous verrez que le groupe bas n’est plus aligné avec comptage=0. Une solution de contournement consiste à calculer les valeurs à afficher, puis à utiliser position=identity, comme dans le code ci-dessous.

random.cumsums <- random.counts[, data.table(
  cumsum=cumsum(comptage), comptage, groupe),
  by=.(lettre, facette)]
ggidentity <- ggplot() +
  theme_bw()+
  geom_segment(aes(
    x=lettre, xend=lettre,
    y=cumsum, yend=cumsum-comptage,
    key=paste(groupe, lettre),
    color=groupe),
    showSelected="facette",
    data = random.cumsums,
    size=10,
    stat = "identity",
    position="identity")
ggidentity+facet_grid(facette ~ .)

Notez que nous avons utilisé geom_segment() au lieu de geom_bar(), mais que l’affichage est semblable.

animint(ggidentity, duration = list(facette = 1000))

Dans le graphique ci-dessus, si vous cliquez sur le menu de sélection pour changer facette=2, vous verrez que le groupe bas reste aligné avec cumsum=0.

7.3 Ajouter des valeurs à la sélection, une à la fois

animint2 ne prend pas en charge la brosse rectangulaire ou le lasso pour définir interactivement un ensemble de valeurs sélectionnées, mais propose plutôt la sélection multiple en ajoutant des valeurs une par une à l’ensemble de sélection multiple. Il faut donc utiliser l’option selector.types pour déclarer une variable de sélection multiple.

7.4 Ajuster y au lieu d’utiliser vjust

Pour l’alignement horizontal du texte, animint prend en charge l’utilisation de hjust dans R. Les valeurs les plus courantes sont : 0 pour l’alignement à gauche, 0,5 pour l’alignement au milieu et 1 pour l’alignement à droite. animint2 traduit ces trois valeurs hjust en propriété text-anchor dans la visualisation de données générée.

Cependant, animint ne prend pas en charge l’alignement vertical du texte à l’aide de vjust dans R, car aucune propriété ne permet l’alignement vertical du texte en SVG.

line.df <- data.frame(just=c(0, 0.5, 1))
text.df <- expand.grid(
  vjust=line.df$just,
  hjust=line.df$just)
gg.lines <- ggplot()+
  theme_bw()+
  geom_vline(aes(xintercept=just), data=line.df, color="grey")+
  geom_hline(aes(yintercept=just), data=line.df, color="grey")
gg.vjust <- gg.lines+
  geom_text(aes(
    hjust, vjust, label="bépo", hjust=hjust, vjust=vjust),
    size=10,
    data=text.df)
gg.vjust+ggtitle("aes(vjust) marche avec affichage non-interactif")

Notez comment hjust et vjust sont respectés dans le ggplot statique ci-dessus. En revanche, considérons le animint ci-dessous. Le graphique de gauche devrait être le même que le ggplot ci-dessus, mais il y a des différences évidentes dans le placement vertical des éléments de texte.

(vis.just <- animint(
  vjust=gg.vjust+
    ggtitle("aes(vjust) ne marche pas avec geom_text"),
  workaround=gg.lines+
    ggtitle("solutions : geom_label_aligned ou modifier y")+
    geom_text(aes(
      hjust, vjust + (0.5-vjust)*0.03 - 0.01,
      label="bépo", hjust=hjust),
      data=text.df)+
    geom_label_aligned(aes(
      hjust+0.25, vjust, label="bépo", hjust=hjust, vjust=vjust),
      data=text.df,
      alignment="horizontal")))
[1] 0.5 1.0
Warning in vjustWarning(g.data$vjust): geom_text currently only supports
vjust=0, but you may want to try geom_label_aligned, which supports vjust
values 0, 0.5, and 1

Les solutions de contournement dans animint2 sont illustrées dans le panneau de droite ci-dessus.

  • Ajuster les valeurs de la position verticale y des éléments de texte pour lesquels vous auriez utilisé vjust.
  • Utiliser geom_label_aligned(), qui fonctionne avec vjust. Pour un exemple, lire le chapitre 8.

Il serait possible d’implémenter une prise en charge de vjust pour geom_text(), mais nous n’avons pas encore eu le temps d’y travailler. Toute contribution en ce sens sera accueillie avec grand plaisir : n’hésitez pas à soumettre une Pull Request. Nous avons déjà une issue qui explique comment l’implémenter.

7.5 Éviter les sauts de ligne dans les étiquettes de texte

Lors de l’affichage d’un ggplot à l’aide des périphériques graphiques R habituels, l’utilisation d’un saut de ligne ou d’une nouvelle ligne \n dans une étiquette geom_text() entraîne l’apparition de plusieurs lignes de texte sur le graphique.

gg.return <- ggplot()+
  geom_text(aes(
    hjust, vjust, label=sprintf("x=%.1f\ny=%.1f", hjust, vjust)),
    size=3,
    data=text.df)
gg.return

Cependant, animint2 ne prend en charge que le tracé de la première ligne de texte.

animint(gg.return)

La prise en charge de plusieurs lignes dans les étiquettes geom_text() serait utile, mais nous n’avons pas encore eu le temps de l’implémenter. Nous avons créé une issue à ce sujet, et toute Pull Request qui implémente cette fonctionnalité sera acceptée.

En attendant, la solution de contournement consiste à utiliser un seul geom_text() pour chaque ligne de texte à afficher :

gg.two.lines <- ggplot()+
  geom_text(aes(
    hjust, vjust, label=sprintf("x=%.1f", hjust)),
    size=3,
    data=text.df)+
  geom_text(aes(
    hjust, vjust-0.05, label=sprintf("y=%.1f", vjust)),
    size=3,
    data=text.df)
gg.two.lines

animint(gg.two.lines)

7.6 Éviter certaines options du thème ggplot

L’un des objectifs de animint2 est de prendre en charge toutes les options de thème, mais nous n’avons pas encore réussi à toutes les implémenter, faute de temps. Si vous utilisez une option de thème que animint2 ne prend pas encore en charge, n’hésitez pas à nous envoyer une Pull Request. La liste suivante répertorie les options theme déjà prises en charge par animint2 :

  • panel.margin désigne la distance entre les panneaux, et est utilisé dans la méthode facettes économes en espace.
  • panel.grid.major est utilisé pour dessiner à l’échelle, les lignes de la grille qui sont désignées par l’argument breaks.
  • panel.grid.minor est utilisé pour dessiner les lignes de la grille entre ses lignes principales.
  • panel.background est utilisé pour le <rect> en arrière-plan de chaque panneau.
  • panel.border est utilisé pour la bordure <rect> de chaque panneau (sur l’arrière-plan <rect>).
  • legend.position="none" fonctionne pour cacher toutes les légendes, mais aucune des autres positions de légende n’est prise en charge (les légendes apparaissent toujours à droite du graphique).

Les options de thème suivantes peuvent être définies par element_blank pour masquer les axes :

  • axis.title, axis.title.x, axis.title.y désignent le titre de l’axe.
  • axis.ticks, axis.ticks.x, axis.ticks.y désignent les tics de l’axe.
  • axis.line, axis.line.x, axis.line.y désignent la ligne d’axe.
  • axis.text, axis.text.x, axis.text.y désignent l’étiquette de texte de l’axe, et prennent en charge les arguments angle et hjust de element_text.

7.7 Facettes avec plusieurs variables par axe

animint2 prend en charge facet_grid pour créer des visualisations de données à plusieurs panneaux, mais ne prend en charge que de manière limitée les variables multiples par axe. Par exemple, le ggplot ci-dessous utilise deux variables pour créer des facettes verticales, ce qui fait deux lignes de texte pour le titre de chaque facette lorsque la visualisation est générée avec les sorties graphiques traditionnelles de R.

data(intreg)
signals.df <- transform(
  intreg$signals,
  person=sub("[.].*", "p", signal),
  chromosome=sub(".*[.]", "c", signal))
two.strips <- ggplot()+
  theme_animint(height=600)+
  facet_grid(person + chromosome ~ ., scales="free")+
  geom_point(aes(base/1e6, logratio), data=signals.df)
two.strips+ggtitle("two strip labels on the right")

En comparaison, animint2 affiche le même ggplot ci-dessous en n’utilisant qu’une seule étiquette de bande.

animint(two.strips+ggtitle("only one strip label"))

Il serait intéressant de prendre en charge plusieurs étiquettes de bande par axe, mais nous ne l’avons pas encore implémenté. Si vous souhaitez le faire, nous serions heureux d’accepter votre Pull Request.

7.8 Définition interactive de mappings aes() à l’aide de shiny

Normalement, les mappings aes() sont définis une fois dans le code R, et ne peuvent pas être modifiés après l’affichage d’un animint. Une façon de surmonter cette limite est de définir des entrées shiny qui sont utilisées comme aes() de animint, tel que démontré dans l’exemple suivant :

shiny::runApp(system.file(
  "examples", "shiny-WorldBank", package="animint2"))

7.9 Calcul interactif

Une autre limitation de animint2 est de ne pouvoir afficher que des données préalablement calculées et stockées dans un tableau. Cela signifie que animint2 n’est pas approprié lorsqu’il y a trop de sous-ensembles à tracer pour les calculer tous. Dans ce cas, il serait préférable d’utiliser shiny.

7.10 Résumé du chapitre et exercices

Nous avons discuté des limites de l’implémentation actuelle de animint2 et présenté plusieurs solutions de contournement.

Exercices :

  • Réalisez un ggplot à facettes avec stat_bin qui ne fonctionnera pas avec animint2 lorsque la variable facette est utilisée comme variable showSelected. Calculez le statut de chaque facette, et utilisez stat_identity pour que votre calcul fonctionne avec animint2.
  • Faites un ggplot qui s’affiche bien en utilisant facet_grid(. ~ var, scales="free"), mais ne s’affiche pas correctement avec showSelected=var. Pour résoudre le problème, calculez une version normalisée de var et utilisez-la dans showSelected.

Dans le chapitre 8, nous vous expliquerons comment créer une visualisation multi-panneaux des données de la Banque mondiale.