rstudio / rticles

LaTeX Journal Article Templates for R Markdown
https://pkgs.rstudio.com/rticles/
1.46k stars 516 forks source link

IEEE Update graphicx handling in template for images in figures from code chunk #385

Open Masonavic opened 3 years ago

Masonavic commented 3 years ago

OK I think I've dotted all my i's and crossed my t's here but here it goes. I am trying to use the IEEE template. I want to have a figure that has the following characteristics:

What is the proper way to do this? Because there are R-generated graphics, the figure needs to be generated from a code chunk, so I cannot simply hard-code the LaTeX.

One of the basic problems with this, which seems to me to be a bug (or just lack of functionality?) is that I can't seem to use a code chunk to give me two images in a single figure. As instructed I posted this problem on a Stack Overflow post, that gives a minimum reproducible example (MRE) for the basic issue with images in a code chunk. This post has received nothing but "crickets" so I'm bringing it here.

I'm not including session_info at the moment because I'm honestly not sure if this is a bug or if this just doesn't work yet "as designed." If requested I can provide whatever information required but I imagine the phenomena described in the StackOverflow post is easily reproducible.


By filing an issue to this repo, I promise that

I understand that my issue may be closed if I don't fulfill my promises.

cderv commented 3 years ago

Hi,

Thanks for you patience.

Do you manage to do what you want with rmarkdown and pdf_document format ? Just trying to see if this is a specific rticles topic or just a general R Markdown question.

If you know how to do that with LaTeX code, feel free to share - because I don't.

Also just dropping this here, but it exists several packages to organize plot in a graphic device:

The above would work with several type of output.

As you are using rticles only here, maybe LaTeX subfigure are the way to go: https://bookdown.org/yihui/rmarkdown-cookbook/latex-subfigure.html

and this what you may be looking for.

Your example on SO give the expected result: include_graphics is vectorized but used to insert several figures in a document, not organize them like subfigure.

I let you read the above, and try with IEEE template. Please give me feedback, specifically if you still think there is an issue.

Masonavic commented 3 years ago

Hello,

Thanks for the response. I will respond to specific points inline:

Do you manage to do what you want with rmarkdown and pdf_document format ?

Well actually, I had to insert fig.show='hold', but then I got the expected behavior from a basic pdf_document RMarkdown. Inserting fig.show='hold' back into the IEEE rticles template gives the same result.

If you know how to do that with LaTeX code, feel free to share - because I don't.

As I show in the SO post, the LaTeX code that is part of the IEEE skeleton for a two-column figure is given as follows:

\begin{figure*}[!t]
\centering
\subfloat[Case I]{\includegraphics[width=2.5in]{box}%
\label{fig_first_case}}
\hfil
\subfloat[Case II]{\includegraphics[width=2.5in]{box}%
\label{fig_second_case}}
\caption{Simulation results for the network.}
\label{fig_sim}
\end{figure*}

One of the keys here as I understand it is the figure* environment that forces the figure to wrap over two columns.

As you are using rticles only here, maybe LaTeX subfigure are the way to go:

Yes, this was the path I had gone down previously, which I had not shared in the attempt to provide a minimum example of the problem... But here we go. So now in order to introduce subfigures I've changed the YAML for the output to read:

output: 
  rticles::ieee_article:
    extra_dependencies: "subfig"

And I've changed the code chunk to read:

```{r TestGraphic, fig.cap="Test", fig.subcap=c('1','2'), echo=F, fig.ncol = 2, out.width = "50%", fig.align = "center"}
knitr::include_graphics(c("Test1.jpg","Test2.jpg"))
```

Now, the produced LaTeX is:

 \begin{figure}
 {\centering \subfloat[1\label{fig:TestGraphic-1}]{\includegraphics[width=0.5\linewidth]{Test1} }\subfloat[2\label{fig:TestGraphic-2}]{\includegraphics[width=0.5\linewidth]{Test2} }
 }
 \caption{Test}\label{fig:TestGraphic}
 \end{figure}

Which looks more like the required LaTeX, but still throws the following error on knitting:

! Undefined control sequence.
<argument> \includegraphics 
                        [width=0.5\linewidth ]{Test1} 
