ggiraph avec Shiny : sélection au clic et réactivité en R

Lisez les clics d’un widget girafe avec opts_selection() et input$_selected — et enregistrez le graphique dans n’importe quel rapport

Pilotez une application Shiny depuis un graphique avec ggiraph — affichez un widget girafe avec girafeOutput() et renderGirafe(), laissez les lecteurs cliquer pour sélectionner des points avec opts_selection(), lisez la sélection de façon réactive depuis input$<id>_selected pour des vues liées et l’exploration détaillée, puis enregistrez ou intégrez un girafe dans n’importe quel rapport Quarto ou R Markdown.

Date de publication

9 juillet 2026

Modifié

9 juillet 2026

AstucePoints clés
  • Placez un graphique girafe dans une application Shiny avec girafeOutput("id") dans l’UI et renderGirafe({ girafe(...) }) dans le serveur.
  • Ajoutez opts_selection() à girafe() pour qu’un clic sélectionne les éléments par leur data_idtype = "single" ou type = "multiple".
  • Lisez la sélection de façon réactive depuis input$<id>_selected — un vecteur de caractères des data_id sélectionnés — pour piloter des vues liées, un tableau de détail ou une exploration détaillée.
  • Un objet girafe() est un htmlwidget autonome : il s’intègre dans n’importe quel rapport HTML Quarto/R Markdown et peut être écrit dans un fichier autonome avec htmlwidgets::saveWidget().
  • ggiraph est libre et open source, et conserve le rendu prêt à publier de ggplot2.

Introduction

Vous avez un nuage de points dans un tableau de bord et vous voulez qu’il fasse quelque chose : le lecteur clique sur quelques points, et un tableau en dessous se remplit avec leurs détails — ou un second graphique se redessine pour n’afficher que ce qu’il a choisi. Ce schéma « cliquer pour sélectionner » avec vues liées est au cœur d’un tableau de bord interactif, et ggiraph vous l’offre sans quitter ggplot2.

Cette leçon présente le côté Shiny de ggiraph : comment afficher un widget girafe() dans une application, comment opts_selection() transforme un clic en sélection, et comment lire cette sélection de façon réactive en R pour mettre à jour le reste de la page. Un serveur Shiny actif ne peut pas s’exécuter dans cette leçon statique, le code de l’application est donc présenté comme du R ordinaire que vous pouvez copier dans app.R — mais la sélection elle-même fonctionne côté client, si bien que l’unique widget interactif ci-dessous vous permet de cliquer et de sélectionner ici même. Si vous débutez avec ggiraph, commencez par Démarrer avec ggiraph ; ici, nous supposons que vous connaissez le motif geom_*_interactive() + girafe().

Les données

Nous utilisons le jeu de données intégré mtcars — une ligne par voiture, avec le poids (wt), l’efficacité énergétique (mpg) et la puissance (hp). Chaque voiture devient un point, et le nom de la voiture devient le data_id du point — la valeur qu’un clic renverra.

head(mtcars[, c("wt", "mpg", "hp")])
                     wt  mpg  hp
Mazda RX4         2.620 21.0 110
Mazda RX4 Wag     2.875 21.0 110
Datsun 710        2.320 22.8  93
Hornet 4 Drive    3.215 21.4 110
Hornet Sportabout 3.440 18.7 175
Valiant           3.460 18.1 105

Le graphique à rendre interactif

Voici le nuage de points ggplot2 ordinaire — le poids des voitures en fonction des miles par gallon, des points azur de la marque, rien d’interactif pour l’instant. C’est la figure statique sur laquelle s’appuie la leçon (et le graphique que vous savez déjà réaliser).

library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(color = "#3a86d4", size = 3) +
  labs(x = "Weight (1000 lbs)", y = "Miles per gallon",
       title = "Fuel efficiency by car weight") +
  theme_minimal()

Scatter plot of car weight on the x-axis against miles per gallon on the y-axis, with brand-azure points on a minimal theme; points trend downward.

