Scatterplot in Shiny Module Issue - r

I have a shiny app, example shown below that should be reproducible where I am trying to show a ggplot2 scatterplot with points which can be excluded as shown in this example here. I am also using modules, which might be part of this issue here.
https://gallery.shinyapps.io/106-plot-interaction-exclude/
I keep getting this "Error in eval: object 'xaxis' not found" message. Any ideas? I put the module code up front then the rest of the code for the app.R file.
library(ggplot2)
library(scales)
library(shiny)
library(shinydashboard)
###### MODULE CODE ###############
scatter_graphUI <- function(id, tab_panel_name, height = "500px") {
ns <- NS(id)
tabPanel(tab_panel_name,
plotOutput(ns("scatter_1"), height = height, click = "plot1_click", brush =
brushOpts(id = "plot1_brush")),
actionButton(ns("exclude_toggle"), "Toggle points"),
actionButton(ns("exclude_reset"), "Reset")
)
}
scatter_graph <- function(input, output, session, scatter_data, col_select) {
scatter_data_df <- reactive({
mtcars
})
vals <- reactiveValues()
data_df <- reactive({
scatter_df <- scatter_data_df()
main_df <- scatter_df[,col_select]
vals$keeprows = rep(TRUE,nrow(main_df))
main_df
})
output$scatter_1 <- renderPlot({
graph_df <- data_df()
# Plot the kept and excluded points as two separate data sets
keep <- graph_df[ vals$keeprows,]
exclude <- graph_df[!vals$keeprows,]
final_df <- keep
title = paste(colnames(final_df)[1], "vs", colnames(final_df)[2])
line_method = "quad"
axis_text = 12
title_text = 16
split_colors = TRUE
colors = c("red","black")
# create red points for negative x axis returns if split_colors is TRUE
if (split_colors == TRUE) {
final_df[,"color"] <- ifelse(final_df[,2,drop=F]<0,colors[1],colors[2])
} else {
final_df[,"color"] <- ifelse(final_df[,2,drop=F]<0,colors[2],colors[2])
}
# create a generic graphing final_df
colnames(final_df) <- c("xaxis","yaxis","color")
# setup the graph
gg <- ggplot(final_df, aes(x = xaxis, y = yaxis)) + geom_point(color = final_df[,"color"])
gg <- gg + geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25) +
coord_cartesian(xlim = c(1.5, 5.5), ylim = c(5,35))
if (line_method == "loess") {
gg <- gg + stat_smooth(span = 0.9)
} else if (line_method == "quad") {
gg <- gg + stat_smooth(method = "lm", formula = y ~ poly(x, 2), size = 1)
} else if (line_method == "linear") {
gg <- gg + stat_smooth(method = "lm")
} else {
}
gg <- gg + theme_bw()
gg <- gg + labs(x = colnames(final_df)[2], y = colnames(final_df)[3], title = title)
gg
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
main_df <- data_df()
res <- nearPoints(main_df, input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Toggle points that are brushed, when button is clicked
observeEvent(input$exclude_toggle, {
main_df <- data_df()
res <- brushedPoints(main_df, input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Reset all points
observeEvent(input$exclude_reset, {
main_df <- data_df()
vals$keeprows <- rep(TRUE, nrow(main_df))
})
}
########################################
##### REST OF APP CODE ######
header <- dashboardHeader(
title = 'Test Dashboard'
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "scatter_eval",
tabBox(
title = "Scatter",
selected = "Selected",
height = "600px", side = "right",
scatter_graphUI("selected_scatter", "Selected")
)
)
)
)
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Scatter Evaluation", icon = icon("th"), tabName = "scatter_eval")
)
)
ui <- dashboardPage(skin = "blue",
header,
sidebar,
body
)
server <- function(input, output, session) {
callModule(scatter_graph, id ="selected_scatter", scatter_data = reactive(selected_scatter_data()),
col_select = c(1,2))
}
shinyApp(ui = ui, server = server)
########

The issue is the two lines:
gg <- ggplot(final_df, aes(x = xaxis, y = yaxis)) + geom_point(color = final_df[,"color"])
gg <- gg + geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25) +
coord_cartesian(xlim = c(1.5, 5.5), ylim = c(5,35))
Because you have not set a new aes for the exclude object, it inherits the aes from your ggplot call. It therefore needs to find a column named xaxis and yaxis in the exclude dataset. Since you only renamed final_df, it throws this error.
A graph is displayed when you change:
colnames(final_df) <- c("xaxis","yaxis","color")
to:
colnames(final_df) <- c("xaxis","yaxis","color")
colnames(exclude) <- c("xaxis","yaxis")

