R Plotly extendTraces: Change to incremental and clear data - r

I am trying out the R Streaming example for extendTraces on Plotly. I am trying to add a functionality to the chart such that it would clear all the data as the browser starts stalling after some time (eg., an actionButton, etc). Is there a way to stop the trace and clear the trace/data on a second click of the actionButton ? Alternatively, is it possible to make the chart incremental, such that the entire data isn't getting stored locally.
https://plot.ly/r/streaming/#streaming-in-r
library(shiny)
library(plotly)
rand <- function() {
runif(1, min=1, max=9)
}
ui <- fluidPage(
includeCSS("styles.css"),
headerPanel(h1("Streaming in Plotly: Multiple Traces", align = "center")),
br(),
div(actionButton("button", "Extend Traces"), align = "center"),
br(),
div(plotlyOutput("plot"), id='graph')
)
server <- function(input, output, session) {
p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
output$plot <- renderPlotly(p)
observeEvent(input$button, {
while(TRUE){
Sys.sleep(1)
plotlyProxy("plot", session) %>%
plotlyProxyInvoke("extendTraces", list(y=list(list(rand()), list(rand()))), list(1,2))
}
})
}
shinyApp(ui, server)
Thanks in advance,
Raj.

Hi maybe you could do something like this?
library(shiny)
library(plotly)
library(shinyjs)
rand <- function() {
runif(1, min=1, max=9)
}
ui <- fluidPage(
# includeCSS("styles.css"),
headerPanel(h1("Streaming in Plotly: Multiple Traces", align = "center")),
br(),
div(actionButton("button", "Extend Traces"),actionButton("buttonReset", "Reset Traces"), align = "center"),
br(),
div(plotlyOutput("plot"), id='graph'),
useShinyjs()
)
server <- function(input, output, session) {
values <- reactiveValues()
values$p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
output$plot <- renderPlotly({values$p})
observe({
invalidateLater(1000, session)
req(input$button > 0)
plotlyProxy("plot", session) %>%
plotlyProxyInvoke("extendTraces", list(y=list(list(rand()), list(rand()))), list(1,2))
})
observeEvent(input$buttonReset,{
values$p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
runjs("Shiny.onInputChange('button',0)")
})
}
shinyApp(ui, server)
Hope this helps!!

Related

R Shiny plotly horizontal legend doesnt fit properly when box is small

Normally the legend of a plotly plot is positioned right to the plot. When added to a box in Shiny its scales well with the legend, no matter how small the box is...however when the legend is placed horizontally, the legend covers the plot when the box is scaled too small. Why is this? And how can I fox this?
Code plot:
x1 <- rnorm(50)
x2 <- rnorm(10)
fig <- plot_ly()
fig <- fig %>%
add_histogram(x = ~x1, name = "X1", marker = list(color = "red")
) %>%
add_histogram(x = ~x2, name = "X2", marker = list(color ="#blue")
) %>%
layout(legend = list(orientation = "h",
traceorder= 'normal',
xanchor = "center",
x = 0.5)
)
Code Shiny app:
ui <- dashboardPage(dashboardHeader(),
dashboardSidebar(),
dashboardBody(
box(
title = "test",
width = 4,
height = "auto",
plotlyOutput("plot1", height = "360px"),
inline = F
)
))
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
fig
})
}
shinyApp(ui, server)
I used a combination of the margin parameter of plotly's layout, and the y parameter of the legend to generate the output below.
Code:
library(tidyverse)
library(shiny)
library(shinydashboard)
library(plotly)
x1 <- rnorm(50)
x2 <- rnorm(10)
# THIS CHANGE
m <- list(
l = 10,
r = 10,
b = 100,
t = 10,
pad = 20
)
fig <- plot_ly()
fig <- fig %>%
add_histogram(x = ~x1, name = "X1", marker = list(color = "red")
) %>%
add_histogram(x = ~x2, name = "X2", marker = list(color ="#blue")
) %>%
layout(legend = list(orientation = "h",
traceorder= 'normal',
xanchor = "center",
x = 0.5,
y = -0.3), # THIS CHANGE
margin = m # THIS CHANGE
)
ui <- dashboardPage(dashboardHeader(),
dashboardSidebar(),
dashboardBody(
box(
title = "test",
width = 4,
height = "auto",
plotlyOutput("plot1", height = "360px"),
inline = F
)
))
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
fig
})
}
shinyApp(ui, server)

