Reputation: 8404
In the shiny
app below I click on a point of my 1st line chart and subset the 2nd linechart. If I choose to click first on the 2nd linechart then I subset the 1st linechart.
But what if I had a third line chart and wanted to apply the same logic. Basically when I click on any chart first then the other 2 should be subsetted according to it.
library(shiny)
library(shinydashboard)
library(plotly)
library(dplyr)
library(ggplot2)
linedat1<-structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"), n_cases = c(1L, 1L, 1L, 2L, 3L,
1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)), row.names = c(NA, -15L
), class = c("tbl_df", "tbl", "data.frame"))
linedat2<-structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"), n_events = c(1L, 1L, 1L, 2L, 3L,
1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)), row.names = c(NA, -15L
), class = c("tbl_df", "tbl", "data.frame"))
linedat3<-structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"), n_objects = c(1L, 1L, 1L, 2L, 3L,
1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)), row.names = c(NA, -15L
), class = c("tbl_df", "tbl", "data.frame"))
ui <- tags$body(
dashboardPage(
# ----header----
header = dashboardHeader(
),
# ----sidebar----
sidebar = dashboardSidebar(
),
# ----body----
body = dashboardBody(
plotlyOutput("plot1"),
plotlyOutput("plot2"),
plotlyOutput("plot3"),
)
)
)
server <- function(input, output, session) {
output$plot1<-renderPlotly({
if(is.null(myPlotEventData2())){
p<-ggplot(data = linedat1, aes(x=date, y = n_cases)) +
geom_area( fill="#69b3a2", alpha=0.4) +
geom_line(color="#69b3a2", size=0.5) +
geom_point(size=1, color="#69b3a2")+ scale_color_grey() + theme_classic()+
labs(title="Cases per month",x="Date", y = "Cases")
ggplotly(p,source = "myPlotSource", customdata = ~date)
}
else{
linedat1<-subset(linedat1,date %in% myPlotEventData2()[1,3])
p<-ggplot(data = linedat1, aes(x=date, y = n_cases)) +
geom_area( fill="#69b3a2", alpha=0.4) +
geom_line(color="#69b3a2", size=0.5) +
geom_point(size=1, color="#69b3a2")+ scale_color_grey() + theme_classic()+
labs(title="Cases per month",x="Date", y = "Cases")
ggplotly(p)
}
})
myPlotEventData <- reactive({
event_data(
event = "plotly_click",
source = "myPlotSource")
})
myPlotEventData2 <- reactive({
event_data(
event = "plotly_click",
source = "myPlotSource2")
})
output$plot2<-renderPlotly({
if(is.null(myPlotEventData())){
p<-ggplot(data = linedat2, aes(x=date, y = n_events)) +
geom_area( fill="#69b3a2", alpha=0.4) +
geom_line(color="#69b3a2", size=0.5) +
geom_point(size=1, color="#69b3a2")+ scale_color_grey() + theme_classic()+
labs(title="Cases per month",x="Date", y = "events")
ggplotly(p,source = "myPlotSource2", customdata = ~date)
}
else{
linedat2<-subset(linedat2,date %in% myPlotEventData()[1,3])
p<-ggplot(data = linedat2, aes(x=date, y = n_events)) +
geom_area( fill="#69b3a2", alpha=0.4) +
geom_line(color="#69b3a2", size=0.5) +
geom_point(size=1, color="#69b3a2")+ scale_color_grey() + theme_classic()+
labs(title="Cases per month",x="Date", y = "events")
ggplotly(p)
}
})
output$plot3<-renderPlotly({
p<-ggplot(data = linedat3, aes(x=date, y = n_objects)) +
geom_area( fill="#69b3a2", alpha=0.4) +
geom_line(color="#69b3a2", size=0.5) +
geom_point(size=1, color="#69b3a2")+ scale_color_grey() + theme_classic()+
labs(title="Cases per month",x="Date", y = "objects")
ggplotly(p)
})
}
shinyApp(ui, server)
Upvotes: 1
Views: 496
Reputation: 33407
You'll have to create separate filtered datasets for each plot:
library(shiny)
library(shinydashboard)
library(plotly)
library(dplyr)
library(ggplot2)
linedat1 <- structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"),
n_cases = c(1L, 1L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)),
row.names = c(NA, -15L),
class = c("tbl_df", "tbl", "data.frame"))
linedat2 <- structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"),
n_events = c(1L, 1L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)),
row.names = c(NA, -15L),
class = c("tbl_df", "tbl", "data.frame"))
linedat3 <- structure(list(date = structure(c(18599, 18600, 18604, 18606,
18607, 18608, 18610, 18611, 18612, 18614, 18615, 18618, 18619,
18620, 18621), class = "Date"),
n_objects = c(1L, 1L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 2L)),
row.names = c(NA, -15L),
class = c("tbl_df", "tbl", "data.frame"))
ui <- tags$body(
dashboardPage(
header = dashboardHeader(),
sidebar = dashboardSidebar(),
body = dashboardBody(
plotlyOutput("plot1"),
plotlyOutput("plot2"),
plotlyOutput("plot3")
)
)
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
if (!is.null(myPlotEventData2())) {
displaydat1 <- subset(linedat1, date %in% myPlotEventData2()[1, 3])
} else if (!is.null(myPlotEventData3())){
displaydat1 <- subset(linedat1, date %in% myPlotEventData3()[1, 3])
} else {
displaydat1 <- linedat1
}
p <- ggplot(data = displaydat1, aes(x = date, y = n_cases)) +
geom_area(fill = "#69b3a2", alpha = 0.4) +
geom_line(color = "#69b3a2", size = 0.5) +
geom_point(size = 1, color = "#69b3a2") + scale_color_grey() + theme_classic() +
labs(title = "Cases per month", x = "Date", y = "Cases")
ggplotly(p, source = "myPlotSource1", customdata = ~ date)
})
output$plot2 <- renderPlotly({
if (!is.null(myPlotEventData1())) {
displaydat2 <- subset(linedat2, date %in% myPlotEventData1()[1, 3])
} else if (!is.null(myPlotEventData3())){
displaydat2 <- subset(linedat2, date %in% myPlotEventData3()[1, 3])
} else {
displaydat2 <- linedat2
}
p <- ggplot(data = displaydat2, aes(x = date, y = n_events)) +
geom_area(fill = "#69b3a2", alpha = 0.4) +
geom_line(color = "#69b3a2", size = 0.5) +
geom_point(size = 1, color = "#69b3a2") + scale_color_grey() + theme_classic() +
labs(title = "Cases per month", x = "Date", y = "events")
ggplotly(p, source = "myPlotSource2", customdata = ~ date)
})
output$plot3 <- renderPlotly({
if (!is.null(myPlotEventData1())) {
displaydat3 <- subset(linedat3, date %in% myPlotEventData1()[1, 3])
} else if (!is.null(myPlotEventData2())){
displaydat3 <- subset(linedat3, date %in% myPlotEventData2()[1, 3])
} else {
displaydat3 <- linedat3
}
p <- ggplot(data = displaydat3, aes(x = date, y = n_objects)) +
geom_area(fill = "#69b3a2", alpha = 0.4) +
geom_line(color = "#69b3a2", size = 0.5) +
geom_point(size = 1, color = "#69b3a2") + scale_color_grey() + theme_classic() +
labs(title = "Cases per month", x = "Date", y = "objects")
ggplotly(p, source = "myPlotSource3", customdata = ~ date)
})
myPlotEventData1 <- reactive({
event_data(event = "plotly_click", source = "myPlotSource1")
})
myPlotEventData2 <- reactive({
event_data(event = "plotly_click", source = "myPlotSource2")
})
myPlotEventData3 <- reactive({
event_data(event = "plotly_click", source = "myPlotSource3")
})
}
shinyApp(ui, server)
PS: in plotly you can also use the source
argument across multiple plots - but in this scenario we need to distinguish where the click event originated.
PPS: as a faster alternative to re-rendering the plot you could use plotlyProxy
to replace the underlying data. Here you can find an example.
Upvotes: 3