Wrapping caption text when it contains LaTeX

I've been trying to solve this for ages to no avail.

I like lengthy informative captions, but that means they need maths in and to be wrapped.

Here I've tried to use stringr::str_wrap and latex2exp::TeX - so far no luck. Anyone know how to do this?

# how do I add a long plot with latex commands into a plot?

library(tidyverse)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
#> Registered S3 method overwritten by 'rvest':
#>   method            from
#>   read_xml.response xml2
library(latex2exp)

# dummy parameters for the caption

trials <- 10
unequal_effect_ratio <- 1.2
measure <- "median"

# some text

caption_text <-  paste0(
    "a) These simulation results are summarised by the proportion, coverage, of ",
    trials,
    " confidence intervals that contain the true measure $\\nu$, or log-ratio $\\log(\\rho)$ of control $\\nu_C$ and intervention $\\nu_I$ measures, with $\\rho := \\nu_I/\\nu_C$.\n
The case where the control median $\\nu_C$ is equal to the intervention median $\\nu_I$ is considered, $\\rho= 1$, as is an unequal ratio, $\\rho =$ ",
    unequal_effect_ratio,
    ".\n Data for the control and intervention arms sampled from distributions in accompanying b) Distributions plot.\n
Summary statistics were calculated from the samples, for the estimator of the variance $\\mathcal{V}(m)$ of the sample ",
    measure,
    " $m$ or $m_C/m_I$.\n" 
  )

# a plot to try out the caption text
dummy_plot <- iris %>% ggplot(aes(x = Petal.Length)) + 
  geom_density() +
  facet_wrap(~ Species)

# here, of course, the TeX is not parsed
dummy_plot + labs(caption = caption_text)


# this wraps but latex is not parsed yet
dummy_plot + labs(caption = str_wrap(caption_text))


# some TeX works, but not wrapped
dummy_plot + labs(caption = TeX(caption_text))


# argh! wraps horror text
dummy_plot + labs(caption = str_wrap(TeX(caption_text)))
#> Warning in stri_split_lines(str): argument is not an atomic vector;
#> coercing


# doesn't wrap
dummy_plot + labs(caption = TeX(str_wrap(caption_text)))

Created on 2019-05-23 by the reprex package (v0.2.1)

