class: center, middle, inverse, title-slide <h1 class = "celeste-ish" style="line-height: 90px; margin-top: -50px;"> Clase 5: <p style="margin-bottom: -170px;"> </p> Flexdashboard y<br> htmlwidgets </h1> <h3 class = "celeste-ish" style = "position: absolute; bottom: 80px;"> Autor: Lucio Cornejo </h3> --- ## Flexdashboard <p style="margin-bottom: -85px;"> </p> Un **dashboard** es como un _resumen_ empleado para mejorar la toma de decisiones, cuyo objetivo es **transformar data en información**. En un **dashboard** se recopilan datos y estos se presentan de manera concisa para resaltar lo más importante que deducimos a partir de aquella información. Ejemplos de [proyectos](https://rstudio.github.io/flexdashboard/articles/examples.html) realizados con el paquete flexdashboard. > Ok ok ... pero ... ¿de dónde viene el _flex_? El paquete **flexdashboard** emplea la propiedad `display: flex` de **CSS** para alterar el ancho y altura de ciertos elementos de la página con el fin de llenar _lo mejor posible_ el espacio disponible en la pantalla del dispositivo. <p style="margin-bottom: -30px;"> </p> ## Instalación <p style="margin-bottom: -85px;"> </p> ```r install.packages('flexdashboard') ``` --- class: middle ## Encabezado YAML básico de proyecto flexdashboard ```yaml --- title: Proyecto con flexdashboard output: flexdashboard::flex_dashboard: orientation: columns # rows vertical_layout: fill # scroll --- ``` <p style="margin-bottom: -35px;"> </p> ### `orientation` Establece si añadimos secciones (al dashboard ) por columnas o por filas. <p style="margin-bottom: -35px;"> </p> ### `vertical_layout` Con `fill`, los gráficos se autoajustan para cubrir toda la pantalla; pero, con `scroll`, los gráficos preservan su altura natural, y la página permitirá desplazarse verticalmente _fuera de la pantalla_. --- <p style="margin-bottom: -85px;"> </p> ## Modelo para `vertical_layout: scroll` <p style="margin-bottom: -80px;"> </p> ````yaml --- output: flexdashboard::flex_dashboard: vertical_layout: scroll --- ### Gráfico 1 ```{r} AirPassengers ``` ### Gráfico 2 ```{r} plot(pressure) ``` ### Gráfico 3 ```{r} mtcars ``` ```` --- class: middle ## Manos a la obra Iniciaremos creando un documento **R Markdown** de este tipo: ````text --- title: Mi dashboard output: flexdashboard::flex_dashboard: theme: default orientation: columns vertical_layout: fill --- ```{r setup, include=FALSE} library(flexdashboard) ``` # Layout 1 ```` --- class: middle ## Creación de columnas y filas <p style="margin-bottom: -80px;"> </p> Los símbolos `#` , `##` y `###` adquieren un nuevo significado: `DEMOSTRACIÓN` <br> ## Alteración de ancho y altura de las secciones creadas <p style="margin-bottom: -80px;"> </p> ```md ## {data-width=700} ### {data-height=200} ### {data-height=800} ## {data-width=300} ### {data-height=1} ### {data-height=999} ``` <br> ### Plantillas visuales para flexdashboard <p style="margin-bottom: -40px;"> </p> <details> <summary> Presionar para revelar mis secretos </summary> default<br> cosmo<br> bootstrap<br> cerulean<br> journal<br> flatly<br> readable<br> spacelab<br> united<br> lumen<br> paper<br> sandstone<br> simplex<br> yeti<br> </details> --- .pull-left[ ## valueBox <p style="margin-bottom: -80px;"> </p> ````text ### Mensaje ```{r, echo = FALSE} value <- 13 valueBox(value, icon = "fa-trash", href = "#htmlwidgets", # tal link solo dirige a páginas/layouts color = ifelse(value > 10, "warning", "primary")) # "succes" "danger" disponibles también ``` ```` <p style="margin-bottom: -60px;"> </p> ## gauge <p style="margin-bottom: -80px;"> </p> ````text ### Gráfico ```{r, echo = FALSE} level <- 42 gauge(level, min=0, max=100, symbol="%", gaugeSectors( success = c(90,100), warning = c(70,89), danger = c(0,69) )) ``` ```` ] .pull-right[ ## Uso de tabsets ```text ## {.tabset} ### Tab 1 contenido 1 ### Tab 2 contenido 2 ``` <p style="margin-bottom: -30px;"> </p> ## Creación de nuevos layouts ```text # Layout 2 {data-icon=fa-frog} ## ### Fila solitaria ``` ] --- <p style="margin-bottom: -70px;"> </p> ## Uso de íconos para el navegador <p style="margin-bottom: -80px;"> </p> - [Ejemplos](https://fontawesome.com/v5.15/icons) de íconos, aunque no todos están disponibles en flexdashboard. - **No dejar espacio entre los extremos del símbolo** _=_ **al definir _data-icon="fa-sth"_** <p style="margin-bottom: -60px;"> </p> ## Cambiar la orientación de una página/layout <p style="margin-bottom: -80px;"> </p> ```md # Filas {data-orientation=rows} ## {data-height=700} ### Columna 1 {data-width=300} ### Columna 2 {data-width=700} ## {data-height=300} ### Columna 3 ### Columna 4 ``` ## Incluir en el sitio web el código Rmd del dashboard <p style="margin-bottom: -80px;"> </p> ```yaml output: flexdashboard::flex_dashboard: source_code: embed ``` --- class: middle ## Customización de la barra de navegación ```yaml output: flexdashboard::flex_dashboard: favicon: favicon.ico # También puede ser .png . logo: logo.png # La imagen no será reescalada. social: - twitter - facebook - google-plus - linkedin - pinterest - menu # contiene todas las redes sociales disponibles por default navbar: - title: "About" icon: far fa-folder-open # misma manera que se definen en _site.yml href: "temporal.html" # https://www.google.com align: left # right ``` ??? El logo debería tener 48 pixels de altura para que "se vea bien" en el barra de navegación de la plantilla "cosmo", pero **otras plantillas podrían tener distintas alturas para la barra de navegación.** --- ## Organizar las páginas/layouts en secciones <p style="margin-bottom: -70px;"> </p> ```md # Página A.1 {data-navmenu="Sección A"} ## Column ### Fila A.1.1 ### Fila A.1.2 # Página A.2 {data-navmenu="Sección A" data-icon="fa-frog"} ## ### Fila A.2.1 [Link](#primer-secreto) al primer secreto. ## ### Fila A.2.2 # Primer secreto {data-navmenu="Secretos" .hidden} Escondemos esta página del menú donde está contenida, pero aún es posible acceder a la página vía el link que usamos para llegar acá. [Math has a fatal flaw](https://www.youtube.com/watch?v=HeQX2HjkcNo&t=64s&ab_channel=Veritasium) ``` --- class: middle ## Storyboards <p style="margin-bottom: -80px;"> </p> Cuando se requiere presentar una secuencia de visualizaciones de data, con comentarios respectivos, podemos emplear la opción ```yaml output: flexdashboard::flex_dashboard: storyboard: true ``` Revisemos el siguiente [ejemplo](https://beta.rstudioconnect.com/jjallaire/htmlwidgets-showcase-storyboard/htmlwidgets-showcase-storyboard.html) de una **storyboard** creada con **flexdashboard**. También es posible que no todo el dashboard posea el modo **storyboard**, sino alguna(s) de sus páginas. --- <p style="margin-bottom: -70px;"> </p> ## Página/layout en modo `storyboard` <p style="margin-bottom: -80px;"> </p> ````md # Déjame que te cuente limeñe ... {.storyboard} ### Frame 1 {data-commentary-width=1000} ```{r} plot(pressure) ``` --- Comentario para el primer frame. Para **storyboard**, ya no se usan los encabezados de nivel 2. ### Corta descripción para el segundo frame, pero corta en serio porque si nos sobrepasamos del espacio disponible en la sección de la página web para este texto, no será visible el texto que se sobrepasó al espacio disponible. ```{r} #| echo: FALSE knitr::include_graphics(xaringan:::karl) ``` --- Who dat? ```` --- class: middle ## Referencias <p style="margin-bottom: -80px;"> </p> - <https://pkgs.rstudio.com/flexdashboard/articles/> - <https://pkgs.rstudio.com/flexdashboard/articles/using.html> - <https://warin.ca/dpr/dashboards.html#storyboards> --- class: middle ## htmlwidgets Este paquete de **R** nos permite emplear directamente en **R** (y **R Markdown** ) librerías de **JavaScript** especializadas en visualización de datos. Asimismo, la librería **htmlwidgets** nos da la posibilidad de crear nuestro propio **widget** para poder emplear vía **R** alguna librería de **JavaScript** de nuestro interés. En esta sesión, trabajaremos con solo algunas de las librerías de **JavaScript** que el paquete **htmlwidgets** nos facilita utilizar en **R**. ??? - Ejecutar los htmlwidgets en un archivo **.R** por separado. - Instalar el paquete `tidyverse`. --- ## Leaflet <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutorial:<br> <https://rstudio.github.io/leaflet/> Listado de funciones:<br> <https://cran.r-project.org/web/packages/leaflet/leaflet.pdf> ```r install.packages("leaflet") library(leaflet) ``` ] .panel[.panel-name[Creación de un mapa] ```r leaflet() %>% addTiles() %>% addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R") ```
] .panel[.panel-name[¿Dónde me encuentro?] [Obtener mis coordenadas](https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-CD0101EN-SkillsNetwork/labs/demos/geo-location-demo.html?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-coursesedxorg-SkillsNetworkCoursesIBMDeveloperSkillsNetworkCD0101ENSkillsNetwork20336975-2021-01-01) ```r leaflet() %>% setView(lng = -71.0589, lat = 42.3601, zoom = 17) %>% addTiles() ``` ] .panel[.panel-name[Mapa de clusters] ```r leaflet(quakes) %>% addTiles() %>% addMarkers(clusterOptions = markerClusterOptions()) ``` ] ] ??? Ejecutar secuencialmente el primer ejemplo de un mapa. --- ## Dygraphs <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutorial:<br> <https://rstudio.github.io/dygraphs/> Listado de funciones:<br> <https://cran.r-project.org/web/packages/dygraphs/dygraphs.pdf> ```r install.packages("dygraphs") library(dygraphs) ``` ] .panel[.panel-name[Ejemplo 1] ```r dygraph(mdeaths) %>% dyRangeSelector() ```
] .panel[.panel-name[Ejemplo 2] ```r dygraph(nhtemp, main = "New Haven Temperatures") %>% dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01")) %>% dyOptions(fillGraph = TRUE, fillAlpha = 0.25) ``` ] .panel[.panel-name[Ejemplo 3] ```r dygraph(nhtemp, main = "New Haven Temperatures") %>% dySeries(label = "Temp (F)", color = "black") %>% dyShading(from = "1920-1-1", to = "1930-1-1", color = "rgba(255,0,0,0.25)") %>% dyShading(from = "1947-1-1", to = "1955-1-1", color = "#E6E6FF") ``` ] ] ??? **Time-series** en R: <https://www.statmethods.net/advstats/timeseries.html> --- ## Plotly <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutorial:<br> <https://plotly.com/r/> Listado de funciones:<br> <https://cran.r-project.org/web/packages/plotly/plotly.pdf> ```r install.packages('plotly') library(plotly) ``` ] .panel[.panel-name[Ejemplo 1] ```r plot_ly(mtcars,y=~wt,type='box') #### Intento de simular que plotly oculte los valores atípicos, #### ya que por ahora no se posee aquella funcionalidad # plot_ly(mtcars, y=~wt, type='box', marker=list(opacity=0)) ``` ] .panel[.panel-name[Ejemplo 2] ```r plot_ly(iris,x=~Sepal.Length,color=~Species,type='box') %>% layout(xaxis=list(showticklabels = TRUE)) %>% config(displayModeBar= FALSE) # esconder barra de la parte superior ``` ] .panel[.panel-name[Ejemplo 3] ```r plot_ly(iris,y=~Sepal.Length,color=~Species,type='box') %>% layout(xaxis=list(title='Species'), yaxis= list(zeroline=FALSE)) # no esconder "marcas" en eje X ``` ] .panel[.panel-name[Ejemplo 4] ```r accumulate_by <- function(dat, var) { var <- lazyeval::f_eval(var, dat) lvls <- plotly:::getLevels(var) dats <- lapply(seq_along(lvls), function(x) { cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]]) }) dplyr::bind_rows(dats) } iris2 <- iris iris2$indices <- 1:nrow(iris2) iris2 %>% accumulate_by(~indices) %>% plot_ly( x = ~indices, y = ~Sepal.Length, frame = ~frame, type = 'scatter', mode = 'lines' # unir vía líneas los puntos consecutivos del gráfico ) %>% animation_opts( frame = 50, transition = 0, redraw = FALSE # dibujar el gráfico tras cada transición ) ```
] ] --- count: false ### Gráficos 3D .panel1-plotly-3d-auto[ ```r *plot_ly(z = ~volcano) ``` ] .panel2-plotly-3d-auto[ ``` ## No trace type specified: ## Based on info supplied, a 'heatmap' trace seems appropriate. ## Read more about this trace type -> https://plotly.com/r/reference/#heatmap ```
] --- count: false ### Gráficos 3D .panel1-plotly-3d-auto[ ```r plot_ly(z = ~volcano) %>% * add_surface( * contours = list( * z = list( * show=TRUE, * usecolormap=TRUE, * highlightcolor="red", * project=list(z=TRUE) * ) * ) *) ``` ] .panel2-plotly-3d-auto[
] --- count: false ### Gráficos 3D .panel1-plotly-3d-auto[ ```r plot_ly(z = ~volcano) %>% add_surface( contours = list( z = list( show=TRUE, usecolormap=TRUE, highlightcolor="red", project=list(z=TRUE) ) ) ) %>% * layout( * scene = list( * camera=list( * eye = list(x=1.87, y=0.88, z=-0.64) * ) * ) *) ``` ] .panel2-plotly-3d-auto[
] <style> .panel1-plotly-3d-auto { color: black; width: 49%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-plotly-3d-auto { color: black; width: 49%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-plotly-3d-auto { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> <style> #plotly-3d { margin-bottom: 2%; } .panel1-plotly-3d-auto .remark-code-line { width: 700px; } .panel2-plotly-3d-auto .remark-code-line { display: none; } :root { --code-highlight: rgba(200,0,100,0.5) !important; } </style> --- ## visNetwork <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutoriales:<br> - <https://datastorm-open.github.io/visNetwork/> - <https://cran.r-project.org/web/packages/visNetwork/vignettes/Introduction-to-visNetwork.html> Listado de funciones:<br> <https://cran.r-project.org/web/packages/visNetwork/visNetwork.pdf> ```r install.packages('visNetwork') library(visNetwork) ``` ] .panel[.panel-name[Ejemplo 1] ```r vertices <- data.frame(id = 1:4, shape = c("circle", "square"), label = LETTERS[1:4]) aristas <- data.frame(from = c(2,4,3,3), to = c(1,2,4,2)) visNetwork(vertices, aristas, width = "100%") %>% visNodes(color = list(background = "lightblue", border = "darkblue", highlight = "yellow"), shadow = list(enabled = TRUE, size = 10)) %>% visLayout(randomSeed = 12) # para tener siempre el mismo grafo ``` ] .panel[.panel-name[Ejemplo 2] ```r aristas <- data.frame(from = c(2,3,5,7), to = c(1,4,6,10), length = c(100,250,500,700), width = c(1,2,3,5), arrows = c("to", "from", "to;from", "to"), dashes = c(TRUE, FALSE, TRUE, FALSE), smooth = c(FALSE, TRUE, FALSE, TRUE), shadow = c(FALSE, TRUE, FALSE, TRUE) ) vertices <- data.frame(id = 1:6, label=LETTERS[1:6], group = c("Y", "N")) visNetwork(vertices, aristas, height = "500px", width = "100%") %>% visLayout(randomSeed = 42) ``` ] .panel[.panel-name[Ejemplo 3] <https://datastorm-open.github.io/visNetwork/image_icon.html> ```r vertices <- data.frame(id = 1:3, group = c("B", "A", "B")) aristas <- data.frame(from = c(1,2), to = c(2,3)) visNetwork(vertices, aristas, width = "100%") %>% visGroups(groupname = "A", shape = "icon", icon = list(code = "f0c0", size = 75)) %>% visGroups(groupname = "B", shape = "icon", icon = list(code = "f007", color = "red")) %>% addFontAwesome() ``` ] .panel[.panel-name[Ejemplo 4] ```r vertices <- data.frame(id = 1:7) aristas <- data.frame(from = c(1,2,2,2,3,3), to = c(2,3,4,5,6,7) ) visNetwork(vertices, aristas, width = "100%") %>% visEdges(arrows = "middle") %>% visHierarchicalLayout() ``` ] .panel[.panel-name[Ejemplo 5] ```r vertices <- data.frame(id = 1:50) aristas <- data.frame(from = sample(1:50, 100, replace = TRUE), to = sample(1:50, 100, replace = TRUE) ) visNetwork(vertices, aristas, width= "100%") %>% visIgraphLayout(layout = "layout_in_circle") %>% visNodes(size = 10) ``` ] ] ??? Actualizar página cada vez que muestro un nuevo ejemplo. --- count: false ### Grafos aleatorios .panel1-custom-graph-1-5[ ```r espacio_muestral <- prob::urnsamples( x = 1:6, size = 2, replace = FALSE, ordered = FALSE ) vertices <- data.frame( id = 1:6, title = paste( "node", 1:6 ), shape = "dot", size = 15, color = "lightblue" ) aristas <- espacio_muestral %>% slice_sample(n=5) colnames(aristas) <- c("from","to") visNetwork(vertices, aristas) ``` ] .panel2-custom-graph-1-5[
] --- count: false ### Grafos aleatorios .panel1-custom-graph-1-5[ ```r espacio_muestral <- prob::urnsamples( x = 1:6, size = 2, replace = FALSE, ordered = FALSE ) vertices <- data.frame( id = 1:6, title = paste( "node", 1:6 ), shape = "dot", size = 15, color = "lightblue" ) aristas <- espacio_muestral %>% slice_sample(n=5) colnames(aristas) <- c("from","to") visNetwork(vertices, aristas) ``` ] .panel2-custom-graph-1-5[
] --- count: false ### Grafos aleatorios .panel1-custom-graph-1-5[ ```r espacio_muestral <- prob::urnsamples( x = 1:6, size = 2, replace = FALSE, ordered = FALSE ) vertices <- data.frame( id = 1:6, title = paste( "node", 1:6 ), shape = "dot", size = 15, color = "lightblue" ) aristas <- espacio_muestral %>% slice_sample(n=5) colnames(aristas) <- c("from","to") visNetwork(vertices, aristas) ``` ] .panel2-custom-graph-1-5[
] --- count: false ### Grafos aleatorios .panel1-custom-graph-1-5[ ```r espacio_muestral <- prob::urnsamples( x = 1:6, size = 2, replace = FALSE, ordered = FALSE ) vertices <- data.frame( id = 1:6, title = paste( "node", 1:6 ), shape = "dot", size = 15, color = "lightblue" ) aristas <- espacio_muestral %>% slice_sample(n=5) colnames(aristas) <- c("from","to") visNetwork(vertices, aristas) ``` ] .panel2-custom-graph-1-5[
] --- count: false ### Grafos aleatorios .panel1-custom-graph-1-5[ ```r espacio_muestral <- prob::urnsamples( x = 1:6, size = 2, replace = FALSE, ordered = FALSE ) vertices <- data.frame( id = 1:6, title = paste( "node", 1:6 ), shape = "dot", size = 15, color = "lightblue" ) aristas <- espacio_muestral %>% slice_sample(n=5) colnames(aristas) <- c("from","to") visNetwork(vertices, aristas) ``` ] .panel2-custom-graph-1-5[
] <style> .panel1-custom-graph-1-5 { color: black; width: 49%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-custom-graph-1-5 { color: black; width: 49%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-custom-graph-1-5 { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> <style> #grafos-aleatorios { margin-bottom: 2%; } </style> --- ## DT <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutorial:<br> <https://rstudio.github.io/DT/> Listado de funciones:<br> <https://cran.r-project.org/web/packages/DT/DT.pdf> Extensiones extra:<br> <https://datatables.net/extensions/index> ```r install.packages('DT') library(DT) ``` ] .panel[.panel-name[Tabla básica] ```r datatable(iris, options = list(pageLength = 5)) ``` ] .panel[.panel-name[Tabla editable] ```r datatable(head(mtcars), editable = 'cell' # 'row', 'column' 'all' ) ``` ] .panel[.panel-name[Botones extra] ```r datatable(mtcars, editable = 'cell', extensions = "Buttons", options = list( dom="Bfrtip", # necesario para mostrar los botones buttons=c("copy","print","csv") ) ) ``` ] ] ??? Ejecutar aparte los códigos en **R**. --- ## threejs <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutorial:<br> <https://github.com/bwlewis/rthreejs> Listado de funciones:<br> <https://cran.r-project.org/web/packages/threejs/threejs.pdf> Ejemplos para **R**:<br> <https://bwlewis.github.io/rthreejs/> El verdadero potencial de **three.js**:<br> <https://threejs.org/examples/> ```r install.packages('threejs') library(threejs) ``` ] .panel[.panel-name[Grafo interactivo] ```r data(ego) # grafo social obtenido de Facebook graphjs(ego, bg="black") ```
] .panel[.panel-name[Proyección 2D a esfera] ```r # globejs(img = "ruta_local_de_alguna_imagen.png") globejs(img = xaringan:::karl) ```
] .panel[.panel-name[Gráfico sobre el globo terrestre] ```r library(maps) library(maptools) data(world.cities, package="maps") ciudades <- world.cities[order(world.cities$pop,decreasing=TRUE)[1:1000],] globejs(bg = "white", lat=ciudades$lat, # latitud long=ciudades$long, # longitud value = 100*(ciudades$pop/max(ciudades$pop)), # alturas para los valores rotationlat = -0.34, # Rotación latitudinal inicial (en radianes) del globo rotationlong =-0.38, # Rotación longitudinal inicial (en radianes) del globo fov = 30 # Campo de visión (field of view) inicial ) ``` ] ] --- ## rgl <p style="margin-bottom: -3%;"> </p> .panelset.sideways[ .panel[.panel-name[Configuración] Tutoriales:<br> - <https://cran.r-project.org/web/packages/rgl/vignettes/rgl.html> - <https://cran.r-project.org/web/packages/rgl/vignettes/WebGL.html> El segundo tutorial es de **gran** utilidad si poseen un nivel por lo menos básico de **JavaScript**. En caso no te funcione tras instalar el paquete:<br> <https://github.com/cran/rgl> Listado de funciones:<br> <https://cran.r-project.org/web/packages/rgl/rgl.pdf> ```r install.packages('rgl') library(rgl) # Suprimir la ventana aparte que contiene el gráfico "rgl", # para que se grafique dentro del documento html creado. options(rgl.useNULL = TRUE) ``` ] .panel[.panel-name[Ejemplo 1] ### Gráfico de dispersión ```r *close3d() *open3d() numero_puntos <- 12*25 x <- sort(rnorm(numero_puntos)) y <- rnorm(numero_puntos) z <- rnorm(numero_puntos) + atan2(x,y) points3d(x, y, z, col = rainbow(numero_puntos)) # lines3d(x, y, z, col = rainbow(numero_puntos)) # segments3d(x, y, z, col = rainbow(numero_puntos)) # triangles3d(x, y, z, col = rainbow(numero_puntos)) # quads3d(x, y, z, col = rainbow(numero_puntos)) *rglwidget() ``` ```r close3d() open3d() plot3d(x, y, z, col = rainbow(numero_puntos)) rglwidget() ``` ] .panel[.panel-name[Ejemplo 2] ### Customización gráfica ```r close3d() open3d() triangles3d(x, y, z, col = rainbow(numero_puntos)) axes3d(tick = TRUE, nticks = 10) # Añadir algunas propiedades al gráfico 3D decorate3d( main = "Título", box = TRUE, # Dibujar caja alrededor del gráfico expand = 1.25, # Cuánto expandir la caja (si se dibuja) respecto al gráfico aspect = c(0.5,1,1.5) # aspect ratio de los ejes ) bg3d("#92E3ED") # color de fondo rglwidget(elementId = "ejemplo-2") ``` ] .panel[.panel-name[Ejemplo 3] ### Superficies de revolución ```r close3d() open3d() x <- seq(from=1, to=5, by=0.5) y <- log(x) *wire3d(turn3d(x, y, n = 20, smooth = FALSE)) # shade3d(turn3d(x, y, n = 20, smooth = TRUE), col="green") # dot3d(turn3d(x, y, n = 20, smooth = FALSE), col="#EA42FF") rglwidget() ``` ```r close3d() open3d() shade3d(turn3d(x, y, n = 20, smooth = TRUE # Renderización gráfica más "suave" ), col="green" ) rglwidget() ``` ] .panel[.panel-name[Ejemplo 4] ### Animación de curva respecto al tiempo ```r close3d() open3d() ``` ``` ## null ## 5 ``` ```r library(manipulateWidget) # instalarla si es necesario tiempo <- 0:500 xyz <- data.frame( x = cos(tiempo/20), y = sin(tiempo/10), z = tiempo ) id_curva <- plot3d(xyz, type="l")["data"] # curva por trazar id_esfera <- spheres3d(xyz[1,], # este valor no importa, # se reemplaza al iniciar la animación radius = 8, # radio de la esfera graficada col = "purple" # color de la esfera graficada ) rglwidget(elementId = "curva-parametrizada") %>% playwidget(list( ageControl(births = tiempo, # Frames en los cuales la gráfica se actualizará ages = c( 0, # Al inicio del frame del frame actual 20, # Tras 20 frames del frame actual 50 # Tras 50 frames del frame actual ), colors = c( "green", # Color de vértice tras transcurrir 0 frames "red", # Color de vértice tras transcurrir 20 frames "blue" # Color de vértices tras transcurrir 100 frames ), objids = id_curva # Identificador que será actualizado via "colors", # en este caso, la curva graficada. ), ageControl(births = 0, # Actualizaciones iniciarán en el primer frame ages = tiempo, # Tras aquellas cantidad de frames (n-ésimo frame), vertices = xyz, # actualizar el gráfico con el n-ésimo vértice. objids = id_esfera) # Las actualizaciones serán para el # gráfico de una esfera (en posiciones distintas) ), start = 0, stop = max(tiempo), # cantidad de frames por considerar en la animación rate = 50, # cantidad de frames por segundo components = c("Reverse", "Play", "Slower", "Faster","Reset", "Slider", "Label"), loop = TRUE # Repetir la animación cuando concluya. ) ```
] .panel[.panel-name[Ejemplo 5] ### Combinando rgl y JavaScript ```js ////// Código de JavaScript ////// rgl = document.getElementById('curva-parametrizada').rglinstance; rglObject = rgl.getObj(rgl.subsceneid); //// Ejemplo particular: Rotaciones //// angulo = 10; // Una rotación respecto al eje X rglObject.par3d.userMatrix.rotate(angulo, 0, 1, 0); rgl.drawScene(); // Una rotación respecto al eje Y rglObject.par3d.userMatrix.rotate(angulo, 1, 0, 0); rgl.drawScene(); // Iniciar rotación constante respecto al eje X let rotaX = setInterval( function () { rglObject.par3d.userMatrix.rotate(angulo, 0, 1, 0); rgl.drawScene(); } , 200); // Iniciar rotación constante respecto al eje Y let rotaY = setInterval( function () { rglObject.par3d.userMatrix.rotate(angulo, 1, 0, 0); rgl.drawScene(); } , 200); // Detener alguna rotación clearInterval(rotaX); clearInterval(rotaY); ``` ] ] ??? Para el ejemplo 5: Alterar los siguientes valores asociados al gráfico:<br> - Ejemplo raro probablemente sin mucha utilidad - `rgl.colLoc = 0` 1, 2 o 3 (mismo resultado que 3 para valores >=3) - `rgl.drawScene()` - Cambiar color de los valores en los ejes - `rgl.canvas.style.backgroundColor = "blue"` - Modificar tamaño de la caja contenedora: - `rglObject.par3d.bbox[some_index] = some_number` - `rgl.drawScene()` - Alterar el nivel de zoom - `rglObject.par3d.FOV = 10` - `rglObject.par3d.zoom = 0.5` - Cambiar las escalas de los ejes - `rglObject.par3d.scale` - Para proyectar el gráfico sobre el eje XY:<br> `rglObject.par3d.scale[2]=0`<br> Requiere después hacer click en la figura para proyectarse. - Proyección (creo) respecto a los planos de R^3 - XY: `rglObject.par3d.userMatrix.scale(0,1,1)` - XZ: `rglObject.par3d.userMatrix.scale(1,1,0)` - Rotación - `rglObject.par3d.userMatrix.rotate(angulo_en_grados,x,y,z)` --- ## Referencias - <http://www.htmlwidgets.org/> - <https://rstudio.github.io/leaflet/> - <https://rstudio.github.io/dygraphs/> - <https://plotly.com/r/> - <https://datastorm-open.github.io/visNetwork/> - <https://rstudio.github.io/DT/> - <https://github.com/bwlewis/rthreejs> - <https://cran.r-project.org/web/packages/rgl/vignettes/rgl.html>