Pour le rendre sélectionnable, remplacez geom_point() par geom_point_interactive() et mappez deux attributs esthétiques : data_id (la valeur qu’un clic renvoie — le nom de la voiture) et tooltip (ce qui s’affiche au survol). Tout le reste du graphique demeure identique.

library(ggplot2)
library(ggiraph)

p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point_interactive(
    aes(data_id = rownames(mtcars), tooltip = rownames(mtcars)),
    color = "#3a86d4", size = 3
  ) +
  labs(x = "Weight (1000 lbs)", y = "Miles per gallon",
       title = "Fuel efficiency by car weight") +
  theme_minimal()
p

Scatter plot of car weight against miles per gallon built with geom_point_interactive; visually identical to the static version until rendered as a widget.

Rendu sous forme d’image statique, p paraît identique au premier graphique — les valeurs data_id et tooltip sont des métadonnées cachées rattachées à chaque point. Elles ne prennent vie que lorsque girafe() restitue le graphique sous forme de SVG interactif.

Cliquer pour sélectionner : opts_selection()

opts_selection() est l’option qui rend les éléments sélectionnables : cliquez sur un point et il reste mis en évidence ; cliquez de nouveau pour le désélectionner. Son argument type contrôle combien d’éléments peuvent être sélectionnés à la fois :

type Comportement Sélection renvoyée
"single" Un seul élément à la fois ; cliquer sur un autre le remplace. Un vecteur de caractères de longueur 1.
"multiple" Cliquez-en plusieurs ; chacun s’active ou se désactive. Un vecteur de caractères de chaque data_id sélectionné.
"none" Sélection désactivée (valeur par défaut).