Related

R Shiny recoloring of points

I would like click-select points and group them based on color.
I can save selected points with color information into a new data frame and plot it, however I would like to keep track and see what was already selected on the interactive plot.
How can I show/label already selected points or make it permanent after "Add selection"?
library(shiny)
library(tidyverse)
library(DT)
library(colourpicker)
ui = fluidPage(
colourInput("col", "Select colour", "purple"),
actionButton("addToDT", "Add selection", icon = icon("plus")), hr(),
plotOutput("plot", click = "plot_click", dblclick = "plot_reset"),
DT::dataTableOutput('plot_DT'), hr(),
textOutput("clickcoord"),
DT::dataTableOutput('final_DT'),
plotOutput("plotSelected")
)
server = function(input, output, session) {
selectedPoint = reactiveVal(rep(FALSE, nrow(mtcars)))
output$clickcoord <- renderPrint({
print(input$plot_click)
})
observeEvent(input$plot_click, {
clicked = nearPoints(mtcars, input$plot_click, allRows = TRUE)$selected_
selectedPoint(clicked | selectedPoint())
})
observeEvent(input$plot_reset, {
selectedPoint(rep(FALSE, nrow(mtcars)))
})
output$plot_DT = DT::renderDataTable({
mtcars$sel = selectedPoint()
mtcars = dplyr::filter(mtcars, sel == TRUE) %>% mutate(group_color = input$col)
})
final_DT = reactiveValues()
final_DT$df = data.frame()
FinalData = eventReactive(input$addToDT, {
mtcars$sel = selectedPoint()
mtcars = dplyr::filter(mtcars, sel == TRUE) %>% mutate(group_color = input$col)
final_DT$df = bind_rows(final_DT$df, mtcars)
})
output$final_DT = renderDataTable({FinalData()})
output$plot = renderPlot({
mtcars$sel = selectedPoint()
ggplot(mtcars, aes(wt, mpg, color = mtcars$sel, fill=mpg)) +
geom_point(shape = 21, size = 6, stroke = 2) +
scale_color_manual(values = c("#ffffff00", input$col)) +
scale_fill_viridis_c() +
theme_bw()
})
output$plotSelected = renderPlot({
sel_df = FinalData()
ggplot(sel_df, aes(wt, mpg, fill = group_color, colour = group_color)) +
geom_point(shape = 21, size = 6, stroke = 2) +
scale_color_manual(values = unique(sel_df$group_color)) +
scale_fill_manual(values = unique(sel_df$group_color)) +
theme_bw()
})
observeEvent(input$addToDT, {
selectedPoint(rep(FALSE, nrow(mtcars)))
})
}
shinyApp(ui, server)
I think this is the "crux" of what your are looking for. I used a very similar example that I found in the help for entitled:
A demonstration of clicking, hovering, and brushing
(https://shiny.rstudio.com/reference/shiny/0.13.1/plotoutput)
It is very similar to your example.
I create a matrix of T/F elements where the rows are the observations and the columns are in which batch the observation is selected. So when you launch the whole matrix is False, but as you click on observations the switch to positive in the first column. Then if you click addSelection and continue you start switching the observations in the next column.
Could you confirm that this what you are looking for?
Below is the code.
shinyApp(
ui = basicPage(
fluidRow(
column(
width = 4,
plotOutput("plot",
height = 300,
click = "plot_click", # Equiv, to click=clickOpts(id='plot_click')
),
actionButton("addToDT", "Add selection", icon = icon("plus")), hr(),
h4("Clicked points"),
tableOutput("plot_clickedpoints"),
),
column(
width = 4,
verbatimTextOutput("counter"),
),
)
),
server = function(input, output, session) {
data <- reactive({
input$newplot
# Add a little noise to the cars data so the points move
cars + rnorm(nrow(cars))
})
output$plot <- renderPlot({
d <- data()
plot(d$speed, d$dist, main = paste("No of Sets Chosen", input$addToDT))
})
output$plot_clickinfo <- renderPrint({
cat("Click:
")
str(input$plot_click)
})
selectedPoints <- reactiveVal(rep(FALSE, nrow(cars)))
selectionMatrix <- reactiveVal(matrix(data = F, nrow = nrow(cars), ncol = 7))
observeEvent(input$plot_click, {
clicked <- nearPoints(data(), input$plot_click, "speed", "dist", allRows = TRUE)$selected
selectedPoints(clicked | selectedPoints())
tmp <- unlist(selectionMatrix())
tmp[, (input$addToDT + 1)] <- selectedPoints()
selectionMatrix(tmp)
})
observeEvent(input$addToDT, {
selectedPoints(rep(FALSE, nrow(cars)))
})
output$plot_clickedpoints <- renderTable({
# if (input$addToDT==0) {
res <- selectionMatrix()
return(res)
})
}
)

When click actionbutton to refresh plot there is a table that is not be refreshed

I created a shinyapp and there are three vital buttons.
The three buttons works well
And the click3 can output a plot and a table togather.
Now I met a problem that plot1, plot2 and plot3(plot3 and the heatmap output togather) can refresh each other ideally.But it works doesn't look like that.
The output table always keep stay there no matter click1 or click2 clicked.
I tried modifying my code but it didn't work.
I hope somebody could give me some advice that the table will diappear with the heatmpa no matter which button clicked.
My reproducible code and data here:
library(shiny)
library(ggplot2)
## load("04.21_3.RData")
mean_data <- data.frame(
Name = c(paste0("Group_", LETTERS[1:20])),
matx <- matrix(sample(1:1000, 1000, replace = T), nrow = 20)
)
names(mean_data)[-1] <- c(paste0("Gene_", 1:50))
sd_data <- data.frame(
Name = c(paste0("Group_", LETTERS[1:20])),
matx <- matrix(runif(1000, 5, 10), nrow = 20)
)
names(sd_data)[-1] <- c(paste0("Gene_", 1:50))
############
ui <- fluidPage(
sidebarPanel(
selectizeInput(
"selectGeneSymbol",
"Select:",
choices = NULL,
multiple =F,
width = 400,
selected = NULL,
options = list(placeholder = 'e.g. gene here',create = F)
),
actionButton("plot1", "click1"),
actionButton("plot2", "click2"),
actionButton("dataTable", "click3")
),
mainPanel(
uiOutput("all"),
# plotOutput("myPlot"),
tableOutput("myTable")
)
)
server <- function(input, output, session) {
updateSelectizeInput(session, "selectGeneSymbol", choices = colnames(mean_data[,-1]), server = TRUE)
global <- reactiveValues(out = NULL,
p1 = NULL,
p2 = NULL)
plotdata <- eventReactive(input$plot1,{
df <- mean_data %>% mutate(sd = sd_data[,input$selectGeneSymbol])
})
output$all <- renderUI({ ##
global$out
})
observeEvent(input$plot1, {
global$out <- plotOutput("plot1")
})
##
observeEvent(input$plot2, {
global$out <- plotOutput("plot2")
})
observeEvent(input$dataTable, {
global$out <- plotOutput("myPlot")
})
####
myPlot = reactiveVal()
myData = reactiveVal()
observeEvent(input$dataTable, {
data_cor<-mean_data[,-1]
tm <- corr.test(data_cor[,input$selectGeneSymbol,drop=FALSE],
y = data_cor, use = "pairwise", "spearman", adjust="none",
alpha=0.05, ci=F, minlength=5)
res <-setNames(as.data.frame(t(do.call(rbind, tm[c("r", "p")]))), c("Correlation", "P_value"))
res<-res[-which(rownames(res)== input$selectGeneSymbol),]
res<-data.frame(Gene=rownames(res),res)
res
##############
data_correlation=t(mean_data[, -1])
data_subset=data_correlation[c(input$selectGeneSymbol, as.vector(head(res$Gene, 10))), ]
myPlot(
pheatmap(log2(data_subset+1), show_colnames = F,fontsize_row =12,
cluster_rows = F, cluster_cols = F, gaps_row = 1)
)
myData(res)
})
output$myPlot = renderPlot({
myPlot()
})
output$myTable = renderTable({
myData()
})
####
p1 <- eventReactive(input$plot1,
{
ggplot(data =plotdata(), aes(x = Name, y = .data[[as.name(input$selectGeneSymbol)]])) +
geom_bar(stat = "identity", position = position_dodge(0.9), width = 0.9) +
theme(legend.position = "none") +
labs(title = paste(input$selectGeneSymbol), x = NULL, y = "666666") })
p2 <- eventReactive(input$plot2,
{
ggplot(data = plotdata(), aes(x = Name, y = .data[[as.name(input$selectGeneSymbol)]], fill=Name)) +
geom_bar(stat = "identity", position = position_dodge(0.9), width = 0.9) +
theme(legend.position = "none") +
labs(title = paste(input$selectGeneSymbol), x = NULL, y = "777777") })
output$plot1 <- renderPlot({
p1()})
output$plot2 <- renderPlot({
p2()})
}
shinyApp(ui, server)
Try this
observeEvent(input$plot1, {
global$out <- plotOutput("plot1")
myData(NULL)
})
observeEvent(input$plot2, {
global$out <- plotOutput("plot2")
myData(NULL)
})

Using a (logical) vector from a reactive expression in a reactive context / attempt to apply non-function error

I am trying to use a logical vector from a reactive expression. This generates an error in a function xor() when I try to perform a logical operation on this vector in another reactive expression. I would like to generate a reactive expression (logical vector), and then use it in another reactive function. A toy example below. The error appears when points on the plot are clicked.
In the original here, keeprows() is not reactive, but I would like to make this structured as on the schematic below (from Shiny website). The fist object is input for a reactive expression, and then a second (reactive) object (which is a user-subsetted table) is used for point selection, etc. The elements after bifurcation are the tables with the kept and excluded points. I have a problem in making this last subsetting to work.
Could someone explain to me the root of this problem?
library(ggplot2)
library(shiny)
library(dplyr)
ui <- fluidPage(
fluidRow(
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click",
brush = brushOpts(
id = "plot1_brush"
)
),
actionButton("exclude_toggle", "Toggle points"),
sliderInput(inputId = "efficiency", value = 20, label = "MPG", min = min(mtcars$mpg), max = max(mtcars$mpg))
)
)
)
server <- function(input, output) {
# For storing which rows have been excluded
mt_subset <- reactive(mtcars %>% filter(mpg > input$efficiency))
vals <- reactiveValues()
vals$keeprows <- reactive(rep(TRUE, nrow(mt_subset()), label = "TuProblem", quoted = FALSE))
output$plot1 <- renderPlot({
# Plot the kept and excluded points as two separate data sets
keep <- mt_subset()[ vals$keeprows(), , drop = FALSE]
exclude <- mt_subset()[!vals$keeprows(), , drop = FALSE]
ggplot(keep, aes(wt, mpg)) + geom_point() +
geom_smooth(method = lm, fullrange = TRUE, color = "black") +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25) +
coord_cartesian(xlim = c(1.5, 5.5), ylim = c(5,35))
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
res <- nearPoints(mt_subset(), input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(as.logical(vals$keeprows()), as.logical(res$selected_))
})
# Toggle points that are brushed, when button is clicked
observeEvent(input$exclude_toggle, {
res <- brushedPoints(mt_subset(), input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows(), res$selected_)
})
}
shinyApp(ui, server)
I'm not sure if this is the output you're looking for, but this code reads in a local file and then performs the brushing point selection, greying out the brushed points after "toggle points" is hit and also adjusting the correlation.
library(ggplot2)
library(Cairo) # For nicer ggplot2 output when deployed on Linux
library(shiny)
library(readxl)
data(iris)
write.xlsx(x = iris, file = "iris.xlsx")
ui <- fluidPage(
fluidRow(
fileInput(inputId = "file",
label = "Load file"),
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click",
brush = brushOpts(
id = "plot1_brush"
)
),
actionButton("exclude_toggle", "Toggle points"),
actionButton("exclude_reset", "Reset")
)
)
)
server <- function(input, output) {
# Get file
getFile <- reactive({ if (is.null(input$file)) {
return(NULL)
} else {
return(input$file)
}})
# Read data
data <- reactive({ if (is.null(getFile())) {
return(NULL)
} else {
as.data.frame(read_excel(getFile()$datapath))
}})
# For storing which rows have been excluded
vals <- reactiveValues()
observeEvent(data(), {
vals$keeprows <- rep(T, nrow(data()))
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
res <- nearPoints(data(), input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Toggle points that are brushed, when button is clicked
observeEvent(input$exclude_toggle, {
res <- brushedPoints(data(), input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Reset all points
observeEvent(input$exclude_reset, {
vals$keeprows <- rep(TRUE, nrow(data()))
})
output$plot1 <- renderPlot({
if (is.null(data())) {
return(NULL)
} else {
# Indices for keep and exclude
keep_v <- which(vals$keeprows)
exclude_v <- which(!vals$keeprows)
# Subset data
keep <- data()[keep_v, , drop = F]
exclude <- data()[exclude_v, , drop = F]
ggplot(keep, aes(Sepal.Length, Sepal.Width)) + geom_point() +
geom_smooth(method = lm, fullrange = TRUE, color = "black") +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25)
}
})
}
shinyApp(ui, server)
Solved:
library(ggplot2)
library(shiny)
library(dplyr)
ui <- fluidPage(
fluidRow(
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click",
brush = brushOpts(
id = "plot1_brush"
)
),
actionButton("exclude_toggle", "Toggle points"),
sliderInput(inputId = "efficiency", value = 20, label = "MPG", min = min(mtcars$mpg), max = max(mtcars$mpg))
)
)
)
server <- function(input, output) {
mt_subset <- reactive(mtcars %>% filter(mpg > input$efficiency))
vals <- reactiveValues()
observeEvent(mt_subset(), {
vals$keeprows <- rep(TRUE, nrow(mt_subset()), label = "TuProblem", quoted = FALSE)
})
output$plot1 <- renderPlot({
# Plot the kept and excluded points as two separate data sets
keep <- mt_subset()[ vals$keeprows, , drop = FALSE]
exclude <- mt_subset()[!vals$keeprows, , drop = FALSE]
ggplot(keep, aes(wt, mpg)) + geom_point() +
geom_smooth(method = lm, fullrange = TRUE, color = "black") +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25) +
coord_cartesian(xlim = c(1.5, 5.5), ylim = c(5,35))
})
observeEvent(input$plot1_click, {
res <- nearPoints(mt_subset(), input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
observeEvent(input$exclude_toggle, {
res <- brushedPoints(mt_subset(), input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
}
shinyApp(ui, server)

ggplot2 interaction - toggle points

Based on this question, I found a nice example to remove points from a plot using ggplot2.
My question now is: once I delete a data point I would like to get rid of it permanently. The way it works now, every time the brush covers a coordinate where a deleted point was, that point comes back in. Any thoughts?
Example:
library(ggplot2)
library(Cairo) # For nicer ggplot2 output when deployed on Linux
ui <- fluidPage(
fluidRow(
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click",
brush = brushOpts(
id = "plot1_brush"
)
),
actionButton("exclude_toggle", "Toggle points"),
actionButton("exclude_reset", "Reset")
)
)
)
server <- function(input, output) {
# For storing which rows have been excluded
vals <- reactiveValues(
keeprows = rep(TRUE, nrow(mtcars))
)
output$plot1 <- renderPlot({
# Plot the kept and excluded points as two separate data sets
keep <- mtcars[ vals$keeprows, , drop = FALSE]
exclude <- mtcars[!vals$keeprows, , drop = FALSE]
ggplot(keep, aes(wt, mpg)) + geom_point() +
geom_smooth(method = lm, fullrange = TRUE, color = "black") +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25) +
coord_cartesian(xlim = c(1.5, 5.5), ylim = c(5,35))
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
res <- nearPoints(mtcars, input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Toggle points that are brushed, when button is clicked
observeEvent(input$exclude_toggle, {
res <- brushedPoints(mtcars, input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Reset all points
observeEvent(input$exclude_reset, {
vals$keeprows <- rep(TRUE, nrow(mtcars))
})
}
shinyApp(ui, server)

Trouble using zoom on ggplot2 shiny

I'm new here as a user but I have searched like crazy for a problem I have encountered while trying to create a data visualization app with shiny in Rstudio.
The thing is, I want to read a .csv, understand it's columns, select wich column I want as x and as y axis, plot them with the type of graph I have chosen and be able to zoom in in a secondary plot whenever I want.
I'm almost there, the thing is that the zoom with brush that I have tried to do is no working properly. It doesn't understand the values of the axis correctly, instead it works as if both axis where only from 0 to 1, and then zoom in the correct way but with the wrong xlim and ylim.
Here is my ui.R:
library(shiny)
library(ggplot2)
base = read.csv("TESTE.csv", sep = ";")
tipos <- c("Dispersão", "Histograma", "Boxplot", "Área")
shinyUI(fluidPage(
titlePanel("MGM"),
sidebarLayout(
sidebarPanel(
selectInput("selectedColX", "Select colum for X axis", choices = colnames(base), selected = colnames(base)[7]),
selectInput("selectedColY", "Select colum for Y axis", choices = colnames(base), selected = colnames(base)[4]),
selectInput("selectedColor", "Select colum for colour axis", choices = colnames(base), selected = colnames(base)[6]),
selectInput("seletedGraph", "Select type of graph", choices = tipos, selected = tipos[1])
),
fluidRow(
column(width = 12, class = "well",
h4("Left plot controls right plot"),
fluidRow(
column(width = 10,
plotOutput("Disp", height = 300,
brush = brushOpts(
id = "Disp_brush",
clip = TRUE,
resetOnNew = TRUE
)
)
),
column(width = 10,
plotOutput("DispZoom", height = 300)
)
)
)
)
# mainPanel(
#
# plotOutput("Hist"),
# plotOutput("Box"),
# plotOutput("Ar")
# )
)
))
And then my Server.R:
library(shiny)
library(ggplot2)
base = read.csv("TESTE.csv", sep = ";")
tipos <- c("Dispersão", "Histograma", "Boxplot", "Área")
shinyServer(function(input, output) {
output$Disp <- renderPlot({
validate(need(input$seletedGraph=="Dispersão", message=FALSE))
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis))
gg <- gg + geom_point()
plot(gg)
})
ranges2 <- reactiveValues(x = NULL, y = NULL)
output$DispZoom <- renderPlot({
validate(need(input$seletedGraph=="Dispersão", message=FALSE))
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis)) + geom_point() + coord_cartesian(xlim = ranges2$x, ylim = ranges2$y)
plot(gg)
})
output$Hist <- renderPlot({
validate(need(input$seletedGraph=="Histograma", message=FALSE))
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis))
gg <- gg + geom_histogram()
gg
})
output$Box <- renderPlot({
validate(need(input$seletedGraph=="Boxplot", message=FALSE))
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis))
gg <- gg + geom_boxplot()
gg
})
output$Ar <- renderPlot({
validate(need(input$seletedGraph=="Área", message=FALSE))
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis))
gg <- gg + geom_area()
gg
})
observe({
brush <- input$Disp_brush
if (!is.null(brush)) {
ranges2$x <- c(brush$xmin, brush$xmax)
ranges2$y <- c(brush$ymin, brush$ymax)
} else {
ranges2$x <- NULL
ranges2$y <- NULL
}
})
})
Just ignore the other plots that are not the geom_point. As soon as I get this one working the others should work just fine, I guess...
Thank you so much, I'm having such a pain trying to figure this out!
Some texts are in portuguese, but I think everything is understandable enough.
Your brushed points are on scale from 0 to 1 in the brushOpts because you print or plot your variable instead of just returning it.
1. Short desmonstration
This short app show the difference between the brushed points scales according to how it has been returned.
library(shiny)
ui <- fluidPage(
fluidRow(
column(6,
# My plot rendering with print or plot
h4("Plot with print or plot variable"),
plotOutput("plot1", height = 300, brush = brushOpts(id = "plot1_brush", clip = TRUE, resetOnNew = TRUE)),
p(),
# Brushed points
"Brushed points informations, scale from 0 to 1",
verbatimTextOutput("brush1")
),
column(6,
# My plot rendering without print or plot
h4("Plot with a return variable"),
plotOutput("plot2", height = 300, brush = brushOpts(id = "plot2_brush", clip = TRUE, resetOnNew = TRUE)),
p(),
# Brushed points
"Brushed points informations, scale according to x and y variables",
verbatimTextOutput("brush2")
)
)
)
server <- function(input, output) {
data <- iris
# Plot1 I render with print or plot
output$plot1 <- renderPlot({
gg <- ggplot(data, aes(x = Sepal.Length, y = Petal.Length, color = Species)) + geom_point()
plot(gg)
})
# Brush points from plot1
output$brush1 <- renderPrint({
input$plot1_brush
})
# Plot2 I render just returning the variable
output$plot2 <- renderPlot({
gg <- ggplot(data, aes(x = Sepal.Length, y = Petal.Length, color = Species)) + geom_point()
return(gg)
})
# Brush points from plot2
output$brush2 <- renderPrint({
input$plot2_brush
})
}
shinyApp(ui = ui, server = server)
2. Reproductible example from your question
Herebelow I made a reproductible example using the iris dataset.
Also, I changed some characters because of accents.
ui.R
library(shiny)
library(ggplot2)
shinyUI(fluidPage(
titlePanel("MGM"),
sidebarLayout(
sidebarPanel(
uiOutput("plots_parameters")
),
mainPanel(
fluidRow(
column(12,
h4("Plot without zoom"),
plotOutput("Disp", height = 300, brush = brushOpts(id = "Disp_brush", clip = TRUE, resetOnNew = TRUE))
)
),
fluidRow(
column(12,
h4("Zoomed plot"),
plotOutput("DispZoom", height = 300)
)
)
)
)
))
server.R
library(shiny)
library(ggplot2)
base = iris
shinyServer(function(input, output) {
output$plots_parameters <- renderUI({
tipos <- c("Dispersao", "Histograma", "Boxplot", "Área")
choices <- colnames(base)
div(
selectInput("selectedColX", "Select colum for X axis", choices = choices, selected = "Sepal.Length"),
selectInput("selectedColY", "Select colum for Y axis", choices = choices, selected = "Petal.Length"),
selectInput("selectedColor", "Select colum for colour axis", choices = choices, selected = "Species"),
selectInput("seletedGraph", "Select type of graph", choices = tipos, selected = "Dispersao")
)
})
output$Disp <- renderPlot({
req(input$seletedGraph == "Dispersao")
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis))
gg <- gg + geom_point()
# Return variable without print or plot
gg
})
ranges2 <- reactiveValues(x = NULL, y = NULL)
output$DispZoom <- renderPlot({
req(input$seletedGraph == "Dispersao")
y_axis <- input$selectedColY
x_axis <- input$selectedColX
color_axis <- input$selectedColor
gg <- ggplot(base, aes_string(x = x_axis, y = y_axis, color = color_axis)) + geom_point() +
coord_cartesian(xlim = ranges2$x, ylim = ranges2$y)
# Return variable without print or plot
gg
})
observe({
brush <- input$Disp_brush
if (!is.null(brush)) {
ranges2$x <- c(brush$xmin, brush$xmax)
ranges2$y <- c(brush$ymin, brush$ymax)
} else {
ranges2$x <- NULL
ranges2$y <- NULL
}
})
})

Resources