Kapitola 7 Interaktívna vizualizácia
Vrátime sa ku vizualizácii. Videli sme, že balík ggplot2 produkuje elegantnú grafiku, ktorou môžeme bez hanby prezentovať svoje analýzy. Využiteľnosť grafickej informácie sa však za určitých okolností dá ešte zvýšiť – a to interaktivitou. Tým rozumieme napr. zväčšenie časti grafu (zoom), vyvolanie bublinovej nápovedy (tooltip) nájazdom kurzora, alebo voľbu zobrazených premenných pomocou zaškrtávacieho zoznamu (checklist) či voľbu rozsahu pomocou posuvníkov (slider).
Inšpiráciou tejto kapitoly je veľké množstvo aplikácií interaktívnej grafiky na internete – počnúc galériou https://www.r-graph-gallery.com/interactive-charts.html.
Praktický úvod a návod ku nástrojom htmlwidgets a shiny poskytuje napr. príspevok (Engel 2019, kap. 2).
Pochopiteľne, zobrazenie interaktívnych grafov je v statickom dokumente (typu HTML a obzvlášť PDF) veľmi obmedzené. Preto je na čitateľovi tejto učebnice, aby si nasledujúce príklady sám vyskúšal.
7.1 ggvis
Jedným z ideových nasledovníkov balíku ggplot2 a celkovo gramatických pravidiel grafiky je balík ggvis (Chang a Wickham 2020). V skladaní komponentov ide ešte ďalej, integruje reťazenie príkazov (pipe) a pridáva napr. aj interaktívne prvky. Celý koncept je však zatiaľ skôr hudbou budúcnosti, pretože ďalší vývoj balíka je dočasne pozastavený v prospech dolaďovania súčasných projektov z ekosystému tidyverse.
Nasledujúci kód – pre začiatok – zobrazí jednoduchý bodový graf bez interaktívnych prvkov:
library(ggvis)
%>%
mtcars ggvis(x = ~disp, y = ~mpg) %>% # definuje úlohy
::mutate(disp = disp / 61.0237) %>% # konvertuje objem valcov na litre
dplyrlayer_points() # pridá geometrickú vrstvu (body)
Ďalší už pre nastavenie histogramu (šírky intervalu) pridá posuvník (slider):
%>%
mtcars ggvis(~wt) %>%
layer_histograms(width = input_slider(0, 2, step = 0.10, label = "width"))
detach("package:ggvis", unload = TRUE)
Okrem interaktívneho elementu input_slider sa núkajú aj input_checkbox, input_checkboxgroup, input_numeric, input_radiobuttons, input_select a input_text, ale napr. aj add_tooltip.
Podrobné návody sa dajú nájsť napr. na stránkach:
https://ggvis.rstudio.com/ggvis-basics.html
https://towardsdatascience.com/a-short-introduction-to-ggvis-52a4c104df71
7.2 htmlwidgets
JavaScript je pravdepodobne najviac využívaný skriptovací jazyk na tvorbu interaktívnych webstránok. Balík htmlwidgets poskytuje framework na prepojenie R s rôznymi interaktívnymi JavaScript-ovými knižnicami.11 Takto vytvorené interaktívne komponenty (widgety) sa dajú:
- využiť v príkazovom riadku R podobne ako tradičné grafy (v RStudiu cez Viewer),
- zakomponovať do R Markdown dokumentov a Shiny web aplikácií,
- uložiť ako samostatné webové stránky na jednoduché zdielanie cez email, cloudové úložiská a pod.
7.2.1 plotly
Jedným z najužitočnejších balíkov v tejto triede je plotly, pretože na interaktívny dokáže premeniť akýkoľvek graf ggplot. Pohrajte sa s aktívnymi prvkami grafu, napríklad vypínanie/zapínanie vrstiev, zoomovanie atď.:
library(ggplot2)
<- ggplot(data = mpg, mapping = aes(x = displ, y = cty, color = drv)) +
p geom_point()
detach("package:ggplot2")
library(plotly)
ggplotly(p)
Balík má však aj svoje vlastné vysokoúrovňové funkcie, napríklad
plot_ly(data = ggplot2::mpg, x = ~displ, y = ~cty, color = ~drv,
type = "scatter", mode = "markers") %>%
layout(legend = list(title = list(text = '<b> drv </b>')))
ktoré zvládnu aj 3D (vrátane možnosti rotácie):
plot_ly(data = ggplot2::mpg, x = ~displ, y = ~cty, z = ~cyl, color = ~drv,
type = "scatter3d", mode = "markers")
detach("package:plotly", unload = TRUE)
Typ a mód grafu dokáže funkcia plot_ly uhádnuť aj sama, ale zobrazuje o tom hlásenia.
Paleta grafov (a ich nastavení) v plotly je enormná – od základných a štatistických grafov, cez špecificky vedecké, finančnícke, geografické mapy až po 3D (body, povrch, vrstevnice). Pre podrobný prehľad odporúčame pozrieť stránku https://plotly.com/r/.
7.2.2 Iné
Na stránke https://www.htmlwidgets.org v sekcii Showcase nájdeme výber z rozsiahlej triedy htmlwidgets, rozsiahlejší zoznam opäť v Galérii http://gallery.htmlwidgets.org/. Mnohé z nich sa spomínajú aj v časti Interactive charts na stránke https://www.r-graph-gallery.com/interactive-charts.html. Pre nás neskôr môžu byť užitočné napr. nasledujúce:
::dygraph(nhtemp, main = "New Haven Temperatures") %>%
dygraphs::dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01")) dygraphs
::leaflet() %>%
leaflet::addTiles() %>% # defaultné OpenStreetMap mapové diely
leaflet::addMarkers(lng=17.11526, lat=48.15198, popup="Stavebná fakulta STU") leaflet
Výnimkou medzi grafmi, no iste užitočnou, je interaktívna tabuľka:
::datatable(mtcars, options = list(pageLength = 5)) DT
Otázka užitočnosti je však subjektívna, využiteľnosť si každý určí sám. Mnohé z grafov a widgetov sa môžu zísť vo výučbe, výskume i komerčných projektoch.
7.3 shiny
Widgety htmlwidgets sú mocným nástrojom a dajú sa ľahko zakomponovať do samostatných dokumentov. Ak však treba väčšiu flexibilitu a prispôsobiteľnosť užívateľským vstupom, vtedy je balík shiny (Chang et al. 2020) rozumnejšou voľbou. Jeho nevýhodou je to, že kód sa už dokáže vykonať iba v samotnom internetovom prehliadači, ale je naň potrebný beh vlastného servera.
Použitie ilustrujeme pomocou datasetu mpg na príklade grafu závislosti zdvihového objemu disp a dojazdu mimo mesta hwy s odlíšením roku výroby modelu year pomocou priehľadnosti a druhu paliva fl 12 farebne (a názvom modelu namiesto bodu). Graf by bol pre všetkých 234 modelov áut neprehľadný, preto predpokladajme, že nás v jednom momente zaujímajú dáta iba jedného konkrétneho výrobcu manufacturer. Statický graf pomocou ggplot2 dostaneme nasledovne:
library(ggplot2)
%>%
mpg ::filter(manufacturer == "chevrolet") %>%
dplyrggplot(aes(x = displ, y = hwy, alpha = year, color = fl)) +
geom_text(aes(label = model), position="jitter") +
scale_alpha(range = c(0.4, 1))
Poloha je pre časté prekrytia zámerne trochu rozochvená (jitter) a spodná hranica priehľadnosti je pre dobrú viditeľnosť zvýšená. Ak by sme chceli zobraziť takéto grafy pre všetkých výrobcov, pomocou fazetovania by vzniklo 15 subgrafov. Nechajme radšej užívateľa, nech si výrobcu vyberie priamo z rolovacieho menu pri grafe:
library(shiny)
# Užívateľské prostredie:
<- fluidPage( # použi fluid Bootstrap layout
ui # nadpis stránky
titlePanel("Mileage per galon related to displacement"),
# vytvor riadok s bočným panelom
sidebarLayout(
# definuj bočný panel s jedným vstupom
sidebarPanel(
selectInput("manuf", "Manufacturer:",
choices=unique(mpg$manufacturer)),
hr(), # horizontal rule
helpText("Data from ggplot2.")
),# vytvor miesto pre graf
mainPanel(
plotOutput("mileagePlot")
)
)
)# Server:
<- function(input, output) { # definuj server pre Shiny app
server # zaplň miesto vytvorené pre graf
$mileagePlot <- renderPlot({
output%>%
mpg ::filter(manufacturer == input$manuf) %>%
dplyrggplot(aes(x = displ, y = hwy, alpha = year, color = fl)) +
geom_text(aes(label = model), position="jitter") +
scale_alpha(range = c(0.4, 1)) +
# aby nedochádzalo k zmene mierky pre rôzny subset údajov:
scale_x_continuous(limits = range(mpg$displ)) +
scale_y_continuous(limits = range(mpg$hwy))
})
}# Skombinovanie frontend-u a backendu-u.
shinyApp(ui, server)
Aplikácia vytvorí server, v ktorom beží jedna inštancia R-ka a výsledok zobrazí v záložke Viewer alebo v externom internetovom prehliadači.
Ak chceme svoju interaktívnu shiny aplikáciu poskytnúť iným ľuďom, ktorí nemajú Rko nainštalované, alebo ho nevedia obsluhovať, mǒžeme vytvoriť server prístupný pod verejnou IP adresou. Alebo použiť službu, ktorá to urobí za nás. Jednou z takých je https://www.shinyapps.io. Stačí sa zaregistrovať a po prihlásení nasledovať jednoduchý postup, ako načítať shiny aplikáciu na server. Účet zadarmo má obmedzenie na 5 aplikácií, ktoré môžu bežať najviac 25 hodín/mesiac. Podrobná dokumentácia služby shinyapps.io sa nachádza na stránke https://docs.rstudio.com/shinyapps.io/.
Horeuvedenú aplikáciu sa dá vyskúšať na adrese https://bacigal.shinyapps.io/shinyapp/. Aby sme ju mohli uploadnuť, uložili sme R script do osobitného súboru app.R v adresári shinyapp. Pochopiteľne, názvy sa dajú zvoliť. Potom sme nainštaloval balík rsconnect, nakonfigurovali ho poskytnutím tokenu a hesla (z účtu na shinyapps.io), načítali balík a nahrali aplikáciu na server (treba mať už správne nastavený pracovný adresár pomocou setwd):
install.packages('rsconnect')
::setAccountInfo(name='bacigal',
rsconnecttoken='.................................',
secret='.........................................')
::deployApp('shinyapp/') rsconnect
V účte sme nastavili parameter timeout, po ktorom sa aplikácia po poslednom použití uspí, na 5 min (štandardne je nastavené 15 min), aby sa 25-hodinový limit míňal čo najpomalšie.
Viac o tvorbe Shiny aplikácií sa píše v oficiálnej dokumentácii na stránke https://shiny.rstudio.com/, detailnejšie v publikácii (Wickham 2020).
7.4 Interaktívna podpora tvorby grafov ggplot
Interaktivita sa dá využiť aj na tvorbu statických grafov. Dobrým príkladom je balík ggraptR (Dubossarsky a Song 2020), ktorý začiatočníkom veľmi výrazne uľahčuje tvorbu základných grafov (scatter, line, path, density 2D, bin 2D, hex) možnosťou nastavenia komponentov aesthetic, theme, facet a aggregation. Výsledný graf sa dá exportovať ako obrázok alebo zdrojový script v R. Rovnako sa dajú tvoriť tabuľky súhrnov (napr. priemer podľa skupín), tie žiaľ už nejde exportovať. Nasledujúcim príkazom sa spustí lokálny server a otvorí nové okno vo webovom prehliadači:
::ggraptR() ggraptR
Štandardne sa pri spustení načíta dataset diamonds, no nie je problém načítať akýkoľvek iný dátový rámec. Pre stručný návod pozri vignette v nápovede R.
Alternatívou ku ggraptR je prídavný modul (tzv. add-in) do RStudia, balík esquisse, ktorý sa po inštalácii spustí buď z ponuky [Addins] alebo príkazom (aj s konkrétnym datasetom):
::esquisser(iris) esquisse
7.5 Cvičenie
Pomocná nápoveda ku riešeniu je uvedená v zátvorke na konci úloh.
Prvý príklad v kapitole o ggvis študijného materiálu upravte tak, aby sa body závislosti dojazdu od zdvihového objemu zafarbili p odľa diskrétnej premennej, ktorú si používateľ interaktívne zvolí v rolovacom menu. Diskrétne premenné v mtcars predtým konvertujte na faktor. (input_select,
map=as.name
)Predošlý príklad implementujte pomocou ggplot ako aplikáciu Shiny: vľavo nech je rolovacie menu, vpravo graf a pod ním tabuľka priemerov oboch premenných v jednotlivých skupinách (interaktívne zvolenej) diskrétnej premennej. (funkcie selectInput, plotOutput, tableOutput, aes_string, group_by + summarize, across)
Poskytnite aplikáciu z predošlého príkladu online (formou odkazu, napr. pomocou služby www.shinyapps.io). Ak sa vám predošlý príklad nepodarilo urobiť, poskytnite jednoduchú aplikáciu na výpočet mocniny čísla zadaného z textového poľa, alebo niečo iné – originálne, vaše.
Pomocou ggplot2 a plotly v interaktívnom bodovom grafe zobrazte závislosť dojazdu od zdvihového objemu s farebným odlíšením počtu valcov tak, aby tooltip obsahoval iba informáciu o modeli auta a súradniciach bodu. Vedeli by ste text tooltip-u formátovať tak, aby bol model auta prvý a hodnoty parametrov auta boli uvedené aj s jednotkami? (argument tooltip, aes text)
Zobrazte príklad takého htmlwidget-u (zo všetkých dostupných, ale nespomínaných v tejto kapitole), ktorý je pre vás zaujímavý a užitočný (vysvetlite prečo).