Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centering incomplete when using subfig in markdown with out.width < "100%" #2518

Closed
slrellison opened this issue Sep 18, 2023 · 6 comments
Closed
Assignees

Comments

@slrellison
Copy link

slrellison commented Sep 18, 2023

Using subfig as in bookdown 6.6, with fig.ncol=1, fig.align="center" and out.width="80%" (for example), the final subfigure is not aligned with previous figures.

Inspection of the LaTeX shows that this is due to a missing \newline after the final subfigure; inserting it manually in the LaTeX output corrects the alignment.

Reprex based on section 6.6 example:

---
output: 
  pdf_document:
    extra_dependencies: "subfig"
    keep_tex: yes
---

```{r, fig.cap='Figure 1', fig.dim=c(7,3), fig.ncol=1, fig.align = "center", out.width="80%", fig.cap="Minimal example; note the misalignment of (c) on compilation to pdf", fig.subcap=c('First', 'Second', 'Third')}
plot(1:10)
plot(cars, pch = 19)
boxplot(Sepal.Width ~ Species, data = iris)
```


Session info:

xfun::session_info('rmarkdown')
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045), RStudio 2023.6.1.524

Locale:
LC_COLLATE=English_United Kingdom.utf8 LC_CTYPE=English_United Kingdom.utf8
LC_MONETARY=English_United Kingdom.utf8 LC_NUMERIC=C
LC_TIME=English_United Kingdom.utf8

time zone: Europe/London
tzcode source: internal

Package version:
base64enc_0.1.3 bslib_0.5.1 cachem_1.0.8 cli_3.6.1
digest_0.6.33 ellipsis_0.3.2 evaluate_0.21 fastmap_1.1.1
fontawesome_0.5.2 fs_1.6.3 glue_1.6.2 graphics_4.3.1
grDevices_4.3.1 highr_0.10 htmltools_0.5.6 jquerylib_0.1.4
jsonlite_1.8.7 knitr_1.43 lifecycle_1.0.3 magrittr_2.0.3
memoise_2.0.1 methods_4.3.1 mime_0.12 R6_2.5.1
rappdirs_0.3.3 rlang_1.1.1 rmarkdown_2.24 sass_0.4.7
stats_4.3.1 stringi_1.7.12 stringr_1.5.0 tinytex_0.46
tools_4.3.1 utils_4.3.1 vctrs_0.6.3 xfun_0.40
yaml_2.3.7

Pandoc version: 3.1.1


  • [YES ] installed and tested your bug with the development version of the rmarkdown package using remotes::install_github("rstudio/rmarkdown")?
    [Checked after initial session Info above]
@cderv
Copy link
Collaborator

cderv commented Oct 3, 2023

Inspection of the LaTeX shows that this is due to a missing \newline after the final subfigure; inserting it manually in the LaTeX output corrects the alignment.

Can you share exactly where the new line should be inserted ? You can show the LaTeX code produced and what it should be for it work for this \begin{figure} block.

Thank you

@cderv
Copy link
Collaborator

cderv commented Oct 3, 2023

I think I understand where you expect it to be...

It should be there:

\begin{figure}

{\centering \subfloat[First\label{fig:unnamed-chunk-1-1}]{\includegraphics[width=0.8\linewidth]{test_files/figure-latex/unnamed-chunk-1-1} }\newline\subfloat[Second\label{fig:unnamed-chunk-1-2}]{\includegraphics[width=0.8\linewidth]{test_files/figure-latex/unnamed-chunk-1-2} }\newline\subfloat[Third\label{fig:unnamed-chunk-1-3}]{\includegraphics[width=0.8\linewidth]{test_files/figure-latex/unnamed-chunk-1-3} }\newline

}

\caption{Minimal example; note the misalignment of (c) on compilation to pdf}\label{fig:unnamed-chunk-1}
\end{figure}

Those figures separators are introduced by knitr directly with its hook for plots in tex file. It will create a default fig.sep to put between the plots.

