Related
I am in the process of learning R and am having some issues. I am trying to add a tab to my app to calculate a few values based on the data I put in. I have a frame of locations and I have some math I did to calculate the values of interest.
I want to take the value called loft and put a string on the panel that says "Loft at Impact is: XXX" with what number is calculated. The data files have several pages in excel I want to shuffle through. Currently it all works except the values I am trying to calculate. It works as expected in a regular R script but I am struggling getting it into R Shiny. I don't think I understand how to manipulate and deal with reactive data and such. Here is my current code:
#Import needed libraries
library(shiny)
library(readxl)
library(plotly)
library(DT)
#start app
runApp(
list(
ui = fluidPage(
#Main Title
titlePanel("Putt Viewer"),
sidebarLayout(
#File input on sidebar
sidebarPanel(
fileInput('file1', ' .xlsx file',
accept = c(".xlsx")
),
#Shot selection
numericInput('shotSelect','Which Shot Would you like to see?', 1, 1)
),
mainPanel(
#Sets up different panels for the main screen
tabsetPanel(
tabPanel("3D View", plotlyOutput("putterPlot2"),
helpText("3D Rendering of data points.")),
tabPanel("Overhead View", plotlyOutput("putterPlot"),
helpText("Overhead view of the toe and heel fiducial markers.")),
tabPanel("View Raw Data", dataTableOutput("contents"),
helpText("Explore the generated data in a table.")),
tabPanel("Face at Launch", textOutput("contents2"))
)
)
),
),
#starts and runs the server functions
server = function(input, output){
data <- reactive({
req(input$file1)
inFile <- input$file1
data <- read_excel(inFile$datapath, input$shotSelect + 1)
})
impactFrame <- data[nrow(shotData)-1,]
launchPoints <- structure(list(X = c(impactFrame$TToe.x_mm,impactFrame$MToe.x_mm, impactFrame$Heel.x_mm, 0),
Y = c(impactFrame$TToe.y_mm,impactFrame$MToe.y_mm, impactFrame$Heel.y_mm, 0),
Z = c(impactFrame$TToe.z_mm,impactFrame$MToe.z_mm, impactFrame$Heel.z_mm, 0)),
.Names = c("X", "Y", "Z"), row.names = c(NA, 3L), class = "data.frame")
ABi = launchPoints[1,2] - launchPoints[1,1] #x2-x1
ABj = launchPoints[2,2] - launchPoints[2,1] #y2-y1
ABk = launchPoints[3,2] - launchPoints[3,1] #z2-z1
ACi = launchPoints[1,3] - launchPoints[1,1] #x3-x1
ACj = launchPoints[2,3] - launchPoints[2,1] #y3-y1
ACk = launchPoints[3,3] - launchPoints[3,1] #z3-z1
AB = c(ABi, ABj, ABk)
AC = c(ACi, ACj, ACk)
normalijk = cross(AB,AC) #face vector
midABi = ABi / 2 + launchPoints[1,1]
midABj = ABj / 2 + launchPoints[2,1]
midABk = ABk / 2 + launchPoints[3,1]
midABCi = launchPoints[3,1] - midABi
midABCj = launchPoints[3,2] - midABj
midABCk = launchPoints[3,3] - midABk
liePlane = c(midABCi, midABCj, midABCk) #lie plane
loft <- reactiveValues(atan(normalijk[3] / sqrt(normalijk[1] ^ 2 + normalijk[2] ^ 2))) #loft
faceAngle = atan(normalijk[2] / sqrt(normalijk[1] ^ 2 + normalijk[2] ^ 2)) # face angle
lie = atan(liePlane[3] / sqrt(liePlane[1] ^ 2 + liePlane[2] ^ 2))
})
output$contents2 <- renderText(loft)
#Tab 3 output of the data
output$contents <- DT::renderDataTable({
#makes sure there is a file and its correct
req(input$file1)
inFile <- input$file1
data = read_excel(inFile$datapath, input$shotSelect + 1)
data
})
output$putterPlot2 <- renderPlotly({
#makes sure there is a file and its correct
req(input$file1)
inFile <- input$file1
data = read_excel(inFile$datapath, input$shotSelect + 1)
plot_ly(data, x = ~TToe.x_mm, y = ~TToe.y_mm, z = ~TToe.z_mm, type="scatter3d", name = "TToe Fiducials", mode="markers", color = ~Timestamp_ms) %>%
add_trace(x = ~MToe.x_mm, y = ~MToe.y_mm, z = ~MToe.z_mm, type="scatter3d", name = "TToe Fiducials", mode="markers", color = ~Timestamp_ms) %>%
add_trace(x = ~Heel.x_mm, y = ~Heel.y_mm + 3, z = ~Heel.z_mm - 25, type="scatter3d", name = "Heel Fiducials", mode="markers", color = ~Timestamp_ms) %>%
layout(title = 'Putter Face Location Data',
scene = list(xaxis = list(title = 'X (mm)', range = c(-200,200), ticktype = "array"),
yaxis = list(title = 'Y (mm)', range = c(-100,100), ticktype = "array"),
zaxis = list(title = 'Z (mm)', range = c(-100,100), ticktype = "array"),
showlegend = FALSE))
})
output$putterPlot <- renderPlotly({
req(input$file1)
inFile <- input$file1
data = read_excel(inFile$datapath, input$shotSelect + 1)
plot_ly(data, x = ~TToe.x_mm, y = ~TToe.y_mm, type="scatter", name = "Toe Data", mode="markers") %>%
add_trace( x = ~MToe.x_mm, y = ~MToe.y_mm, name = 'Toe Regression Fit', mode = 'lines', alpha = 1) %>%
add_trace(x = ~Heel.x_mm, y = ~Heel.y_mm + 3, type="scatter", name = "Heel Data", mode="markers") %>%
add_trace( x = ~Heel.x_mm, y = ~Heel.y_mm, name = 'Heel Regression Fit', mode = 'lines', alpha = 1) %>%
layout(title = 'Top Down View of Toe and Heel',
scene = list(xaxis = list(title = 'X (mm)', range = c(-200,200), ticktype = "array"),
yaxis = list(title = 'Y (mm)', range = c(-100,100), ticktype = "array"),
showlegend = FALSE))
})
}
)
)
My drilldown was working, then I added urls for the user to be linked out when they click on each segment. Here is the reproducible example (I had to comment out the urls as that causes an error). It seems that having a tibble dataframe as the main dataframe the pie chart is using is the only way to have a drilldown capability, but tibble doesn't accept a url column.
library(shiny)
library(DBI)
library(sparklyr)
library(readr)
library(data.table)
library(dplyr)
library(shinyWidgets)
library(DT)
library(highcharter)
library(httr)
library(purrr)
ui <- fluidPage(
fluidRow(
div(style="display: inline-block;vertical-align:top;padding-left: 35%",
highchartOutput("hccontainer_donutchart", height = "475px", width = "475px"))
),
)
server <- function(input, output) {
click_js <- JS("function(event) {Shiny.onInputChange('pieclick',event.point.name);}")
drilldown1_dat <- data.frame(
name = c("Talent", "Quality", "Safety"),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# ),
value = c(25, 25, 25)
)
drilldown1_piecolors <- c("#4169e1", "#4169e1", "#4169e1")
drilldown2_dat <- data.frame(
name = c("Base", "Energy", "Facilities"),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# ),
value = c(20, 20, 20)
)
drilldown2_piecolors <- c("#4169e1", "#4169e1", "#4169e1")
drilldown1_parsed <- list_parse2(drilldown1_dat)
drilldown2_parsed <- list_parse2(drilldown2_dat)
df <- tibble(
name = c("Allies", "Log", "Financials", "People", "Digital", "Operational", "Modernization", "Infrastructure"),
y = c(12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# ),
drilldown = name
)
df_piecolors <- c("#929292", "#929292", "#929292", "#4169e1", "#929292", "#929292", "#929292", "#4169e1")
# DONUT DRILLDOWN FUNCTION
donut_drilldown <- function(donut_data, piecolors, donut_title, hc_name) {
hc_name <- renderHighchart({
highchart() %>%
hc_plotOptions(
series = list(
cursor = "pointer",
point = list(
events = list(
click = JS( "function () { location.href = window.open(this.options.key, '_blank').foucs(); }")
)
)
)
) %>%
hc_tooltip(enabled = FALSE) %>%
hc_chart(type = "pie") %>%
hc_colors(piecolors) %>%
hc_title(
verticalAlign = 'middle',
text = donut_title,
#marginTop = -50,
floating = TRUE,
style = list(fontWeight='bold', fontSize='12px')
) %>%
hc_add_series(
data = donut_data, type = "pie", innerSize='30%', size='100%',
mapping = hcaes(name = name, y = y),
name = "DAF Focus Areas",
colorByPoint = TRUE,
dataLabels = list(enabled = TRUE,
distance = -55,
color = 'white',
crop = FALSE)
) %>%
hc_drilldown(
allowPointDrilldown = TRUE,
series = list(
list(
id = "People",
type = "pie",
innerSize = '30%', size = '100%',
data = drilldown1_parsed,
dataLabels = list(enabled = TRUE,
distance = -52,
crop = FALSE)
),
list(
id = "Infrastructure",
type = "pie",
innerSize = '30%', size = '100%',
data = drilldown2_parsed,
#mapping = hcaes(name = name, y = value, key = url),
dataLabels = list(enabled = TRUE,
distance = -52,
crop = FALSE)
)
)
) %>%
hc_chart(type = "pie", events = list(
load = JS("function() {console.log(this)}"),
drilldown = JS("function(e) {this.update({title: {text: e.seriesOptions.id}})}"),
drillup = JS("function() {this.update({title: {text: 'Main Donut' }})}")
)) %>%
hc_plotOptions(series = list(events = list(click = click_js)))
})
}
output$clicked <- renderText({
input$pieclick
})
output$hccontainer_donutchart = donut_drilldown(df, df_piecolors, "Donut", "hccontainer_donutchart")
}
# Run the application
shinyApp(ui = ui, server = server)
This is my code. I am trying to create an interactive webapp where the user can add new data by drawing polygons and then the
I don't understand the error it returns when trying to click 'Run App' in RSTudio or deploy the app to shinyapps (as it works locally when I just run the code). Does someone have an idea why it doesn't work when running or deploying?
## install required packages (if not installed yet)
require(class)
require(dplyr)
require(leafem)
require(leaflet)
require(leaflet.extras)
require(raster)
require(rgdal)
require(rsconnect)
require(sf)
require(sp)
require(shiny)
#### 0. Import Data ####
## import landfills clusters spatial data (point data)
landfills_clusters <- readOGR("plasticleakagewebapp/data/landfill_clusters.gpkg")
landfills_clusters_sf <- st_read('plasticleakagewebapp/data/landfill_clusters.gpkg')
### import landfill polygons
landfills_polygons <- readOGR("plasticleakagewebapp/data/landfills/OpenLandfills_Vietnam.shp", use_iconv = T, encoding = "UTF-8")
## import shapefile of vietnam
vietnam <- readOGR("plasticleakagewebapp/data/vietnam/vietnam.shp")
#### 1. Interactive Map (Leaflet) ####
## plot map with landfills colored by cluster
# e.g. plot water distance < 500m in red
# create color palette
cof <- colorFactor(c("green","blue","red"), domain = c("1","2","3"))
map <- leaflet(landfills_clusters_sf) %>%
addProviderTiles(providers$Esri.WorldImagery) %>%
setView(lng = 105.48, lat = 15.54, zoom = 6) %>%
addMiniMap %>%
addPolygons(data = vietnam, fill = F, weight = 2, color = "#FFFFCC", group = "Outline") %>%
addPolygons(data = landfills_polygons, fill = F, weight = 2, color = "#FFFFCC") %>%
addCircleMarkers(data = landfills_clusters_sf, color = ~cof(km_cluster_unstand), radius = sqrt(landfills_clusters_sf$area_ha)*2,
fillOpacity = 0.5, label = ~name, group = "Risk") %>%
addLegend("bottomleft", colors= c("red","blue","green"), labels=c("high", "medium", "low"), title = "Leakage Risk")
map
#### Interactive Map ####
ui_inter <- fluidPage("Classification the Plastic Leakage Risk of Landfills in Vietnam", id = "nav",
tabPanel("Interactive Map",
div(class = "outer",
# If not using custom CSS, set height of leafletOutput to a number instead of percent
leafletOutput("map", width = "1700px", height = "800px"),
absolutePanel(id = "controls", class = "panel panel-default", fixed = T,
draggable = T, top = 60, left = "auto", right = 20, bottom = "auto",
width = 350, height = "auto",
h2("Plastic Leakage Risk"),
plotOutput("histRain", height = 200),
plotOutput("histWind", height = 200),
),
)
),
tabPanel("Data Explorer",
hr(),
# display the data in an interactive table
DT::dataTableOutput("landfills"),
textInput('Long', 'Enter new landfill longitude'),
textInput('Lat', 'Enter new landfill latitude'),
actionButton("update", "Update Table")
)
)
df <- landfills_clusters_sf[-c(2,9:10,12,16:17)] # select relevant columns
## add long & lat coordinates
df$long <- st_coordinates(landfills_clusters_sf)[,1]
df$lat <- st_coordinates(landfills_clusters_sf)[,2]
server_inter <- function(input, output, session) {
## create interactive map with leaflet
output$map <- renderLeaflet({
map %>%
# add toolbox to draw polygons
addDrawToolbar(
targetGroup = "drawnPoly",
rectangleOptions = F,
polylineOptions = F,
markerOptions = F,
editOptions = editToolbarOptions(selectedPathOptions = selectedPathOptions()),
circleOptions = F,
circleMarkerOptions = F,
polygonOptions = drawPolygonOptions(showArea = T, repeatMode = F, shapeOptions =
drawShapeOptions(fillColor = "orange", clickable = T))) %>%
addStyleEditor()
})
latlongs <- reactiveValues() # temporary to hold coords
latlongs$df2 <- data.frame(Longitude = numeric(0), Latitude = numeric(0))
## create empty reactive spdf to store drawn polygons
value <- reactiveValues()
value$drawnPoly <- SpatialPolygonsDataFrame(SpatialPolygons(list()), data = data.frame(notes=character(0), stringsAsFactors = F))
# fix the polygon to start another
observeEvent(input$map_draw_new_feature, {
coor <- unlist(input$map_draw_new_feature$geometry$coordinates)
Longitude <- coor[seq(1,length(coor), 2)]
Latitude <- coor[seq(2,length(coor), 2)]
isolate(latlongs$df2 <- rbind(latlongs$df2, cbind(Longitude, Latitude)))
poly <- Polygon(cbind(latlongs$df2$Longitude, latlongs$df2$Latitude))
polys <- Polygons(list(poly), ID = input$map_draw_new_feature$properties$`_leaflet_id`)
spPolys <- SpatialPolygons(list(polys))
print(spPolys)
value$drawnPoly <- rbind(value$drawnPoly, SpatialPolygonsDataFrame(spPolys, data = data.frame(notes = NA, row.names = row.names(spPolys))))
## add polygons to landfills polygons df
test <- SpatialPolygonsDataFrame(spPolys, data = data.frame(name = 1:length(spPolys), row.names = row.names(spPolys)))
test#data$area <- NA
test#data$Notes <- NA
test#data$location <- NA
test#proj4string <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
new_polygons <- rbind(landfills_polygons, test)
## export new & old landfills to shapefile
shapefile(x = new_polygons, filename = "plasticleakagewebapp/data/landfill/OpenLandfills_Vietnam_total.shp", overwrite = T)
shapefile(x = test, filename = "plasticleakagewebapp/data/landfills/OpenLandfills_Vietnam_new.shp", overwrite = T)
## run DataPreparation script to calculate data of new landfill
source("plasticleakagewebapp/plasticleakage_datapreparation.R")
## import outcome of script
variables <- readOGR("plasticleakagewebapp/data/landfill_variables.gpkg")
# basic landfills as training data
train <- landfills_clusters#data[,c(7:8,11,13:15)]
# newly created landfills (from webapp) as testing data
test <- variables#data[,c(7:8,11,13:14)]
# predict risk class/cluster of new landfill (without re-running clustering algorithm)
knnClust <- class::knn(train = train[,-6], test = test, k = 1, cl = train$km_cluster_unstand)
knnClust
## add cluster as row
variables$km_cluster_unstand <- knnClust
# drop not needed columns
landfills_clusters$risk <- NULL
landfills_clusters$risk_label <- NULL
# combine all landfills into one spdf
new_variables <- rbind(landfills_clusters, variables)
## save results as shapefile
st_write(st_as_sf(new_variables), "plasticleakagewebapp/landfill_clusters_total.gpkg", overwrite = T, append = F)
## update plot upon ending draw
observeEvent(input$map_draw_stop, {
#replot it - take off the DrawToolbar to clear the features and add it back and use the values from the SPDF to plot the polygons
leafletProxy('map') %>%
removeDrawToolbar(clearFeatures = T) %>% removeShape('temp') %>% clearGroup('drawnPoly') %>%
addPolygons(data = value$drawnPoly, group = 'drawnPoly', color = "blue", layerId = row.names(value$drawnPoly)) %>%
addDrawToolbar(
targetGroup = "drawnPoly",
rectangleOptions = F,
polylineOptions = F,
markerOptions = F,
editOptions = editToolbarOptions(selectedPathOptions = selectedPathOptions()),
circleOptions = F,
polygonOptions=drawPolygonOptions(showArea = T, repeatMode = F, shapeOptions
= drawShapeOptions(fillColor = "orange", clickable = T)))
})
latlongs$df2 <- data.frame(Longitude = numeric(0), Latitude = numeric(0)) # clear df
## plot newly added landfills & risk cluster
leafletProxy("map", session) %>%
#addPolygons(data = landfills_polygons, fill = F, weight = 2, color = "#FFFFCC") %>%
addCircleMarkers(data = variables, color = ~cof(km_cluster_unstand), radius = sqrt(variables$area_ha)*2,
fillOpacity = 0.5, label = ~name, group = "Risk")
})
# create object for clicked marker (=landfill)
observeEvent(input$map_marker_click,{
## click returns clickid, long & lat
click <- input$map_marker_click
# if(is.null(click))
# return()
leafletProxy("map", session) %>% setView(lng = click$lng, lat = click$lat, zoom = 16)
})
# A reactive expression that returns the set of landfills that are in map bounds (to plot reactive graphs)
landfillsInBounds <- reactive({
if (is.null(input$map_bounds))
return(landfills_clusters_sf[FALSE,])
bounds <- input$map_bounds
latRng <- range(bounds$north, bounds$south)
lngRng <- range(bounds$east, bounds$west)
subset(landfills_clusters_sf,
st_coordinates(landfills_clusters_sf)[,2] >= latRng[1] & st_coordinates(landfills_clusters_sf)[,2] <= latRng[2] &
st_coordinates(landfills_clusters_sf)[,1] >= lngRng[1] & st_coordinates(landfills_clusters_sf)[,1] <= lngRng[2])
})
output$histRain <- renderPlot({
# If no zipcodes are in view, don't plot
if (nrow(landfillsInBounds()) == 0)
return(NULL)
hist(landfillsInBounds()$rain,
main = "Weather Data",
xlab = "Average Precipitation (mm)",
xlim = range(landfills_clusters_sf$rain),
col = '#00ffff',
border = 'white')
})
output$histWind <- renderPlot({
# If no landfills are in view, don't plot
if (nrow(landfillsInBounds()) == 0)
return(NULL)
hist(landfillsInBounds()$windspeed,
main = "",
xlab = "Average Wind Speed (km/h)",
xlim = range(landfills_clusters_sf$windspeed),
col = '#00DD00',
border = 'white')
})
output$landfills <- DT::renderDT({
df
})
}
# Run the app
shinyApp(ui_inter, server_inter)
Error which is returend when clicking "Run App" in RStudio:
Fehler in ogrListLayers(dsn = dsn) : Cannot open data source
I've just created my first Shiny app and published to the Internet - https://craycrayjodie.shinyapps.io/MapApp/
When launching the app and viewing in Chrome and I.E the default page ('Map' tab) loads as expected - with the "March" data displayed on the map. This is specified in the sliderTextInput for the page.
However, when I load the app and view in Firefox (i.e. the 'Map' tab), the "March" data is not displayed on the map when the app loads by default in Firefox. I need to move the sliderTextInput, then the data loads on the map in the Browser.
This is only an issue for Firefox, the other browsers (i.e. Chrome and IE) are fine and have the March data loaded and displayed on the map when the default 'Map' page loads.
I have published my files up to GitHub - https://github.com/craycrayjodie/DataVis
Also, my app.R logic is as follows:
library(dplyr)
library(lubridate)
library(sf)
library(leaflet)
library(shinythemes)
library(RColorBrewer)
library(shinyWidgets)
library(rmapshaper)
library(rsconnect)
library(shiny)
library(ggplot2)
library(highcharter)
library(magrittr)
library(htmlwidgets)
library(RColorBrewer)
library(shinycssloaders)
###################################################################################################
myAusdata_by_month_sf = readRDS("myAusdata_by_month.rds") #load previously saved datafile
myAusdata_by_month_5 = readRDS("myAusdata_by_month_5.rds") #load previously saved datafile
areas_by_weeks = readRDS("areas_by_weeks.rds") #load previously saved datafile
# Options for Spinner
options(spinner.color="pink", spinner.type = 7, spinner.color.background="#ffffff", spinner.size=1)
ui <- shinyUI(
navbarPage(
title = "Australians Mobility Changes During COVID",
theme = shinytheme("yeti"),
tabPanel("Map",
div(class = "outer",
tags$head(
includeCSS("styles.css")
),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 30, left = 250, draggable = TRUE,
# slider title, step increments
sliderTextInput("choices", "Select month:", choices = unique(myAusdata_by_month_sf$month),
animate = animationOptions(interval = 1500, loop = FALSE), grid = TRUE, selected = "March", width = 400))
),
tags$div(id = "cite",
'Data downloaded from Facebook for Good by Jodie Anderson (2020).'
)
),
tabPanel("Story",
highchartOutput("timeline", height = "800px" ) %>% withSpinner(),
includeMarkdown("analysis.md"),
br()
),
tabPanel("Heatmap",
highchartOutput("heatmap", height = "100%") %>% withSpinner(),
br()
),
tabPanel("About",
includeMarkdown("about.md"),
br()
)
)
)
# Define server logic
server <- function(input, output, session) {
filteredData <- reactive({
myAusdata_by_month_sf %>%
filter(month %in% input$choices)
})
popup <- reactive({
sprintf("%s: %.1f%%", filteredData()$polygon_name, filteredData()$AvRelChange*100)
})
output$map <- renderLeaflet({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leaflet(myAusdata_by_month_sf) %>%
setView(134, -29, 4) %>%
addProviderTiles("Esri.WorldGrayCanvas") %>%
addLegend(pal=mypalette, values=~AvRelChange, opacity=1, title = "Mobility Change (%)", position = "bottomleft",
labFormat = labelFormat(prefix = "(", suffix = ")", between = ", ",
transform = function(x) 100 * x))
})
observe({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leafletProxy("map", data = filteredData()) %>%
clearShapes() %>%
addPolygons(fillColor = ~mypalette(AvRelChange),
stroke=TRUE,
fillOpacity = 1,
color = "grey",
weight = 0.3,
label = popup(), labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "2px 2px"),
textsize = "13px",
direction = "auto", offset = c(20, -25)))
})
output$timeline <- renderHighchart ({
hc <- myAusdata_by_month_5 %>%
hchart ('spline', hcaes(x= date, y=AvRelChange, group=NAME_1)) %>%
hc_colors(brewer.pal(8, "Dark2")) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"),
align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_xAxis(title = list(text=NULL), plotBands = list(list(label = list(text = "Australia<br>in<br>lockdown"), color = "rgba(100, 0, 0, 0.1)",from = datetime_to_timestamp(as.Date('2020-03-16', tz = 'UTC')),
to = datetime_to_timestamp(as.Date('2020-03-31', tz = 'UTC'))))) %>%
hc_yAxis(title=list(text = "Mobility Change (%)"), showLastLabel = FALSE, labels = list(format = "{value}%")) %>%
hc_caption(text = "The Change in Mobility metric looks at how much people are moving around and compares it to a baseline period that predates most social distancing measures.<br>
The baseline period for this dataset is the four weeks of February 2020 (i.e. from the 2nd to the 29th).", useHTML = TRUE)%>%
hc_credits(text = "www.highcharts.com", href = "www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_tooltip(crosshairs = TRUE, borderWidth = 2, valueSuffix = "%") %>%
hc_navigator(enabled = TRUE) %>%
hc_rangeSelector(enabled = TRUE) %>%
hc_plotOptions(series = list(marker = list(enabled = FALSE), lineWidth = 4)) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-13', tz = 'UTC')),y = 7),shape = "rect", text = "10th July: QLD opens borders", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-20', tz = 'UTC')),y = -22),shape = "rect", text = "30th June: Vic in lockdown", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-08-20', tz = 'UTC')),y = -30),shape = "rect", text = "2nd Aug: Vic restrictions ease", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-11-14', tz = 'UTC')),y = -41),shape = "rect", text = "16th Nov: SA restrictions in place<br>21st Nov: SA restrictions lifted", useHTML = TRUE)))
hc
})
output$heatmap <- renderHighchart ({
hc1 <- areas_by_weeks %>%
hchart(type = "heatmap", hcaes(x = date, y = polygon_name, value = AvRelChange)) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"), align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_boost(useGPUTranslations = TRUE) %>%
hc_size(height = 5000, width = 550) %>%
hc_colorAxis(labels = list(format = '{value}%'), stops = color_stops(10, rev(brewer.pal(10, "RdBu")))) %>%
hc_legend(itemMarginTop = 75, layout = "vertical", verticalAlign = "top", align = "right", valueDecimals = 0) %>%
hc_xAxis(labels = list(enabled = FALSE), tickInterval = 5, title = NULL, lineWidth = 0, tickLength = 20) %>%
hc_yAxis(title=list(text = ""), reversed = TRUE, gridLineWidth = 0) %>%
hc_tooltip(pointFormat = '{point.date} <br> {point.polygon_name}: <b>{point.value} %') %>%
hc_credits(position = list(align = 'center', x = 135, y = -4), text = "www.highcharts.com", href = "http://www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_caption(align = 'center', text = "The white coloured boxes in the heatmap represent gaps in data.", useHTML = TRUE)
hc1
})
}
# Run the application
shinyApp(ui = ui, server = server)
If a clever cookie can please advise on what changes I need to make to get the app working when the page loads with Firefox, that would be fabulous :)
I'm trying to make a shiny app for some user-friendly data analysis of some data I have, and I'd like to change the outputted Plotly plot depending on which file i'm looking at. Basically, I'd like to have one plot outputted at a time, where I can cycle through several plots (that don't change place in my shiny app) depending on which folder and criteria i'm using. Currently I'm struggeling with this, and I don't know exactly what to do from here. I've attached a few images to clarify what I mean and what I want.
This photo shows my UI and how I want my figures to be displayed. I'd like all figures to show in that same location, depending on the selected file.
When I switch to 'Datalogger', a new plot is generated, and it is outputted below the first one. I'd like it to be placed on top of it, in the exact same location.
Any help you can offer would be very welcome.
Best,
T.
Script:
# Load packages
library(shiny)
library(shinythemes)
library(dplyr)
library(readr)
library(lubridate)
library(plotly)
#picarro
time = as.character(seq(as.POSIXct("2018-06-01 12:00:00"), as.POSIXct("2018-06-01 12:10:00"), by=seconds() )); ch4.corr = runif(length(time), 1980, 2000);
data = data.frame(time, ch4.corr); data$time = as.POSIXct(time);
#datalogger
time = as.character(seq(as.POSIXct("2018-06-01 12:00:00"), as.POSIXct("2018-06-01 12:10:00"), by=seconds() )); PressureOut = runif(length(time), 1010, 1020);
dlog = data.frame(time, PressureOut); dlog$time = as.POSIXct(time);
#dronelog
time = as.character(seq(as.POSIXct("2018-06-01 12:00:00"), as.POSIXct("2018-06-01 12:10:00"), by=seconds() ));
ulog = data.frame(time); ulog$time = as.POSIXct(time);
#------------------------------------------------------------------------------
ui <- fluidPage(
titlePanel("Active AirCore analysis"),
hr(),
fluidRow(
column(3,
radioButtons("fileInput", "File",
choices = c("Picarro", "Datalogger", "Dronelog"),
selected = "Picarro"),
hr(),
conditionalPanel(
condition = "input.fileInput == 'Picarro'",
sliderInput("timeInputPicarro", "Time", as.POSIXct(data$time[1]), as.POSIXct(data$time[length(data$time)]), c(as.POSIXct(data$time[1])+minutes(1), as.POSIXct(data$time[length(data$time)])-minutes(1)), timeFormat = "%H:%M:%S", ticks = T, step = seconds(1), pre = "")),
conditionalPanel(
condition = "input.fileInput == 'Datalogger'",
sliderInput("timeInputDatalogger", "Time", as.POSIXct(dlog$time[1]), as.POSIXct(dlog$time[length(dlog$time)]), c(as.POSIXct(dlog$time[1]), as.POSIXct(dlog$time[length(dlog$time)])), timeFormat = "%H:%M:%S", ticks = T, step = seconds(1), pre = "")),
conditionalPanel(
condition = "input.fileInput == 'Dronelog'",
sliderInput("timeInputDronelog", "Time", as.POSIXct(ulog$time[1]), as.POSIXct(ulog$time[length(ulog$time)]), c(as.POSIXct(ulog$time[1])+minutes(1), as.POSIXct(ulog$time[length(ulog$time)])-minutes(1)), timeFormat = "%H:%M:%S", ticks = T, step = seconds(1), pre = "")),
hr(),
conditionalPanel(
condition = "input.fileInput == 'Picarro'",
radioButtons("picarroPlotInput", "Plot type",
choices = c("Time-series", "Process"),
selected = "Time-series")),
conditionalPanel(
condition = "input.fileInput == 'Datalogger'",
radioButtons("dataloggerPlotInput", "Plot type",
choices = c("Time-series", "Altitude"),
selected = "Time-series")),
hr(),
checkboxGroupInput(inputId='sidebarOptions',
label=('Options'),
choices=c('Blabla', 'Store data', 'BlablaBla')),
hr()),
br(),
mainPanel(
plotlyOutput("dataplot"),
hr(),
plotlyOutput("dlogplot")
)
)
)
server <- function(input, output, session) {
datasetInputPic <- reactive({ data = data; })
datasetInputPicSamp <- reactive({ dat = data[(data$time>=input$timeInputPicarro[1]) & (data$time<=input$timeInputPicarro[2]),]; })
datasetInputDatalogger <- reactive({ dlog = dlog })
datasetInputDronelog <- reactive({ ulog = ulog })
output$dataplot <- renderPlotly({
if( (input$fileInput == 'Picarro' ) & (input$picarroPlotInput == 'Time-series')){
data = datasetInputPic();
data$time = as.POSIXct(data$time);
dat = datasetInputPicSamp();
dat$time = as.POSIXct(dat$time);
sec.col = "red";
f = list(size = 8);
x <- list(title = " ")
y <- list(title = "CH<sub>4</sub> [ppb]")
p2 = plot_ly() %>%
add_trace(data = data,
x = ~time,
y = ~ch4.corr,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = 'black')) %>%
add_trace(data = dat,
x = ~time,
y = ~ch4.corr,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = sec.col)) %>%
layout(xaxis = x, yaxis = y, title = '', showlegend = F, titlefont = f);
s1 = subplot(p2, margin = 0.06,nrows=1,titleY = TRUE) %>%
layout(showlegend = F, margin = list(l=50, r=0, b=50, t=10), titlefont = f);
s1
}
})
output$dlogplot <- renderPlotly({
if( (input$fileInput == 'Datalogger' ) & (input$dataloggerPlotInput == 'Time-series')){
data = datasetInputDatalogger();
data$time = as.POSIXct(data$time);
x <- list(title = " ")
y <- list(title = "Outside pressure [mbar]")
p1 = plot_ly() %>%
add_trace(data = data,
y = ~PressureOut,
x = ~time,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = 'black'));
s1 = subplot(p1, margin = 0.07, nrows=2, titleY = TRUE, titleX = FALSE)
layout(s1, showlegend = F, margin = list(l=100, r=100, b=0, t=100), title = "Datalogger data")
s1
}
})
outputOptions(output, c("dataplot", "dlogplot"), suspendWhenHidden = TRUE)
}
runApp(list(ui = ui, server = server))
Your issue is that in your ui you have written:
mainPanel(
plotlyOutput("dataplot"),
hr(),
plotlyOutput("dlogplot")
)
Using this structure, the "dlogplot" will always display below the "dataplot" because you essentially gave it its own position in the main panel that is below the "dataplot". One solution, if you want the plots to be displayed in the same exact spot when clicking the various buttons, is to give only one plotlyOutput. Next you would put conditional if, else if and else in renderPlotly. For example:
output$dataplot <- renderPlotly({
if( (input$fileInput == 'Picarro' ) & (input$picarroPlotInput == 'Time-series')){
data = datasetInputPic();
data$time = as.POSIXct(data$time);
dat = datasetInputPicSamp();
dat$time = as.POSIXct(dat$time);
sec.col = "red";
f = list(size = 8);
x <- list(title = " ")
y <- list(title = "CH<sub>4</sub> [ppb]")
p2 = plot_ly() %>%
add_trace(data = data,
x = ~time,
y = ~ch4.corr,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = 'black')) %>%
add_trace(data = dat,
x = ~time,
y = ~ch4.corr,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = sec.col)) %>%
layout(xaxis = x, yaxis = y, title = '', showlegend = F, titlefont = f);
s1 = subplot(p2, margin = 0.06,nrows=1,titleY = TRUE) %>%
layout(showlegend = F, margin = list(l=50, r=0, b=50, t=10), titlefont = f);
s1
}
else if( (input$fileInput == 'Datalogger' ) & (input$dataloggerPlotInput == 'Time-series')){
data = datasetInputDatalogger();
data$time = as.POSIXct(data$time);
x <- list(title = " ")
y <- list(title = "Outside pressure [mbar]")
p1 = plot_ly() %>%
add_trace(data = data,
y = ~PressureOut,
x = ~time,
type = 'scatter',
mode = "markers",
marker = list(size = 3, color = 'black'));
s1 = subplot(p1, margin = 0.07, nrows=2, titleY = TRUE, titleX = FALSE)
layout(s1, showlegend = F, margin = list(l=100, r=100, b=0, t=100), title = "Datalogger data")
s1
}
})
This code will put the "dlogplot" and the "dataplot" in the same position in your main panel. (You would also need to get rid of output$dlogplot <- renderPlotly({...}) so that it isn't also trying to make that plot.)
Try this out and see if it works for your purposes.