class: center, middle, inverse, title-slide # package ggiraph ## make ggplot interactive ### David Gohel @ ArData.fr ### 2017-11-19 --- # About me <div style="font-family:Lobster;padding:30pt;text-align:center;font-size:40pt;color:#AA9961;">freelanceR based in Paris.</div> *When possible, I am open-sourcing...* --- # Goal <div class="listwithicon"> <ul> <li><strong>Quickly publish on web ggplot2 outputs</strong><img src="libs/media/ggplot2.png"/></li> <li><strong>With basic animations</strong><img src="libs/media/D3js.png"/></li> <li><strong>And shiny interactivity</strong><img src="libs/media/shiny.png"/></li> </ul> </div> An htmlwidget extending [ggplot2](https://CRAN.R-project.org/package=ggplot2) with D3.js (version 4) and package [rvg](https://CRAN.R-project.org/package=rvg). --- # `ggplot2` graphics *gg*: grammar of graphics *“The Grammar of Graphics” from Wilkinson, Anand et Grossman (2005)* -- ggplot2 is separating : * data -- * coordinates system -- * graphical elements (points, polygons, etc.) -- graphical elements are on layers. Layers are superposed with `+` operator. --- class: middle <img src="libs/media/ggplot_skeleton1.png" height="617px" width="988px"> --- # An example code ```r library(ggplot2) gg <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length) ) + geom_point(colour = "red", size = 3) print(gg) ``` <!-- --> --- # An example code ```r library(ggiraph) gg <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, tooltip = Species, data_id = Species )) + geom_point_interactive(colour = "red", size = 3 ) ``` ```r ggiraph(ggobj = gg) ``` ---
--- # Geoms aesthetics <div style="font-family:Lobster;padding:30pt;text-align:center;font-size:50pt;color:#AA9961;">3 new parameters</div> <div class="listwithicon"> <ul> <li><code>tooltip</code></li> <li><code>data_id</code>: id setter (hover effects and shiny interaction)</li> <li><code>onclick</code>: click events</li> </ul> </div> --- # Existing geoms
geom_bar_interactive
geom_boxplot_interactive
geom_line_interactive
geom_map_interactive
geom_path_interactive
geom_point_interactive
geom_polygon_interactive
geom_rect_interactive
geom_segment_interactive
geom_text_interactive
geom_tile_interactive
--- class: inverse, middle, center # Create a dynamic map --- ## Data preparation ```r map <- map_data("france") legis_data <- read_excel("data/Leg_2017_Resultats_T1_c.xlsx", sheet = "Departements T1", skip = 1) %>% transmute( cod_dep = `Code du département`, lib_dep = stri_trans_general(`Libellé du département`, "Latin-ASCII"), abs_ratio = `% Abs/Ins` ) %>% mutate(lib_dep = case_when(lib_dep == "Cote-d'Or" ~ "Cote-Dor", lib_dep == "Cotes-d'Armor" ~ "Cotes-Darmor", lib_dep == "Corse-du-Sud" ~ "Corse du Sud", lib_dep == "Val-d'Oise" ~ "Val-Doise", lib_dep == "Corse-du-Sud" ~ "Corse du Sud", TRUE ~ lib_dep)) result_map <- left_join(x = map, y = legis_data, by = c("region" = "lib_dep") ) head(result_map) ``` ``` ## long lat group order region subregion cod_dep abs_ratio ## 1 2.557093 51.09752 1 1 Nord <NA> 59 54.04 ## 2 2.579995 51.00298 1 2 Nord <NA> 59 54.04 ## 3 2.609101 50.98545 1 3 Nord <NA> 59 54.04 ## 4 2.630782 50.95073 1 4 Nord <NA> 59 54.04 ## 5 2.625894 50.94116 1 5 Nord <NA> 59 54.04 ## 6 2.597699 50.91967 1 6 Nord <NA> 59 54.04 ``` --- ## `ggplot` creation ```r title <- "Abstention rate" subtitle <- "First round of legislative election - 2017" caption <- "source: https://www.data.gouv.fr/fr/datasets/elections-legislatives-des-11-et-18-juin-2017-resultats-du-1er-tour" fr_map <- ggplot(result_map, aes(long, lat, group = group, fill = abs_ratio) ) fr_map <- fr_map + geom_polygon_interactive(mapping = aes(data_id = region, tooltip = abs_ratio), colour = "white", size = .3) + coord_map() fr_map <- fr_map + scale_fill_gradient(name = "", low = "#006699", high = "red", limits = c(40, 60) ) + labs(x = "", y = "", title = title, subtitle = subtitle, caption = caption) ``` --- ## `ggplot` display ```r print(fr_map) ``` <!-- --> --- ## `ggplot` display using `ggiraph` ```r extra_css <- "background-color:#333333;font-style:italic;color:white;padding:10pt;" ggiraph( ggobj = fr_map, tooltip_extra_css = extra_css, tooltip_offy = -20, zoom_max = 3 ) ``` ---
--- # A dynamic heatmap <!-- --> --- ```r ggiraph(ggobj = p, width = 1, width_svg = 10, height_svg = 6) ```
--- class: center, middle, inverse # Shiny interactivity --- class: center, middle, inverse ## [Standard shiny example](http://127.0.0.1:12346) --- class: center, middle, inverse ## [flexdashboard example](http://127.0.0.1:12345/flexdashboard.Rmd) Use arguments `flexdashboard = TRUE, use_widget_size = TRUE` when working with flexdashboard. --- ## Shiny manipulations ggiraphOutput has `outputId` **X**. > How to get the selected id? The reactive value is available in `input$X_selected`. > How to set selected id from shiny? ``` session$sendCustomMessage(type = 'X_set', message = a_character_vector) ``` --- # Future *Solve:* <div class="listwithicon"> <ul> <li>Windows and UTF8</li> <li>Hover effect over duplicated ids</li> </ul> </div> *Enhance:* <div class="listwithicon"> <ul> <li>highlight data series closest to the pointer</li> <li>Rectangular zoom and selections</li> <li>new geoms</li> </ul> </div> --- class: center, middle, inverse # More examples --- ## Interactive mekko charts Originally coded by Data-journalist [Duc Quang Nguyen](https://dqn.website/post/interactive-mekko-charts-in-r) ---
--- ## Interactive bar charts <script> var coincoin = new Audio("./libs/media/Duck.ogg" ) ; var ouahouah = new Audio("./libs/media/Sound-of-dog.ogg" ) ; var meow = new Audio("./libs/media/Meow.ogg" ) ; </script>
--- # Ressources <img src="libs/media/ggiraphlogo.svg" width="15%"/> website: [davidgohel.github.io/ggiraph](https://davidgohel.github.io/ggiraph) stackoverflow: [tag ggiraph](https://stackoverflow.com/questions/tagged/ggiraph) ```r list.files(system.file(package = "ggiraph", "shiny")) ``` ``` ## [1] "cars" "crimes" "DT" "iris" "maps" ``` --- class: inverse, center, middle # Thank you, any question?