Skip to content

Commit

Permalink
Fix shiny chapter heading levels. Add delta map app.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbjones committed Oct 21, 2023
1 parent 6af9c53 commit 5b2dcd7
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 21 deletions.
1 change: 1 addition & 0 deletions materials/DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Imports:
forcats,
foreach,
ggplot2,
ggExtra,
ggforce,
ggmap,
ggpmisc,
Expand Down
40 changes: 20 additions & 20 deletions materials/sections/visualization-shiny.qmd
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
### Learning Objectives
## Learning Objectives
In this lesson we will:

- review the capabilities in Shiny applications
- learn about the basic layout for Shiny interfaces
- learn about the server component for Shiny applications
- build a simple shiny application for interactive plotting

### Overview
## Overview

[Shiny](http://shiny.rstudio.com/) is an R package for creating interactive data visualizations embedded in a web application that you and your colleagues can view with just a web browser. Shiny apps are relatively easy to construct, and provide interactive features for letting others share and explore data and analyses.

Expand All @@ -26,7 +26,7 @@ While that is the best citation and archival location of the dataset, using Shin

We're going to create a simple shiny app with two sliders so we can interactively control inputs to an R function. These sliders will allow us to interactively control a plot.

### Create a sample shiny application
## Create a sample shiny application

- File > New > Shiny Web App...
- Set some fields:
Expand All @@ -45,7 +45,7 @@ the number of bins in the plot.

Note that you can drag the slider to change the number of bins in the histogram.

### Shiny architecture
## Shiny architecture

A Shiny application consists of two functions, the `ui` and the `server`. The `ui`
function is responsible for drawing the web page, while the `server` is responsible
Expand All @@ -62,11 +62,11 @@ else on the Internet (e.g., if the application is deployed to a web server).
![](images/shiny-architecture.png)


### Interactive scatterplots
## Interactive scatterplots

Let's modify this application to plot Yolo bypass secchi disk data in a time-series, and allow aspects of the plot to be interactively changed.

#### Load data for the example
### Load data for the example

Use this code to load the data at the top of your `app.R` script. Note we are using `contentId` again, and we have filtered
for some species of interest.
Expand All @@ -90,7 +90,7 @@ names(delta_data)
```

#### Add a simple timeseries using ggplot
### Add a simple timeseries using ggplot

We know there has been a lot of variation through time in the delta, so let's plot a time-series of Secchi depth. We do so by switching out the histogram code for a simple ggplot, like so:

Expand All @@ -113,7 +113,7 @@ In a Shiny application, the `server` function provides the part of the applicati
that creates our interactive components, and returns them to the user interface (`ui`)
to be displayed on the page.

#### Add sliders to set the start and end date for the X axis
### Add sliders to set the start and end date for the X axis

To make the plot interactive, first we need to modify our user interface to include
widgits that we'll use to control the plot. Specifically, we will add a new slider
Expand All @@ -139,7 +139,7 @@ sidebarPanel(
If you reload the app, you'll see two new sliders, but if you change them, they don't
make any changes to the plot. Let's fix that.

#### Connect the slider values to the plot
### Connect the slider values to the plot

Finally, to make the plot interactive, we can use the `input` and `output` variables
that are passed into the `server` function to access the current values of the sliders.
Expand All @@ -160,7 +160,7 @@ min and max of the Depth axis.

Looks so shiny!

#### Reversed Axes?
### Reversed Axes?

What happens if a clever user sets the minimum for the X axis at a greater value than the maximum?
You'll see that the direction of the X axis becomes reversed, and the plotted points display right
Expand Down Expand Up @@ -193,7 +193,7 @@ second is the max value on the slider.
![](images/shiny-yolo-2.png)


### Extending the user interface with dynamic plots
## Extending the user interface with dynamic plots

If you want to display more than one plot in your application, and provide
a different set of controls for each plot, the current layout would be too simple.
Expand All @@ -205,7 +205,7 @@ a `sidebarLayout`, which is divided horizontally into a `sidebarPanel` and a

![](images/shiny-layout-1.png)

#### Vertical layout
### Vertical layout

To extend the layout, we will first nest the existing `sidebarLayout` in a new
`verticalLayout`, which simply flows components down the page vertically. Then
Expand Down Expand Up @@ -272,7 +272,7 @@ cols <- names(delta_data)
```


#### Add the dynamic plot
### Add the dynamic plot

Because we named the second plot `varPlot` in our UI section, we now need to modify
the server to produce this plot. Its very similar to the first plot, but this time
Expand All @@ -291,7 +291,7 @@ strings, and so would not be recognized as symbols in the `aes` mapping in ggplo
```


### Finishing touches: data citation
## Finishing touches: data citation

Citing the data that we used for this application is the right thing to do, and easy.
You can add arbitrary HTML to the layout using utility functions in the `tags` list.
Expand All @@ -315,7 +315,7 @@ configurable scatterplot in three distinct panels.

![](images/shiny-yolo-app.png)

### Publishing Shiny applications
## Publishing Shiny applications

Once you've finished your app, you'll want to share it with others. To do so, you need to
publish it to a server that is set up to [handle Shiny apps](https://shiny.rstudio.com/deploy/).
Expand All @@ -335,7 +335,7 @@ Your main choices are:

A comparison of [publishing features](https://rstudio.com/products/shiny/shiny-server/) is available from RStudio.

#### Publishing to shinyapps.io
### Publishing to shinyapps.io

The easiest path is to create an account on shinyapps.io, and then configure RStudio to
use that account for publishing. Instructions for enabling your local RStudio to publish
Expand All @@ -348,7 +348,7 @@ application window in RStudio, and your app will be live before you know it!

![](images/shiny-publish.png)

### Summary
## Summary

Shiny is a fantastic way to quickly and efficiently provide data exploration for your
data and code. We highly recommend it for its interactivity, but an archival-quality
Expand All @@ -358,7 +358,7 @@ in our Shiny app, which offers both the preservation guarantees of an archive, p
the interactive data exploration from Shiny. You can utilize the full power of R and
the tidyverse for writing your interactive applications.

### Full source code for the final application
## Full source code for the final application

```{r shinyapp_source, eval=FALSE}
Expand Down Expand Up @@ -458,7 +458,7 @@ shinyApp(ui = ui, server = server)
```


### A shinier app with tabs and a map!
## A shinier app with tabs and a map!

```{r, eval = F}
library(shiny)
Expand Down Expand Up @@ -601,7 +601,7 @@ shinyApp(ui = ui, server = server)
```


### Resources
## Resources

- [Main Shiny site](http://shiny.rstudio.com/)
- [Official Shiny Tutorial](http://shiny.rstudio.com/tutorial/)
1 change: 0 additions & 1 deletion materials/session_05.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ title-block-banner: true
---

{{< include /sections/visualization-shiny.qmd >}}

136 changes: 136 additions & 0 deletions materials/shiny-demo/delta-map-app.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
library(shiny)
library(contentid)
library(dplyr)
library(tidyr)
library(ggplot2)
library(lubridate)
library(shinythemes)
library(sf)
library(leaflet)
library(snakecase)

# read in the data from EDI
sha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'
delta.file <- contentid::resolve(sha1, registries=c("dataone"), store = TRUE)

# fix the sample date format, and filter for species of interest
delta_data <- read.csv(delta.file) %>%
mutate(SampleDate = mdy(SampleDate)) %>%
filter(grepl("Salmon|Striped Bass|Smelt|Sturgeon", CommonName)) %>%
rename(DissolvedOxygen = DO,
Ph = pH,
SpecificConductivity = SpCnd)

cols <- names(delta_data)

sites <- delta_data %>%
distinct(StationCode, Latitude, Longitude) %>%
drop_na() %>%
st_as_sf(coords = c('Longitude','Latitude'), crs = 4269, remove = FALSE)



# Define UI for application
ui <- fluidPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
HTML('<a style="text-decoration:none;cursor:default;color:#FFFFFF;" class="active" href="#">Sacramento River Floodplain Data</a>'), id="nav",
windowTitle = "Sacramento River floodplain fish and water quality data",

tabPanel("Data Sources",
verticalLayout(
# Application title and data source
titlePanel("Sacramento River floodplain fish and water quality data"),
p("Data for this application are from: "),
tags$ul(
tags$li("Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.",
tags$a("doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f", href="http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f")
)
),
tags$br(),
tags$hr(),
p("Map of sampling locations"),
mainPanel(leafletOutput("map"))
)
),

tabPanel(
"Explore",
verticalLayout(
mainPanel(
plotOutput("distPlot"),
width = 12,
absolutePanel(id = "controls",
class = "panel panel-default",
top = 175, left = 75, width = 300, fixed=TRUE,
draggable = TRUE, height = "auto",
sliderInput("date",
"Date:",
min = as.Date("1998-01-01"),
max = as.Date("2020-01-01"),
value = c(as.Date("1998-01-01"), as.Date("2020-01-01")))
)
),

tags$hr(),

sidebarLayout(
sidebarPanel(
selectInput("x_variable", "X Variable", cols, selected = "SampleDate"),
selectInput("y_variable", "Y Variable", cols, selected = "Count"),
selectInput("color_variable", "Color", cols, selected = "CommonName")
),

# Show a plot with configurable axes
mainPanel(
plotOutput("varPlot")
)
),
tags$hr()
)
)
)
)

# Define server logic required to draw the two plots
server <- function(input, output) {


output$map <- renderLeaflet({leaflet(sites) %>%
addTiles() %>%
addCircleMarkers(data = sites,
lat = ~Latitude,
lng = ~Longitude,
radius = 10, # arbitrary scaling
fillColor = "gray",
fillOpacity = 1,
weight = 0.25,
color = "black",
label = ~StationCode)
})

# turbidity plot
output$distPlot <- renderPlot({

ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
geom_point(colour="red", size=4) +
xlim(c(input$date[1],input$date[2])) +
labs(x = "Sample Date", y = "Secchi Depth (m)") +
theme_light()
})

# mix and match plot
output$varPlot <- renderPlot({
ggplot(delta_data, mapping = aes(x = .data[[input$x_variable]],
y = .data[[input$y_variable]],
color = .data[[input$color_variable]])) +
labs(x = to_any_case(input$x_variable, case = "title"),
y = to_any_case(input$y_variable, case = "title"),
color = to_any_case(input$color_variable, case = "title")) +
geom_point(size=4) +
theme_light()
})
}


# Run the application
shinyApp(ui = ui, server = server)

0 comments on commit 5b2dcd7

Please sign in to comment.