rticles icon indicating copy to clipboard operation
rticles copied to clipboard

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

Open Masonavic opened this issue 3 years ago • 15 comments

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:

  • Two columns wide
  • 4 sub-figures in 2x2 layout
  • Two images, two R-generated plots

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

  • [x] I have fully read the issue guide at https://yihui.name/issue/.
  • [x] I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('rticles'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('rstudio/rticles').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

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

Masonavic avatar Apr 14 '21 19:04 Masonavic

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:

  • patchwork, but it is for ggplot only I think https://patchwork.data-imaginist.com/
  • cowplot is the same I guess : https://wilkelab.org/cowplot/
  • gridExtra is more generic to arrange plot in a grid https://cran.r-project.org/web/packages/gridExtra/

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.

cderv avatar Apr 21 '21 16:04 cderv

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?

Masonavic avatar Apr 21 '21 17:04 Masonavic

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 👋

cderv avatar Apr 21 '21 18:04 cderv

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?

Masonavic avatar Apr 21 '21 18:04 Masonavic

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

  • remove graphics: true in the YAML
  • add graphicx as an extra deps
output: 
  rticles::ieee_article:
    extra_dependencies: ["subfig", "graphicx"]

Does that work for you ?

cderv avatar Apr 22 '21 13:04 cderv

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.

DunLug avatar Apr 22 '21 14:04 DunLug

@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

Masonavic avatar Apr 22 '21 16:04 Masonavic

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

Example used
---
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: [email protected]
      mark: 1
      author:
        - name: Michael Shell
    - name: Twentieth Century Fox
      location: Springfield, USA
      mark: 2
      author:
        - name: Homer Simpson
          email: [email protected]
    - 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: [email protected]
        - name: Roy Batty
          email: [email protected]
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
=============
<!-- no \IEEEPARstart -->
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.
<!-- You must have at least 2 lines in the paragraph with the drop letter
(should never be an issue) -->
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.

<!-- conference papers do not normally have an appendix -->

Acknowledgment {#acknowledgment}
==============

The authors would like to thank...

Bibliography styles
===================

Here are two sample references: @Feynman1963118 [@Dirac1953888].

\newpage
References {#references .numbered}
==========

image

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

cderv avatar Apr 22 '21 16:04 cderv

@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?

Masonavic avatar Apr 22 '21 16:04 Masonavic

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

cderv avatar Apr 22 '21 16:04 cderv

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

Masonavic avatar Apr 22 '21 16:04 Masonavic

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 ?

cderv avatar Apr 22 '21 16:04 cderv

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?

Masonavic avatar Apr 22 '21 16:04 Masonavic

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

cderv avatar Apr 27 '21 12:04 cderv

Thanks for your help @cderv !

Masonavic avatar Apr 27 '21 15:04 Masonavic