Hi, I met the same error, and came here after googling.
For future reference, below I write the reason and workarounds I found for my case.
In my case, the reason is I gave multiple elements in a vector as an argument of xlab (and ylab) of ggplot2.
ggplot2 does not complain anything and silently processes successfully the first element in the vector as the label as if a single value is given as a label, whereas ggplotly dies with this Error in if: the condition has length > 1 error which is originated in gg2list.
My first quick workaround is to add unique() to the arguments of xlab and ylab. Also in my case the labels are indeed coming from input values, so I can simply replace them to the input values.
A reprex is as below. I also put my two ways of fix below by the ways as described above.
library(shiny)
library(ggplot2)
library(plotly)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# UI Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
ui <- fluidPage(
selectInput("label_x", "My label for x-axis", c('my own1', 'my own2')),
h4("Plot by ggplotly"),
# plotlyOutput("ggplotly_ok_wo_xlab"),
plotlyOutput("ggplotly_notok"),
# plotlyOutput("ggplotly_ok_way1"),
# plotlyOutput("ggplotly_ok_way2"),
h4("Plot by ggplot"),
plotOutput("ggplot")
)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# Server Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
server <- function(input, output, session) {
# Construction of ggplot object g is the same in both output$ggplot and output$ggplotly_notok.
# Still, ggplot is ok whereas ggplotly_notok dies with message 'Error in if: the condition has length > 1'.
output$ggplot <- renderPlot({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
# not necessarily the same length as the n_row of data:
# xlabs_my <- rep(label_x, 3)
# indeed `ggplot` silently picks up the first element even when different values are given:
# xlabs_my <- c('my1', 'my 2')
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlabs_my))
g
})
output$ggplotly_ok_way1 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
output$ggplotly_ok_way2 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
# xlabs_my <- rep(label_x, dim(faithful)[1])
xlab_my <- paste0('(which is taken directly from input): ', label_x)
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlab_my))
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
# Construction of ggplot object g is the same in both output$ggplot and output$ggplotly_notok.
# Still, ggplot is ok whereas ggplotly_notok dies with message 'Error in if: the condition has length > 1'.
output$ggplotly_notok <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
# output$ggplotly_ok_wo_xlab, which is without the part of xlab addition, works fine.
output$ggplotly_ok_wo_xlab <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
# g <- g +
# # xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
# print(ggplot2::last_plot())
ggplotly(g)
})
# stat_density_2d(aes(fill = ..level..), geom = "polygon") +
# Warning: The dot-dot notation (`..level..`) was deprecated in ggplot2 3.4.0.
# ℹ Please use `after_stat(level)` instead.
# ℹ The deprecated feature was likely used in the ggplot2 package.
# Please report the issue at <https://github.com/tidyverse/ggplot2/issues>.
}
# Run the application
shinyApp(ui = ui, server = server)
- The error message with the above
app.R
Warning: Error in if: the condition has length > 1
104: gg2list
103: ggplotly.ggplot
101: renderPlotly [<mytopdir>/app.R#113]
100: func
97: shinyRenderWidget
96: func
83: renderFunc
82: output$ggplotly_notok
1: shiny::runApp
- Workaround 1, use
unique()
library(shiny)
library(ggplot2)
library(plotly)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# UI Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
ui <- fluidPage(
selectInput("label_x", "My label for x-axis", c('my own1', 'my own2')),
h4("Plot by ggplotly"),
# plotlyOutput("ggplotly_notok"),
plotlyOutput("ggplotly_ok_way1"),
# plotlyOutput("ggplotly_ok_way2"),
h4("Plot by ggplot"),
plotOutput("ggplot")
)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# Server Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
server <- function(input, output, session) {
output$ggplot <- renderPlot({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
# not necessarily the same length as the n_row of data:
# xlabs_my <- rep(label_x, 3)
# indeed `ggplot` silently picks up the first element even when different values are given:
# xlabs_my <- c('my1', 'my 2')
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlabs_my))
g
})
output$ggplotly_ok_way1 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
output$ggplotly_ok_way2 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
# xlabs_my <- rep(label_x, dim(faithful)[1])
xlab_my <- paste0('(which is taken directly from input): ', label_x)
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlab_my))
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
output$ggplotly_notok <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
# stat_density_2d(aes(fill = ..level..), geom = "polygon") +
# Warning: The dot-dot notation (`..level..`) was deprecated in ggplot2 3.4.0.
# ℹ Please use `after_stat(level)` instead.
# ℹ The deprecated feature was likely used in the ggplot2 package.
# Please report the issue at <https://github.com/tidyverse/ggplot2/issues>.
}
# Run the application
shinyApp(ui = ui, server = server)
- Workaround 2, taken from input
library(shiny)
library(ggplot2)
library(plotly)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# UI Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
ui <- fluidPage(
selectInput("label_x", "My label for x-axis", c('my own1', 'my own2')),
h4("Plot by ggplotly"),
# plotlyOutput("ggplotly_notok"),
# plotlyOutput("ggplotly_ok_way1"),
plotlyOutput("ggplotly_ok_way2"),
h4("Plot by ggplot"),
plotOutput("ggplot")
)
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# Server Side ----
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
server <- function(input, output, session) {
output$ggplot <- renderPlot({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
# not necessarily the same length as the n_row of data:
# xlabs_my <- rep(label_x, 3)
# indeed `ggplot` silently picks up the first element even when different values are given:
# xlabs_my <- c('my1', 'my 2')
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlabs_my))
g
})
output$ggplotly_ok_way1 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
output$ggplotly_ok_way2 <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
# xlabs_my <- rep(label_x, dim(faithful)[1])
xlab_my <- paste0('(which is taken directly from input): ', label_x)
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
xlab(paste0('my xlab is: ', xlab_my))
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
# xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
output$ggplotly_notok <- renderPlotly({
label_x <- input$label_x
# dim(faithful)
# [1] 272 2
xlabs_my <- rep(label_x, dim(faithful)[1])
g <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") +
xlim(1, 6) + ylim(40, 100)
g <- g +
# xlab(unique(paste0('my xlab is: ', xlabs_my)))
xlab(paste0('my xlab is: ', xlabs_my))
ggplotly(g)
})
# stat_density_2d(aes(fill = ..level..), geom = "polygon") +
# Warning: The dot-dot notation (`..level..`) was deprecated in ggplot2 3.4.0.
# ℹ Please use `after_stat(level)` instead.
# ℹ The deprecated feature was likely used in the ggplot2 package.
# Please report the issue at <https://github.com/tidyverse/ggplot2/issues>.
}
# Run the application
shinyApp(ui = ui, server = server)
> library(shiny)
>
> library(ggplot2)
> library(plotly)
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
> sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.4.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Asia/Tokyo
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] plotly_4.10.4 ggplot2_3.5.0 shiny_1.8.0
loaded via a namespace (and not attached):
[1] jsonlite_1.8.8 gtable_0.3.4 dplyr_1.1.4 compiler_4.3.2 promises_1.2.1 tidyselect_1.2.0
[7] Rcpp_1.0.12 tidyr_1.3.1 later_1.3.2 scales_1.3.0 fastmap_1.1.1 mime_0.12
[13] R6_2.5.1 labeling_0.4.3 generics_0.1.3 isoband_0.2.7 htmlwidgets_1.6.4 MASS_7.3-60.0.1
[19] tibble_3.2.1 munsell_0.5.0 pillar_1.9.0 rlang_1.1.3 utf8_1.2.4 httpuv_1.6.14
[25] lazyeval_0.2.2 viridisLite_0.4.2 cli_3.6.2 withr_3.0.0 magrittr_2.0.3 digest_0.6.34
[31] grid_4.3.2 rstudioapi_0.15.0 xtable_1.8-4 lifecycle_1.0.4 vctrs_0.6.5 data.table_1.15.0
[37] glue_1.7.0 farver_2.1.1 fansi_1.0.6 colorspace_2.1-0 purrr_1.0.2 httr_1.4.7
[43] tools_4.3.2 pkgconfig_2.0.3 ellipsis_0.3.2 htmltools_0.5.7
>