Fit Plotly Subplot in Bootstrap Card

In the reproducible code below plot 1 looks fine in terms of its width/height, but I'd like to expand plot 2 in terms of its height so the subplots don't seem so "squished" together. Does anyone have a suggestion on how to do that so it stays nicely within the card but expands responsively with the number of subplots? In this example, there are five subplots, but that could be any number (usually 2 to 7 or so).
library(shiny)
library(bslib)
library(shinyWidgets)
library(plotly)
card <- function(body, title) {
div(class = "card",
div(icon("chart-line", style = "color:white"), class = "card-header bg-success text-white text-center font-weight-bold", title),
div(class = "card-body d-flex justify-content-center", body)
)
}
ui <- fluidPage(
navbarPage(
theme = bs_theme(bootswatch = "flatly", version = 4),
title = 'Methods',
tabPanel('One'),
),
mainPanel(
h1('Hello World'),
uiOutput('p1'),
br(),
uiOutput('p2'),
)
)
server <- function(input, output) {
output$p1 <- renderUI({
fig <- plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length)
card(fig, 'Plot 1: Looks Good')
})
### I could do this
output$p2 <- renderUI({
vars <- setdiff(names(economics), "date")
plots <- lapply(vars, function(var) {
plot_ly(economics, x = ~date, y = as.formula(paste0("~", var))) %>%
add_lines(name = var)
})
card(subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE), 'Plot 2: Too Squished')
})
}
shinyApp(ui, server)
We can use plotlyOutput and pass a height parameter corresponding to the number of subplots:
library(shiny)
library(bslib)
library(shinyWidgets)
library(plotly)
card <- function(body, title) {
div(class = "card",
div(icon("chart-line", style = "color:white"), class = "card-header bg-success text-white text-center font-weight-bold", title),
div(class = "card-body d-flex justify-content-center", body)
)
}
ui <- fluidPage(
navbarPage(
theme = bs_theme(bootswatch = "flatly", version = 4),
title = 'Methods',
tabPanel('One'),
),
mainPanel(
h1('Hello World'),
uiOutput('p1'),
br(),
uiOutput('p2'),
)
)
server <- function(input, output) {
output$p1 <- renderUI({
fig <- plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length)
card(fig, 'Plot 1: Looks Good')
})
output$plotlyOut <- renderPlotly({
vars <- setdiff(names(economics), "date")
plots <- lapply(vars, function(var) {
plot_ly(economics, x = ~date, y = as.formula(paste0("~", var))) %>%
add_lines(name = var)
})
subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE)
})
output$p2 <- renderUI({
nSubplots <- length(setdiff(names(economics), "date"))
card(plotlyOutput("plotlyOut", height = paste0(nSubplots*200, "px")), 'Plot 2: Looks Good?')
})
}
shinyApp(ui, server)

Restyling traces using plotlyProxy in a scatterplot is unstable when points are colored according to category