l.527 ...udegraphics[width=0.5\linewidth]{Test1} }
                                                  \subfloat[2\label{fig:Test...

When I've tried to Google this issue it seems like it's related to something in the LaTeX package graphics vs graphicx being loaded... But presumably that's something rticles should handle?

cderv commented 3 years ago

Seems like graphicx is not loaded by default and you need to ask for it https://github.com/rstudio/rticles/blob/e894ed5f44caeef4a333fedaef4a5df7e60884d6/inst/rmarkdown/templates/ieee/resources/template.tex#L349-L350

The template was community contributed and it seems it is not documented in the skeleton.

Could you try adding

graphics: true

in the YAML ?

Also pinging ieee_article contributors for the expertise and insight on this: @Emaasit, @espinielli, @nathanweeks, @DunLug šŸ‘‹

Masonavic commented 3 years ago

Added the line for graphics: true. Now the error is:

! Argument of \Gin@iii has an extra }.
<inserted text> 
                \par 
l.537 ...udegraphics[width=0.5\linewidth]{Test1} }
                                                  \subfloat[2\label{fig:Test...

Which I've seen before in various explorations of this problem... In fact, I think this is as far as I've gotten with it.

EDIT: if I recall this might be some conflict with \subfloat and the way the template handles \includegraphics? Either way, think we're getting to "bug" territory here?

cderv commented 3 years ago

Ok I think there could be an issue with the template as this issue is usually when graphicx is not used.

Does that work for you ?

DunLug commented 3 years ago

Hi everyone, I don't know about the subfig package so I can't help you about it. The cleanest way to include multiple figures with columns span in my opinion is this one : First use the graphicx package using this inside the metadata part (begining of document)

header-includes:
  - \usepackage{graphicx}

I've tested the graphics options which also have issues on my side. It is possible that there is an issue when redefining the includegraphics command.

Then, add this chunk to the document :

```{r TestGraphic, echo=F, fig.env="figure*", fig.align="center", fig.show='hold', out.width="49%", fig.ncol=2, fig.cap=""}
library(ggplot2)
ggplot(mtcars, aes(x=mpg, y=cyl)) + geom_point()
ggplot(mtcars, aes(x=cyl, y=mpg)) + geom_point(color='red')
ggplot(mtcars, aes(x=mpg, y=cyl)) + geom_point()
ggplot(mtcars, aes(x=cyl, y=mpg)) + geom_point(color='red')
Ā ```

The fig.ncol specifies the amount of columns you want so there is a new line when there's more than 2 figures. The fig.env specifies the environment you want... when a figure environment is defined by knitr. It seems that knitr doesn't produce a figure environment by default so the fig.env is ignored. To avoid this issue, I've defined the fig.cap option which will add a caption. Because of this knitr is forced to add a figure environment with the one defined with fig.env.

Please test this and tell me if this is your desired result.

Masonavic commented 3 years ago

@cderv

I changed the YAML as indicated, same issue.

EDIT: see below I think I messed up something here, it works with the code below

cderv commented 3 years ago

Strange. I don't have an issue when using in the template.

Example used ````markdown --- title: Bare Demo of IEEEtran.cls for IEEE Conferences affiliation: institution-columnar: true ## one column per institution (multiple autors eventually) institution: - name: Georgia Institute of Technology department: School of Electrical and Computer Engineering location: Atlanta, Georgia 30332--0250 email: ece@datech.edu mark: 1 author: - name: Michael Shell - name: Twentieth Century Fox location: Springfield, USA mark: 2 author: - name: Homer Simpson email: homer@thesimpsons.com - name: Starfleet Academy location: San Francisco, California 96678-2391 other: "Telephone: (800) 555--1212, Fax: (888) 555--1212" mark: 3 author: - name: Montgomery Scott - name: Tyrell Inc. location: 123 Replicant Street, Los Angeles, USA 90210--4321 mark: 4 author: - name: Eldon Tyrell email: eldon@starfleet-academy.star - name: Roy Batty email: roy@replicant.offworld keywords: ["keyword 1", "keyword 2"] abstract: | The abstract goes here. On multiple lines eventually. with_amsmath: true bibliography: mybibfile.bib output: rticles::ieee_article: extra_dependencies: ["subfig", "graphicx"] --- Introduction ============= This demo file is intended to serve as a ``starter file'' for IEEE conference papers produced under \LaTeX\ using IEEEtran.cls version 1.8b and later. I wish you the best of success. ## Subsection Heading Here Subsection text here. ```{r TestGraphic, fig.cap="Test", fig.subcap=c('1','2'), echo=F, fig.ncol = 2, out.width = "50%", fig.align = "center"} plot(mtcars) plot(cars) ``` ### Subsubsection Heading Here Subsubsection text here. ```{r, include = FALSE} library(ggplot2) p1 <- ggplot(mtcars, aes(x=mpg, y=cyl)) + geom_point() p2 <- ggplot(mtcars, aes(x=cyl, y=mpg)) + geom_point(color='red') ggsave("plot1.png", p1) ggsave("plot2.png", p2) ``` ```{r TestGraphic2, fig.cap="Test", fig.subcap=c('1','2'), echo=F, fig.ncol = 2, out.width = "50%", fig.align = "center"} knitr::include_graphics(c("plot1.png","plot2.png")) ``` Conclusion ============ The conclusion goes here. Acknowledgment {#acknowledgment} ============== The authors would like to thank... Bibliography styles =================== Here are two sample references: @Feynman1963118 [@Dirac1953888]. \newpage References {#references .numbered} ========== ```` ![image](https://user-images.githubusercontent.com/6791940/115749975-f3c38b80-a397-11eb-9213-5e6ef7a56b50.png)

Thanks for your input @DunLug ! FWIWI, adding package name in extra_dependencies is the same a using the line in header-includes.

Masonavic commented 3 years ago

@DunLug

OK, I think it's finally working! My YAML customizations from the base template are:

output: 
  rticles::ieee_article:
    extra_dependencies: "subfig"

and

header-includes:
  - \usepackage{graphicx}

The code that you provided produces a nice 4x4 grid of graphics, albeit on the next page, which AFAIK is the expected behavior due to the figure* environment. Furthermore, I can have a code chunk:

```{r TestGraphic, echo=F, fig.env="figure*", fig.align="center", fig.show='hold', out.width="49%", fig.ncol=2, 
fig.cap='Test',fig.subcap=c('1st','2nd')}
knitr::include_graphics(c("Test1.jpg","Test2.jpg"))
```

And I get my two test images side by side, with captions. Previously, when using the figure environment text would run over the images, and when using figure* I couldn't resize images (they would run off the page). Now it seems to work, the key thing seems to be the header-includes: in the YAML.

So should this be introduced into the code by default?

cderv commented 3 years ago

Glad it works, forget my last answer then.

header-includes:
 - \usepackage{graphicx}

This should be the same if you do this

output: 
  rticles::ieee_article:
    extra_dependencies: ["graphicx", "subfig"]

is it ?

So should this be introduced into the code by default?

I think graphicx should be loaded by default maybe or that this part in the template should be fixed šŸ‘ https://github.com/rstudio/rticles/blob/e894ed5f44caeef4a333fedaef4a5df7e60884d6/inst/rmarkdown/templates/ieee/resources/template.tex#L349-L360

We need to check in the IEEE template how it is to update accordingly

Masonavic commented 3 years ago

@cderv Yes, actually, having it as part of extra-dependencies works as well.

cderv commented 3 years ago

Okay I am relieved !

So this is a matter of having graphicx package maybe loaded by default, or having a switch in YAML to do so because currently graphics: true is not working.

official template should be checked to adapt the one we have: https://journals.ieeeauthorcenter.ieee.org/create-your-ieee-journal-article/authoring-tools-and-templates/tools-for-ieee-authors/ieee-article-templates/

Not sure which IEEE .tex template to look at though ?

Masonavic commented 3 years ago

Not sure which IEEE .tex template to look at though ?

Yeah I'm not sure either, it seems like what they supply on that website is journal-specific... However, as I understand it they all have the common IEEEtran document class... Perhaps that can be used as a general template for journals or conference proceedings?

cderv commented 3 years ago

The part in question which cause an error was added 5 years ago by @Emaasit

$if(graphics)$
\usepackage{graphicx}
% We will generate all images so they have a width \maxwidth. This means
% that they will get their normal width if they fit onto the page, but
% are scaled down if they would overflow the margins.
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth
\else\Gin@nat@width\fi}
\makeatother
\let\Oldincludegraphics\includegraphics
\renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=\maxwidth]{#1}}
$endif$

I don't think this is part of a IEEE template

If anyone is willing to improve the IEEE template, feel free to open a PR for it. As users you may know what is working correctly or not.

@Emaasit, @espinielli, @nathanweeks, @DunLug were all the contributors for this template. I believe it first started as a template for a IEEE conference.

However, as I understand it they all have the common IEEEtran document class...

yes it seems so. Currently the cls file is included as a file in the resource folder and hte IEEE CTAN package is not used I think.

I'll rename the issue and add the label

Masonavic commented 3 years ago

Thanks for your help @cderv !