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))
})
}
)
)
I must design a graph that accumulates variables as they are added in Shiny R using plotly.
For example, if I graph the variable x with respect to the date t with a select input, I add the variable and it is located on the right side of the variable x, indicating with a separator that it is the variable y and so with as many variables are selected.
This is my code:
library(shiny)
library(plotly)
library(dplyr)
set.seed(123)
df <- data.frame(x = seq.Date(as.Date("2000/1/1"), by = "month", length.out = 100),
cat = sample(c("m1","m2","m3"),100, replace = TRUE),
a = cumsum(rnorm(100)),
b = rnorm(100),
c = rnorm(100),
d = rnorm(100))
ui <- fluidPage(
selectInput("x","Variable",names(df)[-1],NULL,TRUE),
selectInput("y", "category", unique(df$cat), NULL, TRUE),
numericInput("ls","limite superior",NULL,-100,100),
numericInput("li","limite superior",NULL,-100,100),
plotlyOutput("plot1")
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
req(input$y, input$x)
df <- df%>%
filter(cat %in% input$y)%>%
select(one_of("x",input$x))
estado <- ifelse(df[[2]]>input$ls,"red",
ifelse(df[[2]]<input$ls & df[[2]]>input$li,
"orange","green"))
df$estado <- estado
p <- plot_ly(df,
x = ~x,
y = ~df[[2]],
type = "scatter",
mode = "lines")
## Makers
p <- p %>%
add_trace(x = ~x,
y= df[[2]],
marker = list(color = ~estado, size = 20, symbol = "square"),
showlegend = FALSE)
## Lengends and labels
p <- p %>%
layout(legend = list(orientation = 'h'))%>%
layout(title = paste('Comportamiento de calidad de agua residual', input$estacion, sep=' '),
plot_bgcolor = "#e5ecf6",
xaxis = list(title = 'Fecha'),
yaxis = list(title = paste(input$x,"mg/l", sep=" ")))
print(p)
})
}
shinyApp(ui, server)
I need that when adding the variables a, b, c, d, the graph will be made just after the variable that was already there so that it looks something like this:
Use subplot and do function.
df %>%
group_by(category) %>%
do(p = plot_ly(...) %>% (plot_features...)) %>%
subplot(sharex= FALSE,sharey=TRUE, nrow=1, margin = 0.0001)
With plot feautures i mean all the deatils of the plot (markers, lines, colors, etc)
I am plotting a graph using the Plot_ly package in R Shiny. Right now I am creating a graph with many lines on it and I would like to know if it is possible for the user to toggle the lines on and off using the checkbox input.
Here is a sample of my server side code:
output$site_filter <- renderUI({
selectInput("site_filter", "Sites"
sort(unique(site_list$sites), decreasing = FALSE))
})
output$plots <- renderPlotly({
forecast_detail <- forecast[forecast$site == input$site_filter,]
actual_detail <- actual[actual$site == input$site_filter,]
p <- plot_ly() %>%
add_lines(x = forecast_detail$date, y = forecast_detail$total,
name = 'Forecast', line = list(color = 'purple')) %>%
add_lines(x = actual_detail$date, y = actual_detail$total,
name = 'Actual', line = list(color = 'blue'))
})
For my ui side, I created the checkbox like this:
fluidRow(checkboxInput("Actuals", "Actual Line", value = TRUE))
Is there a way I could use this checkbox input to toggle the actual lines on and off? I've been trying to use an if statement before the add_lines command but I get an error that states it is not logical.
You can store the first group of lines and add the second group based on a condition triggered by your checkbox. It is hard to come up with a working solution without a reproducible example but something like this should do the job:
output$plots <- renderPlotly({
forecast_detail <- forecast[forecast$site == input$site_filter,]
actual_detail <- actual[actual$site == input$site_filter,]
p <- plot_ly() %>%
add_lines(
x = forecast_detail$date,
y = forecast_detail$total,
name = 'Forecast',
line = list(color = 'purple')
)
if(!is.null(input$Actuals)) {
p <- p %>%
add_lines(
x = actual_detail$date,
y = actual_detail$total,
name = 'Actual',
line = list(color = 'blue')
)
}
return(p)
})
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.
anybody can help? trying to create plotly scatter chart where I can change color of selected markers. I checked the dataframe source and indt$active is a num, not factor, yet plotly chart interprets it as a factor
see the code, everything is fine until i set color = ~active. I tried using inside the reactive indt$active <- as.numeric(as.character( indt$active )) but it still does nothing. I am struggling to find what factor the chart fails on. It fails to load (you can comment out the color=~active to see without the error). To select values, you need to draw a box
library(plotly)
library(shiny)
library(dplyr)
library(tidyr)
tms<-format(seq(as.POSIXct("2013-01-01 00:00:00", tz="GMT"),
length.out=48, by='30 min'), '%H:%M')
dts<-c( "Day Before BH","BH","Sunday","Saturday","Friday","Thursday","Wednesday","Tuesday", "Monday" )
indt <- as.data.frame(matrix( c(0), nrow=9, ncol=48, byrow = TRUE))
indt<-cbind(dts,indt)
colnames(indt) <- c("dt",tms)
indt<-gather(indt,tm,active,-dt)
pal <- c("red", "blue")
pal <- setNames(pal, c(0, 1))
ui <- fluidPage(
plotlyOutput("plot")
)
server <- function(input, output, session) {
ind<-reactive({
d <- event_data("plotly_selected")
indt[d$pointNumber+1,3]<-1
indt<<-indt
return(indt)
})
output$plot <- renderPlotly({
f1 <- list(size = 8)
yform <- list(title = "",
categoryorder = "array",
categoryarray = dts
,tickfont = f1)
plot_ly(ind()
, x = ~tm, y = ~dt, mode = "markers", type = "scatter",
color = ~active,
colors = pal,
marker = list(size = 20)
) %>%
layout(dragmode = "select") %>%
layout(xaxis = list(title = "", tickfont = f1),
yaxis = yform)
})
}
shinyApp(ui, server)
In your plot_ly function try using color = ~as.character(active)instead of color = ~active