diff --git a/courses/04-interactivite.Rmd b/courses/04-interactivite.Rmd new file mode 100644 index 0000000..86ed210 --- /dev/null +++ b/courses/04-interactivite.Rmd @@ -0,0 +1,361 @@ +--- +title: "Interactivité" +author: "Maxime Wack" +date: "20/11/2019" +output: + xaringan::moon_reader: + css: ['default','css/my_style.css'] + lib_dir: libs + seal: false + nature: + ratio: '4:3' + countIncrementalSlides: false + self-contained: true + beforeInit: "addons/macros.js" +--- + +```{r, include = FALSE} +library(gapminder) +library(tidyverse) +library(DT) +library(knitr) + +opts_chunk$set(message = F) + +options(DT.options = list(paging = F, + info = F, + searching = F)) + +datatable <- partial(datatable, rownames = F) +``` + +class: center, middle, title + +# UE Visualisation + +### 2019-2020 + +## Dr. Maxime Wack + +### AHU Informatique médicale +#### Hôpital Européen Georges Pompidou,
Université de Paris + +--- +class: center, middle + +# Objectif + +## Ajouter de l'**interactivité** à une visualisation + +--- + +# Interactivité + +## Réactivité + +L'objet **réagit** à l'utilisateur, mais n'est pas modifié + +## Interactivité + +L'utilisateur peut **influer** sur l'objet
+Un objet peut en **modifier** un autre + +--- +class: center + +# Outils + +### ggplot2 + ggplotly + +### plotly + +### D3 + +### VegaLite + +### Shiny + +--- +class: center, middle + +# ggplot2 + ggplotly + +--- + +### Installer `plotly` + +```{r install plotly, eval = F} +install.packages("plotly") +``` + +```{r libs} +library(tidyverse) +library(plotly) +``` + +--- + +```{r ggplotly simple} +iris %>% + ggplot() + + aes(x = Petal.Length, fill = Species) + + geom_histogram() -> plot + +ggplotly(plot) +``` + +--- + +```{r ggplotly pipe} +(iris %>% + ggplot() + + aes(x = Petal.Length, y = Petal.Width, color = Species) + + geom_point()) %>% + ggplotly +``` + +--- + +```{r ggplotly complex} +iris %>% + ggplot() + + geom_histogram(data = iris %>% select(-Species), aes(x = Petal.Length)) + + geom_histogram(aes(x = Petal.Length, fill = Species)) + + facet_grid(~Species) -> plot + +ggplotly(plot) +``` + +--- +class:center, middle + +# Plotly + +--- + +# Plotly + +### Utilise aussi une **grammaire de graphiques** + +### Bibliothèque **JS** + +### Interface par un **package R** + +### Couche d'**abstraction** pour ggplot2 + +https://plot.ly/r + +--- + +# Plotly + +### `ggplot` → `plot_ly()` + +### `geom_*` → `add_*` ou `add_trace` + +Les *aes* sont données avec des formules dans les traces + +### `facet_*` → **subplots** + +### `scale_*_*` + `theme` → `layout` + +### `+` → `%>%` + +--- + +```{r plotly simple} +iris %>% + plot_ly() %>% + add_markers(x = ~Sepal.Length, + y = ~Sepal.Width) +``` + +--- + +```{r plotly global aes} +iris %>% + plot_ly(x = ~Sepal.Length, + y = ~Sepal.Width) %>% + add_trace(color = ~Species, + size = 4, + mode = "markers") +``` + +--- + +```{r plotly hover} +iris %>% + plot_ly(x = ~Sepal.Length, + y = ~Sepal.Width, + color = ~Species) %>% + add_markers(size = 2, + hoverinfo = "text", + text = ~str_c("Espèce : ", Species, "\n", + "Longueur de sépale :", Sepal.Length, "\n", + "Largeur de sépale :", Sepal.Width)) +``` + +--- + +# Plotly + +### Interaction poussée (JS) + +### Animations (frame) + +*Aesthetic* d'animation, variable définissant l'état à chaque image clé + +--- +class:center, middle + +```{r plotly anim, warning = F, echo = F} +gapminder %>% + plot_ly(x = ~gdpPercap, + y = ~lifeExp, + size = ~pop, + frame = ~year, + color = ~continent, + text = ~country, + hoverinfo = "text") %>% + add_markers() %>% + layout(xaxis = list(type = "log")) %>% + animation_opts(1000) +``` + +--- + +# D3 + +.pull-left[ +### **D**ata **D**riven **D**ocuments +### Créé par **Mike Bostock** +*Data journalist* au NYT +] + +.pull-right[ +![:scale 50%](04_img/bostock.jpg) +] + +### Moteur *bas niveau* pour manipuler des éléments du DOM et du SVG à partir de données. + +### Notion de grammaire liant données et propriétés CSS, dont **animations** et **transitions** + +.center[https://d3js.org] + +--- +class: center + +# Outils dérivés de D3.js + +## Plot.ly + +## Vega(lite) + +## C3.js + +## R2D3 https://rstudio.github.io/r2d3/ + +--- + +# Réactivité + +## Tous les outils précédents sont **réactifs** + +### → affichage d'un overlay + +### → changement de position/échelle + +### → afficher / masquer / réordonner + +(modulo interactions en *JS* à bricoler soi-même) + + +--- + +# Interactivité + +## Manipulation des données + +## Interactions avec la visualisation + +## Interactions entre éléments de visualisation + +--- + +# Shiny + +### Architecture client/serveur + +### Client = interface web + +### Serveur = runtime R + +https://shiny.rstudio.com/ + +--- + +# Shiny + +## Programmation **événementielle** → programmation **réactive** + +## L'interface est mise à jour *quand nécessaire* + +--- + + +# Interface web + +### Créée dans R + +### Génère HTML + CSS + JS + +### Définit des **input** et **output** + +--- + +# UI + +```{r shiny ui, eval = F} +ui <- fluidPage(titlePanel = "Titre", + sidebarLayout( + sidebarPanel( + sliderInput(inputId = "bins", + label = "Bins", + min = 1, + max = 50, + value = 30, + animate = animationOptions(interval = 100))), + mainPanel(plotOutput(outputId = "figure")))) +``` + +--- + +# Serveur + +### Créé et exécuté dans R + +### Génère les éléments d'**output** en fonction des **input** + +### Les **outputs** peuvent *générer* de l'input (htmlwidgets : DT, plotly, etc.) + +### Le serveur peut créer des **input** dynamiques + +--- + +# Server + +```{r shiny server, eval = F} +server <- function(input, output, session) +{ + set.seed(1234) + normale <- tibble(val = rnorm(1000)) + + output$figure <- renderPlot( + { + normale %>% + ggplot() + + aes(x = val) + + geom_histogram(bins = input$bins) + }) +} +``` diff --git a/courses/04_img/bostock.jpg b/courses/04_img/bostock.jpg new file mode 100644 index 0000000..5fd0c75 Binary files /dev/null and b/courses/04_img/bostock.jpg differ