L’argument css met en forme l’apparence des éléments sélectionnés — ici, un point sélectionné passe en ambre (#f5a524) avec un contour foncé, de sorte qu’il se distingue à la fois de l’azur par défaut et de la teinte bleu clair du survol. Un détail qui piège tout le monde en dehors de Shiny : opts_selection() est réservé à Shiny par défaut, donc sur une page statique (comme celle-ci, ou un simple rapport Quarto/R Markdown) vous devez passer only_shiny = FALSE pour activer la sélection au clic — sans cela, cliquer ne fait rien. Définissez un width_svg/height_svg explicite pour que le widget réserve son espace et que la page ne se décale pas pendant son chargement.

Ce widget est interactif — cliquez sur n’importe quel point (ou plusieurs) ; chacun reste en ambre jusqu’à ce que vous cliquiez à nouveau dessus. Dans une application Shiny, les noms des voitures sélectionnées arrivent aussi dans R sous la forme input$<id>_selected, que la section suivante utilise.

library(ggplot2)
library(ggiraph)

p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point_interactive(
    aes(data_id = rownames(mtcars), tooltip = rownames(mtcars)),
    color = "#3a86d4", size = 3
  ) +
  labs(x = "Weight (1000 lbs)", y = "Miles per gallon",
       title = "Click a point to select it") +
  theme_minimal()

girafe(
  ggobj = p,
  width_svg = 7,
  height_svg = 4.5,
  options = list(
    # only_shiny = FALSE is essential OUTSIDE Shiny: by default opts_selection() is
    # Shiny-only, so clicks do nothing on a static page. Setting it FALSE enables
    # click-selection here. A selected point turns amber with a dark outline (it
    # persists); hovering only tints a point light blue (temporary).
    opts_selection(type = "multiple", only_shiny = FALSE,
                   css = "fill:#f5a524;stroke:#0b2942;stroke-width:1.5pt;"),
    opts_hover(css = "fill:#8bb8e8;"),
    opts_tooltip(css = "background:#1b2b40;color:#ffffff;padding:5px 9px;border-radius:6px;font-family:sans-serif;font-size:13px;")
  )
)

La sélection est une fonctionnalité côté client du SVG, c’est pourquoi elle fonctionne dans cette page statique. Ce qui la rend importante, c’est que dans Shiny cette même sélection est exposée au serveur sous forme de valeur réactive — de sorte que R peut y répondre.

Un SVG interactif est opaque pour les lecteurs d’écran, voici donc les données derrière le widget — les premières lignes des voitures tracées, avec le data_id (le nom de ligne) que porte chaque point.

First cars in mtcars; each point’s data_id is its row name (shown in the first column).
Weight (1000 lbs) Miles per gallon Horsepower
Mazda RX4 2.620 21.0 110
Mazda RX4 Wag 2.875 21.0 110
Datsun 710 2.320 22.8 93
Hornet 4 Drive 3.215 21.4 110
Hornet Sportabout 3.440 18.7 175
Valiant 3.460 18.1 105
Duster 360 3.570 14.3 245
Merc 240D 3.190 24.4 62

Placer le widget dans une application Shiny

Deux fonctions font le pont entre ggiraph et Shiny. Dans l’UI, girafeOutput("plot") réserve un emplacement pour le widget. Dans le serveur, renderGirafe({ girafe(...) }) le construit. L’id de sortie que vous passez à girafeOutput() — ici "plot" — est ce qui relie le widget à son entrée de sélection.

library(shiny)
library(ggplot2)
library(ggiraph)

ui <- fluidPage(
  titlePanel("Cars explorer"),
  girafeOutput("plot")
)

server <- function(input, output) {
  output$plot <- renderGirafe({
    p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
      geom_point_interactive(
        aes(data_id = rownames(mtcars), tooltip = rownames(mtcars)),
        color = "#3a86d4", size = 3
      ) +
      theme_minimal()

    girafe(
      ggobj = p,
      options = list(
        opts_selection(type = "multiple", css = "fill:#f5a524;")
      )
    )
  })
}

shinyApp(ui, server)

Cette application fonctionne déjà — vous pouvez cliquer sur les points et ils se mettent en évidence — mais rien ne lit encore les clics. C’est l’étape suivante.

Lire la sélection de façon réactive : input$<id>_selected

Voici la règle clé : lorsqu’une sortie girafe est nommée "plot" et que son girafe() comporte opts_selection(), Shiny publie la sélection courante sous la forme input$plot_selected — un vecteur de caractères des valeurs data_id sélectionnées, mis à jour de façon réactive à chaque clic. Le motif est toujours input$<outputId>_selected.

Comme c’est une entrée réactive ordinaire, vous l’utilisez comme n’importe quelle autre : lisez-la dans un render*() pour construire une vue liée, ou surveillez-la avec observeEvent(). Ce serveur ajoute un tableau de détail qui liste exactement les voitures que le lecteur a sélectionnées :

server <- function(input, output) {
  output$plot <- renderGirafe({
    p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
      geom_point_interactive(
        aes(data_id = rownames(mtcars), tooltip = rownames(mtcars)),
        color = "#3a86d4", size = 3
      ) +
      theme_minimal()
    girafe(ggobj = p,
           options = list(opts_selection(type = "multiple", css = "fill:#f5a524;")))
  })

  # Linked view: a table of the selected cars, redrawn on every click.
  output$picked <- renderTable({
    selected <- input$plot_selected          # character vector of selected data_ids
    if (length(selected) == 0) return(NULL)  # nothing selected yet
    mtcars[selected, c("wt", "mpg", "hp")]   # subset by the returned row names
  }, rownames = TRUE)
}

Ajoutez tableOutput("picked") à l’UI sous girafeOutput("plot") et le tableau suit désormais la sélection en direct. Le même input$plot_selected peut piloter tout élément réactif — filtrer un second graphique, calculer un résumé des lignes choisies ou déclencher une exploration détaillée. Pour réagir à un clic plutôt que d’en dériver un rendu, enveloppez-le dans un observateur :

observeEvent(input$plot_selected, {
  message("Selected: ", paste(input$plot_selected, collapse = ", "))
})

Avec type = "single", input$plot_selected contient au plus une valeur, vous pouvez donc l’utiliser directement (par exemple mtcars[input$plot_selected, ]) pour une exploration détaillée classique du type « cliquer sur une ligne pour voir son détail ».

Enregistrer ou intégrer le girafe

Un appel à girafe() renvoie un htmlwidget — la même classe d’objet qu’une carte leaflet ou un graphique plotly — il s’intègre et s’enregistre donc comme n’importe quel widget. Deux conséquences en découlent :

Il s’intègre automatiquement dans n’importe quel rapport. Affichez un objet girafe() dans un document Quarto ou un rapport HTML R Markdown et il s’affiche en ligne, entièrement interactif, dans le fichier de sortie autonome — aucun serveur Shiny requis. C’est exactement ce qu’est le widget interactif ci-dessus : un girafe affiché dans cette page Quarto. L’interactivité qui nécessite un serveur actif (le input$plot_selected réactif) ne fonctionne qu’au sein de Shiny ; le survol, l’infobulle et la mise en évidence de la sélection au clic fonctionnent dans n’importe quel HTML statique.

Il s’écrit dans un fichier autonome. Pour remettre à quelqu’un un unique fichier HTML autonome du graphique, enregistrez le widget :

library(ggiraph)

gg <- girafe(ggobj = p, options = list(opts_selection(type = "multiple")))
htmlwidgets::saveWidget(gg, "cars.html")

Le fichier cars.html obtenu s’ouvre dans n’importe quel navigateur, avec les infobulles et la mise en évidence de la sélection intactes. C’est la limite honnête à enseigner : l’interactivité SVG voyage avec le fichier, mais lire une sélection en R est une capacité propre à Shiny, car elle a besoin du pont réactif actif.

🟢 Avec un agent IA

Demandez à Prova « comment faire pour qu’un second graphique ggiraph se filtre quand je clique sur un point du premier ? » — elle répond avec du code que vous pouvez exécuter, l’explication est donc reproductible. The runtime is the judge. Demandez à Prova →

Problèmes fréquents

input$plot_selected vaut toujours NULL. L’entrée de sélection n’existe que lorsque le girafe() comporte opts_selection() dans ses options. Sans elle, les clics ne font rien et aucune entrée _selected n’est publiée. Ajoutez opts_selection(type = "single") (ou "multiple") et vérifiez que l’id de sortie dans input$<id>_selected correspond à l’id que vous avez passé à girafeOutput() / output$<id>.

La sélection renvoie les mauvaises valeurs. input$plot_selected renvoie des valeurs data_id, pas des numéros de ligne. Ce que vous avez mappé à data_id est ce qui revient — ainsi mtcars[input$plot_selected, ] ne fonctionne que parce que data_id = rownames(mtcars). Si vous mappez data_id à un indice ou à un code, extrayez le sous-ensemble d’après celui-ci.

Rien ne se sélectionne, mais le survol fonctionne. Vous avez probablement utilisé un geom non interactif. La sélection nécessite geom_*_interactive() (par exemple geom_point_interactive()) avec un attribut esthétique data_id — un simple geom_point() n’a aucun id à sélectionner.

Questions fréquentes

Utilisez la paire girafeOutput("id") dans l’UI et renderGirafe({ girafe(ggobj = p) }) dans le serveur, où p est un ggplot construit avec geom_*_interactive(). L’id que vous donnez à girafeOutput() relie le widget à ses entrées réactives telles que input$id_selected.

Ajoutez opts_selection() à votre appel girafe(), puis lisez input$<outputId>_selected dans le serveur. C’est un vecteur de caractères réactif des valeurs data_id des éléments sélectionnés, mis à jour à chaque clic — utilisez-le dans un render*() pour une vue liée ou dans observeEvent() pour réagir au clic.

type = "single" autorise un seul élément sélectionné à la fois — cliquer sur un autre le remplace — de sorte que input$<id>_selected contient au plus une valeur. type = "multiple" laisse le lecteur activer et désactiver plusieurs éléments, et input$<id>_selected les renvoie tous. Utilisez "single" pour une exploration détaillée en cliquant sur une ligne et "multiple" pour constituer un ensemble.

Oui. Un objet girafe() est un htmlwidget autonome : affiché dans un document HTML Quarto ou R Markdown, il s’affiche en ligne avec les infobulles, le survol et la mise en évidence de la sélection au clic, et htmlwidgets::saveWidget() l’écrit dans un fichier HTML autonome. Seule la lecture d’une sélection en R (input$<id>_selected) nécessite un serveur Shiny actif.

Construisez le widget et passez-le à htmlwidgets::saveWidget(), par exemple saveWidget(girafe(ggobj = p), "chart.html"). La sortie est un unique fichier autonome qui s’ouvre dans n’importe quel navigateur avec son interactivité intacte.

Testez vos connaissances

Vous avez une application Shiny dont la sortie girafe est nommée "plot" et dont le girafe() utilise opts_selection(type = "multiple"), avec data_id = rownames(mtcars). Ajoutez un tableau réactif qui liste le wt, le mpg et le hp d’exactement les voitures que le lecteur a sélectionnées, et qui n’affiche rien lorsque la sélection est vide.

La sélection arrive sous la forme input$plot_selected (motif : input$<outputId>_selected) — un vecteur de caractères de data_id, qui sont ici des noms de ligne. Extrayez le sous-ensemble de mtcars avec elle dans un renderTable(), et protégez le cas vide avec if (length(...) == 0) return(NULL).

output$picked <- renderTable({
  selected <- input$plot_selected
  if (length(selected) == 0) return(NULL)
  mtcars[selected, c("wt", "mpg", "hp")]
}, rownames = TRUE)

Comme data_id = rownames(mtcars), input$plot_selected renvoie les noms de ligne sélectionnés, de sorte que mtcars[selected, ] extrait exactement ces lignes. La protection length(selected) == 0 n’affiche rien jusqu’à ce que le lecteur clique. Ajoutez tableOutput("picked") à l’UI pour l’afficher.

Une sortie girafe nommée "plot" utilise opts_selection() avec data_id = rownames(mtcars). Après que le lecteur a cliqué sur deux points, que contient input$plot_selected ?

Un vecteur de caractères des deux valeurs data_id sélectionnées — ici les deux noms de voiture (noms de ligne), par exemple c("Mazda RX4", "Valiant"). Il contient des valeurs data_id (pas des numéros de ligne), c’est pourquoi en extraire le sous-ensemble fonctionne uniquement lorsque data_id a été mappé aux noms de ligne.

Conclusion

Deux fonctions placent un graphique ggiraph dans Shiny — girafeOutput() dans l’UI et renderGirafe() dans le serveur — et opts_selection() transforme les clics en une sélection réactive que vous lisez depuis input$<id>_selected. À partir de là c’est de la réactivité ordinaire : piloter un tableau lié, filtrer un second graphique ou explorer en détail au clic unique. Et comme un girafe n’est qu’un htmlwidget, le même graphique s’insère dans n’importe quel rapport Quarto ou R Markdown et s’enregistre dans un fichier HTML autonome — vous n’avez besoin de Shiny que lorsque vous voulez que R lise la sélection.

Leçons connexes

Cette page vous a-t-elle été utile ?

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN
Note

Cette leçon est reproductible : les figures sont exécutées au moment de la génération (si elles s’affichent, le code fonctionne). Copiez n’importe quel bloc et exécutez-le pour reproduire ces graphiques. The runtime is the judge.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {ggiraph avec Shiny : sélection au clic et réactivité en R},
  date = {2026-07-09},
  url = {https://www.datanovia.com/learn/data-visualization/ggiraph/ggiraph-in-shiny},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“ggiraph avec Shiny : sélection au clic et réactivité en R.” 2026. July 9. https://www.datanovia.com/learn/data-visualization/ggiraph/ggiraph-in-shiny.