class: center, middle, inverse, title-slide # Mixing R and D3 ### R Pruim ### Big Data Ignite 2019 --- <style> .foo { background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/39/Naruto_Shiki_Fujin.svg); } .inverse { background-image: url(images/BDIorange-teal.jpg); background-size: cover; } .title-slide { background-image: url(images/BDIorange-teal.jpg); background-size: cover; } </style> # Outline 0. Some Teasers 1. Some Quick and Easy Things (No D3 knowledge required) * maps * converting ggplot2 to javascript * using plotly directly * other htmlwidgets 2. If you know some D3, then ... * ... D3 chunks in R markdown are an easy way to mix R and D3. * you might like to write your own htmlwidget --- class: center ## 15 Data Visualizations That Will Blow Your Mind <https://blog.udacity.com/2015/01/15-data-visualizations-will-blow-mind.html> <iframe width = 900 height = 470 src = "https://blog.udacity.com/2015/01/15-data-visualizations-will-blow-mind.html"/> --- class: center ## Visualizing US Gun Deaths <br> <https://guns.periscopic.com/?year=2013> <!-- <iframe width = 900 height = 470 src = "https://guns.periscopic.com/?year=2013"> --> --- ## Some Famous Data ```r data(gapminder, package = "gapminder") gapminder <- gapminder %>% mutate( iso = mosaic::standardCountry(country), # standard ISO codes for countries pop = round(pop / 1e6, 2), # population in millions gdpPercap = round(gdpPercap / 1000, 2)) # GDP in 1000s of $ G2007 <- gapminder %>% filter(year == 2007) ```
--- ## magrittr Pipes (a.k.a. Then Operator) In case you haven't seen `%>%` before, the following are *almost* equivalent: ```r f(x, a) x %>% f(a) ``` -- More interesting example: ```r x %>% f(a) %>% g(b1, b2) %>% h(c) h(g(f(x, a), b1, b2), c) ``` --- ## Little Bunny Foo Foo Little bunny Foo Foo Went hopping through the forest Scooping up the field mice And bopping them on the head. -- ### Without chaining ```r bop(scoop(hop(foo_foo, through = forest), up = field_mice), on = head) ``` -- ### With chaining ```r foo_foo %>% hop(through = forest) %>% scoop(up = field_mice) %>% bop(on = head) ``` --- ### Advantages of Chaining Chaining * reduces parenthesis chasing * keeps arguments near functions * mirrors order of operations (making code easier to read) * facilitates code editing (easy to eliminate or insert a step) --- class: inverse middle center # Quick and Easy #1: Maps with leaflet --- ## Simple maps with leaflet A simple interactive map can be created by specifying a location and zoom level. ```r library(leaflet) leaflet() %>% setView(-85.6721, 42.9683, 16) %>% addTiles() ```
--- ## Adding additional shapes Since our data are global in scope let's start with a slightly wider view. We can get country borders in JSON format and highlight them with `addPolygons()`. ```r map_url <- "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json" world_map <- geojsonio::geojson_read(map_url, what = "sp") m <- leaflet(world_map) %>% setView(0, 0, 1) %>% addTiles() *m %>% addPolygons(weight = 1) # default is 5 -- way too thick ```
--- ## Adding some data to our map We can join additional information to our map using a dplyr join function. ```r world_map@data <- world_map@data %>% * left_join(G2007, by = c("id" = "iso")) # join gapminder data ``` -- A color scale for the 5 quintiles of GDP per capita ```r bins <- quantile(world_map$gdpPercap, probs = (0:5)/5, na.rm = TRUE) color_scale <- colorBin("YlOrRd", domain = world_map$gdpPercap, bins = bins) color_scale(c(1, 2, 5, 10)) ``` ``` ## [1] "#FFFFB2" "#FECC5C" "#FD8D3C" "#F03B20" ``` --- ## Adding colors to the map ```r m <- leaflet(world_map) %>% setView(0, 0, 1) %>% addTiles() m %>% addPolygons( weight = 1, opacity = 1, color = "navy", * fillColor = ~ color_scale(gdpPercap), fillOpacity = 0.4 ) ```
--- ## Adding mouseover ```r m %>% addPolygons( weight = 1, opacity = 1, color = "navy", fillColor = ~ color_scale(gdpPercap), fillOpacity = 0.4, * highlight = * highlightOptions(weight = 2, fillOpacity = 0.9, bringToFront = TRUE) ) ```
--- ## Preparing some text labels for tooltips When we hover over country, we would like to see some information about that country. We can use HTML to make things look nice. ```r # create some HTML labels labels <- sprintf( "<strong>%s</strong><br/>GDP per capita: %g<br/>life exp: %g", world_map$name, world_map$gdpPercap, world_map$lifeExp ) %>% lapply(htmltools::HTML) ``` --- ## Adding tooltips ```r m %>% addPolygons( weight = 1, opacity = 1, color = "navy", fillColor = ~ color_scale(gdpPercap), fillOpacity = 0.4, highlight = highlightOptions(weight = 2, fillOpacity = 0.9, bringToFront = TRUE), * label = labels ) ```
--- class: inverse middle center # Quick and Easy #2: ggplot2 + ggplotly() --- ## Example plot Here's a quick ggplot2 plot (using ggformula). ```r library(ggformula) gf_point(lifeExp ~ gdpPercap, data = G2007, color = ~ continent, size = ~pop, alpha = 0.4, show.legend = FALSE) %>% gf_refine(scale_x_log10()) ``` <img src="BDI2019-slides_files/figure-html/unnamed-chunk-17-1.png" style="display: block; margin: auto;" /> --- ## And now it is interactive! We just need to add one call to `plotly::ggplotly()` to make our plot interactive. ```r *library(plotly) gf_point(lifeExp ~ gdpPercap, data = G2007, color = ~ continent, size = ~pop, alpha = 0.4, show.legend = FALSE) %>% gf_refine(scale_x_log10()) %>% * ggplotly() ```
--- ## Improved interactivity ```r library(plotly) gf_blank(lifeExp ~ gdpPercap, data = G2007, color = ~ continent, size = ~pop, text = ~ paste("country:", country)) %>% gf_point(alpha = 0.6) %>% gf_refine(scale_x_log10()) %>% *ggplotly(tooltip = c("text", "colour")) ```
--- ## Quick and Easy #2: ggplot2 + ggplotly() ### Summary 1. Very quick and easy -- 2. You get what you pay for -- * some annoying features (like duplicated info in tooltips) * doesn't always do what you want * may need to jump through some ggplot2 hoops to get closer to what you want * but often good enough for quick interactivity for personal use --- class: inverse middle center # Quick and Easy #3: plotly without ggplot2 --- ## Quick and Easy #3: plotly without ggplot2 Part of the trouble with #2 is that things have to be inferred from what ggplot2 stores in the plot object (and translated to json/javascript). But we can also use plotly "natively" and avoid the translation step. * downside: need to learn a new plotting system * fortunately: it is pretty similar to ggformula --- ## plot_ly example ```r plot_ly(data = G2007, type = "scatter", alpha = 0.4, x = ~ gdpPercap, y = ~ lifeExp, color = ~ continent, size = ~ pop) %>% layout(xaxis = list(type = "log")) ```
--- ## Adding tooltip info with text = ```r plot_ly(data = G2007, type = "scatter", alpha = 0.4, x = ~ gdpPercap, y = ~ lifeExp, color = ~ continent, size = ~ pop, * text = ~country) %>% layout(xaxis = list(type = "log")) ```
--- ## Animating multiple years ```r plot_ly(data = gapminder, type = "scatter", alpha = 0.4, text = ~country, x = ~ gdpPercap, y = ~ lifeExp, color = ~ continent, size = ~ pop, * frame = ~ year) %>% layout(xaxis = list(type = "log")) ```