Change Plotly Chart Y Variable Based on Selectinput

How to make a plotly chart of variables selected by a user in shiny or flexdahsboard?

There are several approaches to make this work. Unfortunaetly your approach using noquote does not work.

  1. Probably the simplest approach would be to extract the columns from your df and pass them to plotly as vectors, e.g. x = df[[input$x]]
  2. As the plotly API works with one-sided formula a second approach would be to pass the variables as formulas, e.g. x = as.formula(paste0("~", input$x))
  3. Following this post you can also make use of base::get, e.g. x = ~get(input$x)
  4. Following this post you can also make use of tidy evaluation

All four approaches are illustrated in the following example flexdashboard:

---
title: "Plotly"
output: flexdashboard::flex_dashboard
runtime: shiny
---

```{r}
library(plotly)
library(rlang)
```

```{r global, include=FALSE}
# load data in 'global' chunk so it can be shared by all users of the dashboard
df <- data.frame("Timestamp.Excel_1900." = c("2019-04-01 16:52:51","2019-04-01 16:57:46","2019-04-01 17:02:51","2019-04-01 17:07:46","2019-04-01 17:12:52","2019-04-01 17:17:46"), "Temperature.C."= c(5.2995,5.3155,5.3353,5.3536,5.3770,5.4044), "pH.pH."= c(7.60,7.80,7.96,8.04, 8.09, 8.14))

```

Column {.sidebar}
-----------------------------------------------------------------------

```{r}
selectInput("x",
"x",
choices = names(df),
selected = "Timestamp.Excel_1900."
)
selectizeInput("y",
"y",
choices = names(df),
selected = c("Temperature.C.", "pH.pH."),
multiple = TRUE,
options = list(maxItems = 2)
)
```

Column
-----------------------------------------------------------------------

```{r}
# Pass the data columns as vectors
renderPlotly({
if (length(input$y) == 2) {
x1 <- df[[input$x]]
y1 <- df[[input$y[1]]]
y2 <- df[[input$y[2]]]

plot_ly() %>%
add_lines(x = x1, y = y1, name = "Red") %>%
add_lines(x = x1, y = y2, name = "Green")
}
})
```

```{r}
# One-sided formulas
renderPlotly({
if (length(input$y) == 2) {
x1 <- input$x
y1 <- input$y[1]
y2 <- input$y[2]

plot_ly(df) %>%
add_lines(x = as.formula(paste("~", x1)), y = as.formula(paste("~", y1)), name = "Red") %>%
add_lines(x = as.formula(paste("~", x1)), y = as.formula(paste("~", y2)), name = "Green")
}
})
```

Column
-----------------------------------------------------------------------

```{r}
# Using base::get
renderPlotly({
if (length(input$y) == 2) {
x1 <- input$x
y1 <- input$y[1]
y2 <- input$y[2]

plot_ly(df) %>%
add_lines(x = ~ get(x1), y = ~ get(y1), name = "Red") %>%
add_lines(x = ~ get(x1), y = ~ get(y2), name = "Green")
}
})
```

```{r}
# Using tidy evaluation
renderPlotly({
if (length(input$y) == 2) {
x1 <- input$x
y1 <- input$y[1]
y2 <- input$y[2]

eval_tidy(
quo_squash(
quo({
plot_ly(df) %>%
add_lines(x = ~ !!sym(x1), y = ~ !!sym(y1), name = "Red") %>%
add_lines(x = ~ !!sym(x1), y = ~ !!sym(y2), name = "Green")
})
)
)
}
})
```

Sample Image

Passing variable name to user-defined function that makes a plotly chart

When you call your function, you have to use real objects or strings. In other words, you have to pass the column names as strings.

From there you run into another issue. Once you make the column names strings Plotly will not connect columns to the SharedData object without additional intervention.

Since I don't think you want the parameter name as the axes' labels, I added labels, as well.

Here is what you can do to make this work.

make_bar_chart <- function(shared_data, xvar, yvar){
plot_ly(data = shared_data,
hoverinfo = "none") %>%
add_trace(
x = ~.data[[xvar]], # <- tell plotly 'connect to the data object!'
y = ~.data[[yvar]], # <- here, too
type = "bar",
transforms = list(
list(
type = "aggregate",
groups = ~.data[[yvar]], # <- here, too
aggregations = list(
list(
target = "x", func = "avg", enabled = T))))
) %>%
layout(xaxis = list(title = xvar),
yaxis = list(title = yvar))
}
# pass non-environment variables as strings
make_bar_chart(bar_data_shared, "pct_increase", "category")

Sample Image

selectInput and reactive Plotly bar chart in Shiny

You can use get() to convert your variable to something plotly can work with. Also note that you need to do color = ~areas instead of color = areas, otherwise plotly will try and use the object 'areas', which does not exist. A working example:

library(shiny)

server <- function(input, output){

#Data
Experiment <- data.frame(May = c(23,32,34,39,75), June = c(56,23,45,16,76), areas = c("ABD","MAG","DBU","MBSC","PSO"))

# Plotly bar chart
output$Test2 <- renderPlotly({
Test2 <- plot_ly(
Experiment, x = ~areas, y = ~get(input$select), type = "bar", color = ~areas)
})
}

ui <- shinyUI(fluidPage(
plotlyOutput("Test2", height = "600px"),
selectInput("select", "Select", label = h1("Selection Pane"),choices = list(May = "May", June = "June"))
)
)

shinyApp(ui,server)

Hope this helps!
Sample Image

Change chart based on selectinput value in R

I have create the following solution:

ui.R

tabItem(tabName = "sunbrust",
h2("Sunbrust Visualization"),
fluidRow(
#column(10, align="center",
# sunburstOutput("sunburst", width = "1200", height = "1200")

box(
uiOutput("sunburst_auswahl_links"),
sunburstOutput("sunburst", width = "1200", height = "1200")),

box(
uiOutput("sunburst_auswahl_rechts"),
sunburstOutput("sunburst2", width = "1200", height = "1200"))

)

server.R

  output$sunburst_auswahl_links <- renderUI({
selectInput("auswahl_sunburst_links", "Model Auswahl:", c(1,2,3))
})

sunbrylinks <- reactive({sunburst(datapielist[as.integer(input$auswahl_sunburst_links)][[1]], count = TRUE, legend = list(w = 150,h = 50, s = 15 , t = 1 ), breadcrumb = list(w = 150,h = 75, s = 15 , t = 10))})

output$sunburst <- renderSunburst({sunbrylinks()})

output$sunburst_auswahl_rechts <- renderUI({
selectInput("auswahl_sunburst_rechts", "Model Auswahl:", c(1,2,3))
})

sunbryrechts <- reactive({sunburst(datapielist[as.integer(input$auswahl_sunburst_rechts)][[1]], count = TRUE, legend = list(w = 150,h = 50, s = 15 , t = 1 ), breadcrumb = list(w = 150,h = 75, s = 15 , t = 10))})

output$sunburst2 <- renderSunburst({sunbryrechts()})

Selecting axis variable from selectInput() is not being read as numeric from plotly

You can use get() like this:

    fig <- plot_ly(su, type = 'scatter', mode = 'lines')%>%
add_trace(x = ~WaterYear, y = ~get(input$SEL), name = as.character(input$SEL))%>%
layout(showlegend = F)

How to create a barchart with plotly?

You can use get() to convert your input variable to something that plotly can work with. In your case try this:

 output$bar <- renderPlotly(
mtcars %>%
plot_ly(
x = ~get(input$input1),
y = ~get(input$input2),

type = "bar"
)


Related Topics



Leave a reply



Submit