I have a Shiny app that builds a scatterplot and highlights the clicked points by restyling the marker outline via plotlyProxy.
The app also subsets the data and moves the entries corresponding to the clicked points from the original "Data table" to an "Outlier table".
This seems to work fine when the markers are all the same color, or when they are colored by a continuous variable. But when I color the points by a categorical variable (like "Species"), it has a weird behavior, restyling a marker from each category instead of the clicked one. The data subsets correctly.
I think the restyle function should update all traces unless specified otherwise, so I am not sure where exactly lies the problem.
Here is my code:
library(plotly)
library(DT)
ui <- fluidPage(
mainPanel(
fluidRow(
div(
column(
width = 2,
uiOutput('chartOptions')),
column(width = 5,
h3("Scatter plot"),
plotlyOutput("scatterplot"),
verbatimTextOutput("click")
)
)
),
hr(),
div(
column(width = 6,
h2("Data Table"),
div(
DT::dataTableOutput(outputId = "table_keep"),
style = "height:auto; overflow-y: scroll;overflow-x: scroll;")),
column(width = 6,
h2("Outlier Data"),
div(
DT::dataTableOutput(outputId = "table_outliers"),
style = "height:auto; overflow-y: scroll;overflow-x: scroll;"))
)
))
server <- function(input, output, session){
datasetInput <- reactive({
df <- iris
return(df)
})
output$chartOptions <- renderUI({#choose variables to plot
if(is.null(datasetInput())){}
else {
list(
selectizeInput("xAxisSelector", "X Axis Variable",
colnames(datasetInput())),
selectizeInput("yAxisSelector", "Y Axis Variable",
colnames(datasetInput())),
selectizeInput("colorBySelector", "Color By:",
c(c("Do not color",colnames(datasetInput()))))
)
}
})
vals <- reactiveValues(#define reactive values for:
data = NULL,
data_keep = NULL,
data_exclude = NULL)
observe({
vals$data <- datasetInput()
vals$data_keep <- datasetInput()
})
## Datatable
output$table_keep <- renderDT({
vals$data_keep
},options = list(pageLength = 5))
output$table_outliers <- renderDT({
vals$data_exclude
},options = list(pageLength = 5))
# mechanism for managing selected points
keys <- reactiveVal()
observeEvent(event_data("plotly_click", source = "outliers", priority = "event"), {
req(vals$data)
is_outlier <- NULL
key_new <- event_data("plotly_click", source = "outliers")$key
key_old <- keys()
if (key_new %in% key_old){
keys(setdiff(key_old, key_new))
} else {
keys(c(key_new, key_old))
}
is_outlier <- rownames(vals$data) %in% keys()
vals$data_keep <- vals$data[!is_outlier, ]
vals$data_exclude <- vals$data[is_outlier, ]
plotlyProxy("scatterplot", session) %>%
plotlyProxyInvoke(
"restyle",
list(marker.line = list(
color = as.vector(ifelse(is_outlier,'black','grey')),
width = 2
))
)
})
observeEvent(event_data("plotly_doubleclick", source = "outliers"), {
req(vals$data)
keys(NULL)
vals$data_keep <- vals$data
vals$data_exclude <- NULL
plotlyProxy("scatterplot", session) %>%
plotlyProxyInvoke(
"restyle",
list(marker.line = list(
color = 'grey',
width = 2
)
))
})
output$scatterplot <- renderPlotly({
req(vals$data,input$xAxisSelector,input$yAxisSelector)
dat <- vals$data
key <- rownames(vals$data)
x <- input$xAxisSelector
y <- input$yAxisSelector
if(input$colorBySelector != "Do not color"){
color <- dat[, input$colorBySelector]
}else{
color <- "orange"
}
scatterplot <- dat %>%
plot_ly(x = dat[,x], y = dat[,y], source = "outliers") %>%
add_markers(key = key,color = color,
marker = list(size = 10, line = list(
color = 'grey',
width = 2
))) %>%
layout(showlegend = FALSE)
return(scatterplot)
})
output$click <- renderPrint({#click event data
d <- event_data("plotly_click", source = "outliers")
if (is.null(d)) "click events appear here (double-click to clear)" else d
})
}
shinyApp(ui, server)
The problem with your above code is that no traceIndices argument is provided for restyle. Please see this.
In your example, once you switch coloring to the factor Species plotly no longer creates one trace, but three. This happens in JS so counting is done from 0 to 2.
To restyle those traces you can address them via curveNumber (in this case 0:2) and pointNumber (50 data points in each trace 0:49)
With a single trace your example works as your key and your trace have the same length (150).
As your provided code is pretty long I just focused on the "Species" problem. It won't work in all other cases, but you should be able to deduce a more general approach from it:
library(shiny)
library(plotly)
library(DT)
ui <- fluidPage(
mainPanel(
fluidRow(
div(
column(
width = 2,
uiOutput('chartOptions')),
column(width = 5,
h3("Scatter plot"),
plotlyOutput("scatterplot"),
verbatimTextOutput("click")
)
)
),
hr(),
div(
column(width = 6,
h2("Data Table"),
div(
DT::dataTableOutput(outputId = "table_keep"),
style = "height:auto; overflow-y: scroll;overflow-x: scroll;")),
column(width = 6,
h2("Outlier Data"),
div(
DT::dataTableOutput(outputId = "table_outliers"),
style = "height:auto; overflow-y: scroll;overflow-x: scroll;"))
)
))
server <- function(input, output, session){
datasetInput <- reactive({
df <- iris
df$is_outlier <- FALSE
return(df)
})
output$chartOptions <- renderUI({#choose variables to plot
if(is.null(datasetInput())){}
else {
list(
selectizeInput("xAxisSelector", "X Axis Variable",
colnames(datasetInput())),
selectizeInput("yAxisSelector", "Y Axis Variable",
colnames(datasetInput())),
selectizeInput("colorBySelector", "Color By:",
c(c("Do not color",colnames(datasetInput()))))
)
}
})
vals <- reactiveValues(#define reactive values for:
data = NULL,
data_keep = NULL,
data_exclude = NULL)
observe({
vals$data <- datasetInput()
vals$data_keep <- datasetInput()
})
## Datatable
output$table_keep <- renderDT({
vals$data_keep
},options = list(pageLength = 5))
output$table_outliers <- renderDT({
vals$data_exclude
},options = list(pageLength = 5))
# mechanism for managing selected points
keys <- reactiveVal()
myPlotlyProxy <- plotlyProxy("scatterplot", session)
observeEvent(event_data("plotly_click", source = "outliers", priority = "event"), {
req(vals$data)
is_outlier <- NULL
plotlyEventData <- event_data("plotly_click", source = "outliers")
key_new <- plotlyEventData$key
key_old <- keys()
if (key_new %in% key_old){
keys(setdiff(key_old, key_new))
} else {
keys(c(key_new, key_old))
}
vals$data[keys(),]$is_outlier <- TRUE
is_outlier <- vals$data$is_outlier
vals$data_keep <- vals$data[!is_outlier, ]
vals$data_exclude <- vals$data[is_outlier, ]
print(paste("pointNumber:", plotlyEventData$pointNumber))
print(paste("curveNumber:", plotlyEventData$curveNumber))
plotlyProxyInvoke(
myPlotlyProxy,
"restyle",
list(marker.line = list(
color = as.vector(ifelse(vals$data[vals$data$Species %in% vals$data[plotlyEventData$key, ]$Species, ]$is_outlier,'black','grey')),
width = 2
)), plotlyEventData$curveNumber
)
})
observeEvent(event_data("plotly_doubleclick", source = "outliers"), {
req(vals$data)
keys(NULL)
vals$data_keep <- vals$data
vals$data_exclude <- NULL
plotlyProxyInvoke(
myPlotlyProxy,
"restyle",
list(marker.line = list(
color = 'grey',
width = 2
)
))
})
output$scatterplot <- renderPlotly({
req(datasetInput(),input$xAxisSelector,input$yAxisSelector)
dat <- datasetInput()
key <- rownames(dat)
x <- input$xAxisSelector
y <- input$yAxisSelector
if(input$colorBySelector != "Do not color"){
color <- dat[, input$colorBySelector]
}else{
color <- "orange"
}
scatterplot <- dat %>%
plot_ly(x = dat[,x], y = dat[,y], source = "outliers") %>%
add_markers(key = key,color = color,
marker = list(size = 10, line = list(
color = 'grey',
width = 2
))) %>%
layout(showlegend = FALSE)
return(scatterplot)
})
output$click <- renderPrint({#click event data
d <- event_data("plotly_click", source = "outliers")
if (is.null(d)) "click events appear here (double-click to clear)" else d
})
}
shinyApp(ui, server)
As a quick workaround, to avoid creating 3 traces, I simply converted the categorical variable assigned to color to numeric, and I hid the colorbar, so the output looks like this:
output$scatterplot <- renderPlotly({
req(vals$data,input$xAxisSelector,input$yAxisSelector)
dat <- vals$data
key <- rownames(vals$data)
x <- input$xAxisSelector
y <- input$yAxisSelector
if(input$colorBySelector != "Do not color"){
color <- as.numeric(dat[, input$colorBySelector])
}else{
color <- "orange"
}
scatterplot <- dat %>%
plot_ly(x = dat[,x], y = dat[,y], source = "outliers") %>%
add_markers(key = key,color = color,
marker = list(size = 10, line = list(
color = 'grey',
width = 2
))) %>%
layout(showlegend = FALSE) %>%
hide_colorbar()%>%
event_register("plotly_click")
return(scatterplot)
})
Update:
Another solution that I found is to make a loop of plotly proxies for each trace / category in the click event.
So the click event looks like this:
observeEvent(event_data("plotly_click", source = "outliers", priority = "event"), {
req(vals$data)
is_outlier <- NULL
key_new <- event_data("plotly_click", source = "outliers")$key
key_old <- keys()
#keys(c(key_new, key_old))
if (key_new %in% key_old){
keys(setdiff(key_old, key_new))
} else {
keys(c(key_new, key_old))
}
is_outlier <- rownames(vals$data) %in% keys()
vals$data_keep <- vals$data[!is_outlier, ]
vals$data_exclude <- vals$data[is_outlier, ]
indices <- list()
p <- plotlyProxy("scatterplot", session)
if(input$colorBySelector != "Do not color"){
if(is.factor(vals$data[,input$colorBySelector])){
for (i in 1:length(levels(vals$data[,input$colorBySelector]))){
indices[[i]] <- rownames(vals$data[which(vals$data[,input$colorBySelector] == levels(vals$data[,input$colorBySelector])[i]), ]) #retrieve indices for each category
plotlyProxyInvoke(p,
"restyle",
list(marker.line = list(
color = as.vector(ifelse(is_outlier[as.numeric(indices[[i]])],'black','grey')),
width = 2
)), c(i-1) #specify the trace (traces are indexed from 0)
)
}
}else{
p %>%
plotlyProxyInvoke(
"restyle",
list(marker.line = list(
color = as.vector(ifelse(is_outlier,'black','grey')),
width = 2
))
)
}
}else{
p %>%
plotlyProxyInvoke(
"restyle",
list(marker.line = list(
color = as.vector(ifelse(is_outlier,'black','grey')),
width = 2
))
)
}
})