First, note that you can override the default using fig.sep chunk options. By adding a vector of the length of the plot (i.e fig.sep = rep("\\newline", 3), you'll get the result you want

---
output: 
  pdf_document:
    extra_dependencies: "subfig"
    keep_tex: true
    keep_md: true
---

```{r, fig.cap='Figure 1', fig.dim=c(7,3), fig.ncol=1, fig.align = "center", out.width="80%", fig.cap="Minimal example; note the misalignment of (c) on compilation to pdf", fig.subcap=c('First', 'Second', 'Third'), fig.sep = rep("\\newline", 3)}
plot(1:10)
plot(cars, pch = 19)
boxplot(Sepal.Width ~ Species, data = iris)
```

Our current default in knitr is to add \\newline by default except for last one
https://github.com/cderv/knitr/blob/7bc8b393e261c88f299bccc7eee40b4e952ebd57/R/hooks-latex.R#L78-L84

  fig.num = options$fig.num %n% 1L
  animate = options$fig.show == 'animate'
  fig.ncol = options$fig.ncol %n% fig.num
  if (is.null(fig.sep <- options$fig.sep)) {
    fig.sep = character(fig.num)
    if (fig.ncol < fig.num) fig.sep[seq(fig.ncol, fig.num - 1L, fig.ncol)] = '\\newline'
  }

I think we do that for fig.ncol to work as it should. Try more figures and fig.ncol more than 1 and it seems to work, without this last \newline

@yihui do you remember why seq(fig.ncol, fig.num - 1L, fig.ncol) ?
Should we consider a specific edge case of fig.ncol = 1 to have a new.line ?

I'll let you move to knitr if we consider more than providing fig.sep explicitly.

@yihui
Copy link
Member

yihui commented Oct 11, 2023

do you remember why seq(fig.ncol, fig.num - 1L, fig.ncol) ?

I don't remember. Perhaps I thought it was unnecessary to add \newline after the last figure since there's nothing after it.

Should we consider a specific edge case of fig.ncol = 1 to have a new.line ?

The special case is not only for fig.ncol = 1, but when fig.num is a multiple of fig.ncol. I just pushed a fix. @slrellison You can either follow @cderv's suggestion above (to specify fig.sep manually), or install the development version of knitr via

remotes::install_github('yihui/knitr')

@cderv
Copy link
Collaborator

cderv commented Oct 11, 2023

Thank you !

@slrellison
Copy link
Author

Thank you all! This is why I like Open Source !

clrpackages pushed a commit to clearlinux-pkgs/R-knitr that referenced this issue Oct 30, 2023
Christophe Dervieux (4):
      escape `fig.alt` for HTML output (#2291)
      close #2295: use a warning instead of an error for `opts_current` locking (#2296)
      Improve convert_chunk_header() for YAML options (#2300)
      Probably need to use the higher dependency gridSVG that requires XML not available on R 3.6.0

Pedro Faria (1):
      close #2226: add an error handler to improve YAML error message (#2294)

Yihui Xie (12):
      start the next version
      give users the key to unlock opts_current in the error message (yihui/knitr#1798)
      simplify this clumsy decade-old JS code
      the new version of papaja is on CRAN now: crsh/papaja#566
      fix #2288: preserve the minus sign when formatting negative numbers -10^n
      revise c1c9a5766a632fcb535fc432c7be401cba965c22 and ca7172752b6a3b4a5d2d9492e21844adad20198d: just don't use simple progress bars in RStudio, no matter where they are
      lingglosses v0.0.7 is on CRAN
      fix rstudio/rmarkdown#2518: when fig.num is a multiple of fig.ncol, add \newline to the last subfigure
      restore `opts_current` after each code chunk, and also after `knit()` exits (#2292)
      fix #2302: wrap figure output in raw latex blocks for Markdown output (#2303)
      revert 4307aedad27ec04defa35bf21d578feecd10665e and fix #2302 by escaping % instead
      CRAN release v1.45
Copy link

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

3 participants