I am trying to keep the color scale and size scale of my plot constant, regardless of which points are actually displayed.
In ggplot
, I could set these constant using arguments like scale_color_gradient(limits=c(0,1))
. However, I cannot find a parallel function in plot_ly
and for other reasons, I cannot use ggplotly()
here.
I believe this can also be done with eventReactive()
but I'm having trouble understanding how to use it.
Here is a minimal example, where the plot color and size keep changing.
library(dplyr)
library(shiny)
library(plotly)
df <- as.data.frame(list("UserID"=c(1,1,1,1,2,2,2,2),
"Category"=c('A','A','B','B','A','A','B','B'),
"Rate"=c(2,3,5,6,8,6,7,1),
"x"=c(1,3,5,7,2,4,6,8),
"y"=c(1,3,5,7,2,4,6,8)
))
ui <- (fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("userInput","Select User", sort(unique(df$UserID)),
selected=1),
checkboxGroupInput("CategoryInput", "Select Category", sort(unique(df$Category)),
selected=c('A','B'))
),
mainPanel(
plotlyOutput("mainPlot")#,
)
)
))
server <- function(input, output, session) {
# filter for both user and category
filteredFull <- reactive({
df %>%
filter(
UserID == input$userInput,
Category %in% input$CategoryInput
)
})
output$mainPlot <- renderPlotly({
plot_ly(data=filteredFull(), x=x, y=y,
color=Rate, size=Rate,
mode='markers')
})
}
shinyApp(ui, server)
Is it possible to update only which points are displayed, without updating the scale/range of the color/size?
Plotly has those colorscale limits as well. They are nested under the marker attribute. You can set the color scales maximum and minimum values (numeric values) to leave the scale constant regardless which points are actually displayed.
I just added marker = list(cmin = 1, cmax = 8)
to the plot_ly
command. So you would have to scan your df
to determine which are your maximum and minimum values.
Code below:
library(dplyr)
library(shiny)
library(plotly)
df <- as.data.frame(list(
"UserID" = c(1, 1, 1, 1, 2, 2, 2, 2),
"Category" = c('A', 'A', 'B', 'B', 'A', 'A', 'B', 'B'),
"Rate" = c(2, 3, 5, 6, 8, 6, 7, 1),
"x" = c(1, 3, 5, 7, 2, 4, 6, 8),
"y" = c(1, 3, 5, 7, 2, 4, 6, 8)
))
ui <- (fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("userInput","Select User", sort(unique(df$UserID)), selected=1),
checkboxGroupInput("CategoryInput", "Select Category", sort(unique(df$Category)), selected=c('A','B'))
),
mainPanel(
plotlyOutput("mainPlot"),
plotlyOutput("mainPlotFixedSize")
)
)
))
server <- function(input, output, session) {
# filter for both user and category
filteredFull <- reactive({
df %>%
filter(
UserID == input$userInput,
Category %in% input$CategoryInput
)
})
output$mainPlot <- renderPlotly({
plot_ly(data=filteredFull(), x=x, y=y,
color=Rate, size=Rate,
mode='markers', marker = list(cmin = 1, cmax = 8))
})
output$mainPlotFixedSize <- renderPlotly({
plot_ly(data=filteredFull(), x=x, y=y,
color=Rate, mode='markers',
marker = list(sizemode = "area", size = Rate*3400, cmin = 1, cmax = 8))
})
}
shinyApp(ui, server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With