Shinydashboard: height issue even using fluidRow

I need to make a very professional Shinyapp, but the end of the body of the app ends in the middle of the last plot.
I found this other question, but it's solution (use fluidRow) doesn't work in my case:
https://stackoverflow.com/questions/46259208/shiny-dashboard-mainpanel-height-issue
What could be wrong?
All data is reproducible.
## app.R ##
library(shiny)
library(shinydashboard)
library(dygraphs)
library(plotly)
library(readr)
ui <- dashboardPage(
dashboardHeader(title = "Monitoramento Banco de Dados"),
dashboardSidebar(
sliderInput("DateInput", "Periodo", -30, 0, c(-15, 0), pre = "D.")
),
dashboardBody(
fluidRow(
dygraphOutput("plot1"),
br(),
plotlyOutput("plot")
)
)
)
server <- function(input, output) {
output$plot1 <- renderDygraph({
lungDeaths <- cbind(ldeaths, mdeaths, fdeaths)
dyRangeSelector(dygraph(lungDeaths, main = "Deaths from Lung Disease (UK)"), dateWindow = c("1974-01-01", "1980-01-01"))
})
sesiones_por_fuente <- reactive({
#sesiones_ga <- read_csv("www/ga-sesiones-lc-20180824.csv", skip = 0)
sesiones_ga <- read_csv("https://www.dropbox.com/s/w2ggnb0p4mz2nus/sesiones-2018.csv?dl=1", skip = 0)
sesiones_ga <- sesiones_ga %>%
group_by(date, sources) %>%
summarise(sessions = sum(sessions)) %>%
filter(sources != "spam")
})
m <- list(
l = 120,
r = 120,
b = 100,
t = 100,
pad = 20
)
output$plot <- renderPlotly({
plot_ly(sesiones_por_fuente(), x = ~sessions, y = ~sources, type = 'bar',
width = 1200, height = 500, orientation = 'h') %>%
layout(title = "Sesiones por mes",
xaxis = list(title = ""),
yaxis = list(title = ""),
margin = m) %>%
layout(hovermode = 'compare',
separators = ',')
})
}
shinyApp(ui, server)
So I had to inspect the HTML produced by Shiny. And its results that the plotly graphs are rendered in a div (produced by the server.R file) an this div is inside another div (produced by ui.R).
So, if the inner div, produced by the sever.R file, is bigger than the div produced by the ui.R file that produces that layout error.
So, if you have this in the server.R (notice the height argument of 500px in the plot_ly fun()):
output$plot <- renderPlotly({
sesiones_fuente <- sesiones_por_fuente() %>%
filter(date > input$dateRange[1], date < input$dateRange[2]) %>%
group_by(sources) %>%
summarise(sessions = sum(sessions))
plot_ly(sesiones_fuente, x = ~sessions, y = ~sources, type = 'bar',
width = 1200, height = 500, orientation = 'h') %>%
layout(title = "Sesiones por mes",
xaxis = list(title = ""),
yaxis = list(title = ""),
margin = m)
})
You need to used the argument height=500px in plotlyOutput or a Fluidrow of the same height in ui.R:
plotlyOutput of height 500px:
fluidRow(
column(12, offset = 1,
plotlyOutput("plot_sesiones_por_mes", height = "500px"))),
br(),
fluidRow of height 500px:
fluidRow(style = "height:500px",
column(12, offset = 1,
plotlyOutput("plot_sesiones_por_mes"))),
br(),

