Search code examples
rshinyplotlylatexr-plotly

R+plotly+Shiny: trouble with latex rendering


Please have a look at the code at the end of the post. It is a trivial shiny app which uses plotly to generate a histogram. I would like to use some latex syntax to label the x axis, but for some reason I see $n_1/(n_1+n_2)$ instead of the proper latex. Any idea about what goes wrong?

I try to follow the procedure at the links

https://plotly-r.com/mathjax.html

https://plotly.com/r/LaTeX/

But something does not work.

Any help is appreciated!

library(shiny)
library(plotly)
library(tidyverse)

set.seed(1234)

x <- runif(2000)

df_frag_norm <- tibble(n1_norm = x)

ui <- fluidPage(plotlyOutput("myplot1"))

server <- function(input, output) {
  output$myplot1 <- renderPlotly({
    fig <- plot_ly(
        df_frag_norm,
        x = ~ n1_norm,
        ## y = ~decessi_giornalieri,
        type = 'histogram',
        xbins = list(size = 0.05)
      ) %>%
      layout(bargap = 0.1,
             xaxis = list(
               range = c(0, 1),
               title = TeX("n_1/(n_1+n_2)")
             ))
    
    fig <- fig %>% config(mathjax = 'cdn')
  })
  
}

shinyApp(ui, server)

And here is the output from sessionInfo()

R version 4.1.3 (2022-03-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 11 (bullseye)

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.13.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8    
 [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] forcats_0.5.1   stringr_1.4.0   dplyr_1.0.8     purrr_0.3.4    
 [5] readr_2.1.2     tidyr_1.2.0     tibble_3.1.6    tidyverse_1.3.1
 [9] plotly_4.10.0   ggplot2_3.3.5   shiny_1.7.1    

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.8        lubridate_1.8.0   assertthat_0.2.1  digest_0.6.29    
 [5] utf8_1.2.2        mime_0.12         R6_2.5.1          cellranger_1.1.0 
 [9] backports_1.4.1   reprex_2.0.1      httr_1.4.2        pillar_1.7.0     
[13] rlang_1.0.2       lazyeval_0.2.2    readxl_1.3.1      rstudioapi_0.13  
[17] data.table_1.14.2 jquerylib_0.1.4   htmlwidgets_1.5.4 munsell_0.5.0    
[21] broom_0.7.12      compiler_4.1.3    httpuv_1.6.5      modelr_0.1.8     
[25] pkgconfig_2.0.3   htmltools_0.5.2   tidyselect_1.1.2  fansi_1.0.2      
[29] viridisLite_0.4.0 crayon_1.5.0      tzdb_0.2.0        dbplyr_2.1.1     
[33] withr_2.5.0       later_1.3.0       grid_4.1.3        jsonlite_1.8.0   
[37] xtable_1.8-4      gtable_0.3.0      lifecycle_1.0.1   DBI_1.1.2        
[41] magrittr_2.0.2    scales_1.1.1      cachem_1.0.6      cli_3.2.0        
[45] stringi_1.7.6     fs_1.5.2          promises_1.2.0.1  xml2_1.3.3       
[49] bslib_0.3.1       ellipsis_0.3.2    generics_0.1.2    vctrs_0.3.8      
[53] tools_4.1.3       glue_1.6.2        crosstalk_1.2.0   hms_1.1.1        
[57] fastmap_1.1.0     yaml_2.3.5        colorspace_2.0-3  rvest_1.0.2      
[61] haven_2.4.3       sass_0.4.0       

Solution

  • As explained in the docs of plotly::config(),

    IMPORTANT: plotly uses SVG-based mathjax rendering which doesn't play nicely with HTML-based rendering (e.g., rmarkdown documents and shiny apps).

    You can add withMathJax() in fluidPage to make this work. Note that you don't need config(mathjax = 'cdn') in this case.

    Code:

    library(shiny)
    library(plotly)
    library(tidyverse)
    
    set.seed(1234)
    
    x <- runif(2000)
    
    df_frag_norm <- tibble(n1_norm = x)
    
    ui <- fluidPage(
      withMathJax(),
      plotlyOutput("myplot1")
    )
    
    server <- function(input, output) {
      output$myplot1 <- renderPlotly({
        fig <- plot_ly(
            df_frag_norm,
            x = ~ n1_norm,
            ## y = ~decessi_giornalieri,
            type = 'histogram',
            xbins = list(size = 0.05)
          ) %>%
          layout(bargap = 0.1,
                 xaxis = list(
                   range = c(0, 1),
                   title = TeX("n_1/(n_1+n_2)")
                 ))
      })
      
    }
    
    shinyApp(ui, server)