Session info
devtools::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.6.0 (2019-04-26)
#>  os       Ubuntu 19.04                
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language en_AU:en                    
#>  collate  en_AU.UTF-8                 
#>  ctype    en_AU.UTF-8                 
#>  tz       Australia/Melbourne         
#>  date     2019-05-23                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version    date       lib
#>  assertthat    0.2.1      2019-03-21 [1]
#>  backports     1.1.4      2019-04-10 [1]
#>  broom         0.5.2      2019-04-07 [1]
#>  callr         3.2.0      2019-03-15 [1]
#>  cellranger    1.1.0      2016-07-27 [1]
#>  cli           1.1.0      2019-03-19 [1]
#>  colorspace    1.4-1      2019-03-18 [1]
#>  crayon        1.3.4      2017-09-16 [1]
#>  curl          3.3        2019-01-10 [1]
#>  desc          1.2.0      2018-05-01 [1]
#>  devtools      2.0.2      2019-04-08 [1]
#>  digest        0.6.19     2019-05-20 [1]
#>  dplyr       * 0.8.0.1    2019-02-15 [1]
#>  evaluate      0.13       2019-02-12 [1]
#>  forcats     * 0.4.0      2019-02-17 [1]
#>  fs            1.3.0      2019-05-02 [1]
#>  generics      0.0.2      2018-11-29 [1]
#>  ggplot2     * 3.1.1      2019-04-07 [1]
#>  glue          1.3.1      2019-03-12 [1]
#>  gtable        0.3.0      2019-03-25 [1]
#>  haven         2.1.0      2019-02-19 [1]
#>  highr         0.8        2019-03-20 [1]
#>  hms           0.4.2      2018-03-10 [1]
#>  htmltools     0.3.6      2017-04-28 [1]
#>  httr          1.4.0      2018-12-11 [1]
#>  jsonlite      1.6        2018-12-07 [1]
#>  knitr         1.23       2019-05-18 [1]
#>  labeling      0.3        2014-08-23 [1]
#>  latex2exp   * 0.4.0      2019-05-22 [1]
#>  lattice       0.20-38    2018-11-04 [4]
#>  lazyeval      0.2.2      2019-03-15 [1]
#>  lubridate     1.7.4      2018-04-11 [1]
#>  magrittr      1.5        2014-11-22 [1]
#>  memoise       1.1.0      2017-04-21 [1]
#>  mime          0.6        2018-10-05 [1]
#>  modelr        0.1.4      2019-02-18 [1]
#>  munsell       0.5.0      2018-06-12 [1]
#>  nlme          3.1-139    2019-04-09 [4]
#>  pillar        1.4.0      2019-05-11 [1]
#>  pkgbuild      1.0.3      2019-03-20 [1]
#>  pkgconfig     2.0.2      2018-08-16 [1]
#>  pkgload       1.0.2      2018-10-29 [1]
#>  plyr          1.8.4      2016-06-08 [1]
#>  prettyunits   1.0.2      2015-07-13 [1]
#>  processx      3.3.0      2019-03-10 [1]
#>  ps            1.3.0      2018-12-21 [1]
#>  purrr       * 0.3.2      2019-03-15 [1]
#>  R6            2.4.0      2019-02-14 [1]
#>  Rcpp          1.0.1      2019-03-17 [1]
#>  readr       * 1.3.1      2018-12-21 [1]
#>  readxl        1.3.1      2019-03-13 [1]
#>  remotes       2.0.4      2019-04-10 [1]
#>  rlang         0.3.4      2019-04-07 [1]
#>  rmarkdown     1.12       2019-03-14 [1]
#>  rprojroot     1.3-2      2018-01-03 [1]
#>  rvest         0.3.3      2019-04-11 [1]
#>  scales        1.0.0      2018-08-09 [1]
#>  sessioninfo   1.1.1      2018-11-05 [1]
#>  stringi       1.4.3      2019-03-12 [1]
#>  stringr     * 1.4.0      2019-02-10 [1]
#>  testthat      2.1.1.9000 2019-05-18 [1]
#>  tibble      * 2.1.1      2019-03-16 [1]
#>  tidyr       * 0.8.3      2019-03-01 [1]
#>  tidyselect    0.2.5      2018-10-11 [1]
#>  tidyverse   * 1.2.1      2017-11-14 [1]
#>  usethis       1.5.0      2019-04-07 [1]
#>  withr         2.1.2      2018-03-15 [1]
#>  xfun          0.7        2019-05-14 [1]
#>  xml2          1.2.0      2018-01-24 [1]
#>  yaml          2.2.0      2018-07-25 [1]
#>  source                                      
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  Github (stefano-meschiari/latex2exp@e39d46a)
#>  CRAN (R 3.5.1)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.5.3)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  Github (r-lib/testthat@4a546fa)             
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#>  CRAN (R 3.6.0)                              
#> 
#> [1] /home/charles/R/x86_64-pc-linux-gnu-library/3.6
#> [2] /usr/local/lib/R/site-library
#> [3] /usr/lib/R/site-library
#> [4] /usr/lib/R/library
1 Like

So, I'm thinking about the last example some more, and I'm wondering if going from str_wrap() to TeX() is causing problems. Having a look at the str_wrap() documentation, it actually outputs a vector of strings: one for each line. TeX() isn't going to like that on its own.

The examples in the docs suggest taking the str_wrap() output and piping it into cat('\n'), which would make sense in most contexts, but maybe not for TeX(). If you can work out how to do newlines at all with TeX(), maybe you can then go str_wrap() %>% cat() %>% TeX()?

EDIT: this latex2exp issue suggests that adding newlines to TeX() will be a pain but maybe not impossible (maybe you need some sort of recursive use of atop() for more than two lines?).

I haven't explored cowplot::draw_label(), though!

1 Like

If you want a wildly overengineered solution (and I'm all about wildly overengineered solutions), Paul Murrell presented work rendering arbitrary HTML as a grob that can be overlaid on a plot last year!

https://www.stat.auckland.ac.nz/~paul/Reports/HTML/layoutengine/layoutengine.html

I'm not sure if this system allows you to bring in additional JavaScript libraries, but if it does, (It does: use LayoutEngineDOM) You could bring in MathJax, write your caption in LaTeX and then let the HTML rendering handle the wrapping.

Downside? I'm not sure how well it'd go with substituting your parameters.; you'd have to bake those in before you send it to MathJax. Also, it might be difficult to implement in other parts of ggplot2 (eg. axis ticks or facet titles).

This is very much me shooting from the hip :stuck_out_tongue:

Oh I like this! Trying it now. - trying the first solution. :crossed_fingers: it's that simple.

It did not go so well :joy_cat:

1 Like

:rofl::joy:

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.