Linking Leaflet's icons to plotly line plot in Shiny

I would like the icons on a leaflet map to be linked to the correspondent trace on a plotly line plot in a shiny app. Once I click on an icon, only the line with the same id should be displayed in plotly. Is this possible? I have been trying with crosstalk but I must be missing something.
library(shiny)
library(leaflet)
library(plotly)
library(crosstalk)
tmp1 <- data.frame(Date = seq(as.POSIXct("2016-06-18 10:00"),
length.out = 10, by = "mins"),
Temp = rnorm(n = 10, mean = 20, sd = 5),
lat=51.504162,
long=-0.130472,
id="first")
tmp2 <- data.frame(Date = seq(as.POSIXct("2016-06-18 10:00"),
length.out = 10, by = "mins"),
Temp = rnorm(n = 10, mean = 20, sd = 5),
lat=51.502858,
long= -0.116722,
id="second")
uktemp<-rbind(tmp1,tmp2)
#=========================================
ui <- fluidPage(
fluidRow(
column(6, leafletOutput("map")),
column(6, plotlyOutput("graph"))
)
)
server <- function(input, output, session) {
crossuktemp<- SharedData$new(uktemp)
output$map <- renderLeaflet({
leaflet(options = leafletOptions(minZoom = 15,maxZoom =18 ))%>%
addTiles()%>%
addCircles(data=crossuktemp,
lng= ~ long,
lat= ~ lat,
label=~id)
})
output$graph <- renderPlotly({
plot_ly(crossuktemp,x=~Date,y=~Temp, color =~id, mode="lines")%>%
layout(title = "",yaxis = list(title = "C°"),
xaxis = list(title = "Time")) %>%
highlight(off = "plotly_deselect")
})
}
shinyApp(ui, server)
I've hacked together a solution, making use of leaflets events it creates on the click.
ui <- fluidPage(
# add a reset button to undo click event
fluidRow(actionButton("reset", "Reset")),
fluidRow(
column(6, leafletOutput("map")),
column(6, plotlyOutput("graph"))
),
fluidRow()
)
server <- function(input, output, session) {
# create reactive data set based on map click
filteredData <- reactive({
event <- input$map_shape_click
if (!is.null(event)){
uktemp[uktemp$lat == event$lat & uktemp$long == event$lng,]
}
})
output$map <- renderLeaflet({
leaflet(options = leafletOptions(minZoom = 15,maxZoom =18 ))%>%
addTiles()%>%
addCircles(data=uktemp,
lng= ~ long,
lat= ~ lat,
label=~id)
})
# default graph
output$graph <- renderPlotly({
plot_ly(uktemp,x=~Date,y=~Temp, color =~id, mode="lines")%>%
layout(title = "",yaxis = list(title = "C°"),
xaxis = list(title = "Time")) %>%
highlight(off = "plotly_deselect")
})
# if clicked on map, use filtered data
observeEvent(input$map_click,
output$graph <- renderPlotly({
plot_ly(filteredData(),x=~Date,y=~Temp, color =~id, mode="lines")%>%
layout(title = "",yaxis = list(title = "C°"),
xaxis = list(title = "Time")) %>%
highlight(off = "plotly_deselect")
})
)
# if reset, then go back to main data
observeEvent(input$reset,
output$graph <- renderPlotly({
plot_ly(uktemp,x=~Date,y=~Temp, color =~id, mode="lines")%>%
layout(title = "",yaxis = list(title = "C°"),
xaxis = list(title = "Time")) %>%
highlight(off = "plotly_deselect")
})
)
}
To do so, have a read of these links
see the section: Inputs/Events
https://rstudio.github.io/leaflet/shiny.html
some SO questions
Click event on Leaflet tile map in Shiny
R shiny: reset plot to default state
To do undo the click event, I had to add a reset button in. Maybe there is a way of undoing a click in a more elegant way. I expect there are cleaner ways to build this if you read around it some more :)
Cheers,
Jonny

Resources