3

I use R and ggplot to create figures, which I then import as tikz code into my LaTeX file. The publisher wants me to submit in their template, which is based on [12pt]{article}. However, whenever I use the following code to export my ggplot2-figure, there is a small problem.

if (!require("pacman")) install.packages("pacman")
pacman::p_load( 'ggplot2', 'tikzDevice', 'tinytex')



trialfigure <- ggplot(mpg, aes(y = class)) +
  geom_bar(aes(fill = drv)) +
  scale_fill_discrete(labels = c("4" = "really long label")) +
  theme(legend.position = "bottom")

trialfigure
tikz('trialfigure.tex', width = 6.5, height = 4.875, sanitize = TRUE, documentDeclaration = "\\documentclass[12pt]{article}") 
print(trialfigure)
dev.off()    

In the LaTex Output from Overleaf, I feel like the fonts are too big, which can be seen as the "longish color legend" texts always interfere with the legend colors.

If I set my document to 10 points, everything works as expected.

I include the tikz-code as follows:

\documentclass[12pt,authoryear]{article}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage[utf8]{inputenc} % for easy quotation marks ""

%%%%% for the TIKZPictures
\makeatletter
\tikzset{dangerous style/.code={
    \tikzoption{clip}[]{\pgf@relevantforpicturesizefalse}
    \tikzoption{use as bounding box}[]{\pgf@relevantforpicturesizefalse}
    }
}
\makeatother
%%%%% for the TIKZPictures

\usepackage{graphicx}

\begin{document}

\begin{figure}[htbp!]
 
\centering
\resizebox{\textwidth}{!}{

% Created by tikzDevice version 0.12.3.1 on 2023-07-24 15:04:05
% !TEX encoding = UTF-8 Unicode
\begin{tikzpicture}[x=1pt,y=1pt]
\definecolor{fillColor}{RGB}{255,255,255}
\path[use as bounding box,fill=fillColor,fill opacity=0.00] (0,0) rectangle (469.75,352.32);
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{255,255,255}
\definecolor{fillColor}{RGB}{255,255,255}

\path[draw=drawColor,line width= 0.6pt,line join=round,line cap=round,fill=fillColor] (  0.00,  0.00) rectangle (469.75,352.32);
\end{scope}
\begin{scope}
\path[clip] ( 59.42, 67.12) rectangle (464.26,346.82);
\definecolor{fillColor}{gray}{0.92}

\path[fill=fillColor] ( 59.42, 67.12) rectangle (464.26,346.82);
\definecolor{drawColor}{RGB}{255,255,255}

\path[draw=drawColor,line width= 0.3pt,line join=round] (137.18, 67.12) --
    (137.18,346.82);

\path[draw=drawColor,line width= 0.3pt,line join=round] (255.90, 67.12) --
    (255.90,346.82);

\path[draw=drawColor,line width= 0.3pt,line join=round] (374.62, 67.12) --
    (374.62,346.82);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42, 90.42) --
    (464.26, 90.42);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,129.27) --
    (464.26,129.27);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,168.12) --
    (464.26,168.12);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,206.97) --
    (464.26,206.97);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,245.81) --
    (464.26,245.81);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,284.66) --
    (464.26,284.66);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 59.42,323.51) --
    (464.26,323.51);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 77.82, 67.12) --
    ( 77.82,346.82);

\path[draw=drawColor,line width= 0.6pt,line join=round] (196.54, 67.12) --
    (196.54,346.82);

\path[draw=drawColor,line width= 0.6pt,line join=round] (315.26, 67.12) --
    (315.26,346.82);

\path[draw=drawColor,line width= 0.6pt,line join=round] (433.98, 67.12) --
    (433.98,346.82);
\definecolor{fillColor}{RGB}{248,118,109}

\path[fill=fillColor] (285.58,111.79) rectangle (356.81,146.75);

\path[fill=fillColor] (303.39,150.64) rectangle (321.20,185.60);

\path[fill=fillColor] ( 77.82,228.33) rectangle (273.71,263.29);

\path[fill=fillColor] (261.84,267.18) rectangle (285.58,302.14);

\path[fill=fillColor] (143.12,306.03) rectangle (445.85,340.99);
\definecolor{fillColor}{RGB}{0,186,56}

\path[fill=fillColor] ( 77.82,111.79) rectangle (285.58,146.75);

\path[fill=fillColor] ( 77.82,150.64) rectangle (303.39,185.60);

\path[fill=fillColor] ( 77.82,189.49) rectangle (143.12,224.45);

\path[fill=fillColor] (131.24,267.18) rectangle (261.84,302.14);
\definecolor{fillColor}{RGB}{97,156,255}

\path[fill=fillColor] ( 77.82, 72.94) rectangle (107.50,107.91);

\path[fill=fillColor] ( 77.82,267.18) rectangle (131.24,302.14);

\path[fill=fillColor] ( 77.82,306.03) rectangle (143.12,340.99);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{gray}{0.30}

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47, 87.90) {2seater};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,126.75) {compact};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,165.59) {midsize};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,204.44) {minivan};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,243.29) {pickup};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,282.14) {subcompact};

\node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 54.47,320.98) {suv};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{gray}{0.20}

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67, 90.42) --
    ( 59.42, 90.42);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,129.27) --
    ( 59.42,129.27);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,168.12) --
    ( 59.42,168.12);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,206.97) --
    ( 59.42,206.97);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,245.81) --
    ( 59.42,245.81);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,284.66) --
    ( 59.42,284.66);

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 56.67,323.51) --
    ( 59.42,323.51);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{gray}{0.20}

\path[draw=drawColor,line width= 0.6pt,line join=round] ( 77.82, 64.37) --
    ( 77.82, 67.12);

\path[draw=drawColor,line width= 0.6pt,line join=round] (196.54, 64.37) --
    (196.54, 67.12);

\path[draw=drawColor,line width= 0.6pt,line join=round] (315.26, 64.37) --
    (315.26, 67.12);

\path[draw=drawColor,line width= 0.6pt,line join=round] (433.98, 64.37) --
    (433.98, 67.12);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{gray}{0.30}

\node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.73] at ( 77.82, 57.12) {0};

\node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.73] at (196.54, 57.12) {20};

\node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.73] at (315.26, 57.12) {40};

\node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.73] at (433.98, 57.12) {60};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.92] at (261.84, 46.63) {count};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  0.92] at ( 11.81,206.97) {class};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{RGB}{255,255,255}

\path[fill=fillColor] (178.83,  5.50) rectangle (344.84, 33.84);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale=  0.92] at (184.33, 16.52) {drv};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{gray}{0.95}

\path[fill=fillColor] (203.35, 11.00) rectangle (220.70, 28.34);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{RGB}{248,118,109}

\path[fill=fillColor] (204.06, 11.71) rectangle (219.99, 27.63);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{gray}{0.95}

\path[fill=fillColor] (283.04, 11.00) rectangle (300.38, 28.34);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{RGB}{0,186,56}

\path[fill=fillColor] (283.75, 11.71) rectangle (299.67, 27.63);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{gray}{0.95}

\path[fill=fillColor] (313.62, 11.00) rectangle (330.97, 28.34);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{fillColor}{RGB}{97,156,255}

\path[fill=fillColor] (314.33, 11.71) rectangle (330.26, 27.63);
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale=  0.73] at (226.20, 17.15) {really long label};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale=  0.73] at (305.88, 17.15) {f};
\end{scope}
\begin{scope}
\path[clip] (  0.00,  0.00) rectangle (469.75,352.32);
\definecolor{drawColor}{RGB}{0,0,0}

\node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale=  0.73] at (336.47, 17.15) {r};
\end{scope}
\end{tikzpicture}



 }
\caption{Some caption. The problem is in the "really long label".}
 \label{fig:someplotlabel}
\end{figure}


\end{document}

The problem with the figure is in the large label. And I do not want to alter the tikz code, please.

I am not sure, what I could do for a reproducible example, any tips are welcome.

Is there any way to solve my problem with the 12 pt font? - e.g., by defining all figures should be 10 pt?

4
  • Can you please add the missing lines, which are necessary? This code won't compile ... Thank you.
    – MS-SPO
    Jul 20 at 18:47
  • To show us a minimal example make a simple plot with ggplot and then show a minimal document which includes the generated TeX code that your \input command would input.
    – Alan Munn
    Jul 20 at 22:40
  • "what I could do for a reproducible example"? Easy: The simplest single file with .Rnw extension file in Rstudio (or .Rtex in Overleaf) compilable "as is", and of course, using the tizk device like here or here but centered in your issue and the simplicity, i.e., if you can show your font issue with a standard plot() and c(1,2,3) as plot data, do not use ggplot2 nor your large data frame were you are working on.
    – Fran
    Jul 21 at 9:14
  • I did include the MWE - however due to the whole generated TikZ code it is rather long. I prefered the old version with the input. Jul 24 at 13:37

1 Answer 1

5

Edit

(Complete rewrite of the original answer since the question show code that allow a better understanding of the issues.)

A) First, you have a problem with R code. It seems that you created a "document agnostic" tikz picture without the option standAlone=TRUE, so I guess that tikzDocumentDeclaration has no effect and the figure is calculated for the default (10pt). A tikz picture intended for 10pt in 12pt latex text can produce this label overflow.

But even making a standalone TeX document adding this option, the tuning of font metrics of tkiz seems to fail in this way (The R script below, make the wrong picture in 12pt document, the output of trialfigure.tex is included as figure 1 in the next MWE.Rnw):

The MWE.R script:

require(ggplot2)
require(tikzDevice)

options(tikzDocumentDeclaration = "\\documentclass[12pt]{article}")
    
trialfigure <- ggplot(mpg, aes(y = class)) +
  geom_bar(aes(fill = drv)) +
  scale_fill_discrete(labels = c("4" = "really long label")) +
  theme(legend.position = "bottom")

trialfigure
tikz('trialfigure.tex', 
     width = 6.5, height = 4.875, 
     standAlone=TRUE,
     sanitize = TRUE) 
print(trialfigure)
dev.off()    

Now you have a few alternatives to solve the issue:

  1. Do not ask me why, but change in the source the label "really long label" by "really lang label" (just replacing "o" by "a") solves the issue for me. It seems a bug, failing to measure the right dimensions for 12pt with this exact label, but not with 10pt or 11pt. I see no problems using even clearly longer labels with 12 pt as "really long long label". But thinking in other cases of miscalculation:

  2. Presumably, add the pointsize=12 option to the tikz() function. That is used as base font size if tikzDocumentDeclaration fails to produce a math with a valid latex font size. But it does not work with the damn "really long label".

  3. Make the image for the default 10 pt, save the pdf, and scale up the image a 20% (scale=1.2) in the final document.

  4. Edit trialfigure.tex and in \begin{tikzpicture} line change [x=1pt,y=1pt] to [x=1.2pt,y=1.2pt], and take care of reduce picture dimensions proportionally in the tikz() function if needed, to avoid any resizing in LaTeX side.

  5. Alternatively, make "almost" the same standalone documents via knitr in a .Rnw file. Now R will make the figure correctly for 12 pt, so it is ready to use without modifications nor scaling (figure 2). No idea why "really long label" is not problematic here, but although the plot look the same, all tikz coordinates are different, so maybe this avoided the bug?

B) Second, as said in the original anwers, you have also a problem in LaTeX using \resizebox. Using the correct tikz code for 10pt in a 12pt document can produce label overflows (of any label, no only of this weird label), but besides this, the font sizes will be inconsistent between plots and with the main text, depending on whether each one is enlarged or narrowed, just ugly. If instead of the tikz code, you include a pdf image, you will face the same problem using any kind of redimension, via \includegraphics options, or when document set automatically the image dimensions (e.g.: \setkeys{Gin}{width=3cm,height=3cm}). In special you should be aware that Rstudio reports that in PDF (via LaTeX) use templates to automatically shrink large files exceeding \maxdimen (figure 3). So again take care of the dimensions in the R side to avoid redimensions in the LaTeX side, if the final font size matter.

Nonetheless, note that no matter if you make this plot large o small, for 10pt or 12pt, with R script or knitr, invariably the tikz nodes are scaled to 92% or 73% for labels a axis ticks. In a 12pt document, this mean final that the non-scaled image will have font sizes of roughly 11pt and 8pt, respectively. If this matter, you should control also the cex in the R side.

The MWE.Rnw file:

\documentclass[12pt]{article}
\usepackage[bmargin=1cm,tmargin=1cm]{geometry}
\usepackage{tikz}
\parskip1em\parindent0pt
\begin{document}

\begin{figure}[h!]
\centering
\includegraphics[scale=1]{trialfigure.pdf}
\caption{Plot generated by the standalone R script}
\end{figure} 

<<theplot,echo=F,include=F>>=
require(ggplot2)
trialfigure <- ggplot(mpg, aes(y = class)) +
  geom_bar(aes(fill = drv)) +
  scale_fill_discrete(labels = c("4" = "really long label")) +
  theme(legend.position = "bottom")
@
<<herewego,echo=F,dev='tikz',fig.cap="Plot generated with knitr.", fig.align='center', fig.width=4,  fig.height=2,  message=FALSE, fig.pos="h!">>=
trialfigure 
@

<<herewego2,echo=F,dev='tikz',fig.cap="The same but too big = smaller fonts.", fig.align='center', fig.width=6.5,  fig.height=2,  message=FALSE, fig.pos="h!">>=
trialfigure 
@
\end{document}

The MWE.pdf:

new mwe

Note:

Yes, the knitr workflow is very different , but IMHO plenty of advantages, besides manage well this issue.

6
  • Thank you, this is very interesting. I do not think it can solve my problem, as my workflow is very different, i.e. using tikz and \begin{figure}\end{figure}. Working on that MWE now :-) However, your code makes me fear it is actually more of an R than an LaTeX problem :-( Jul 24 at 12:40
  • @canIchangethis After your edit showing manageable code I understand that you are mainly worried about the label overflow, more that for the font size itself, right? I change completely my answer, playing with you example, and touching both issues.
    – Fran
    Jul 25 at 18:18
  • Well, I thought (!) the label overflow is mostly a problem arising from too large font, that's why I thought maybe changing TikZ figure fonts to being smaller than overall font will solve it all. But now trying your solution. Thank you so much! Jul 26 at 12:13
  • So knitr is no option because I am really not skilled to use it and I have everything in overleaf. Actually not only the text "really long label" is my problem but mostly any long label. So I am very happy to drop the resizebox everywhere but for 20 graphs changing manually [x=1pt,y=1pt] to [x=1.2pt,y=1.2pt] seems like a hard thing to do. So I am really confused at this point, which way to go. Thank you so much for all your input @Fran Jul 26 at 12:20
  • @canIchangethis (1) Overleaf admit knitr! The only rqueriment is change the .Rnw extension to .Rtex (2) knitr is just a R between text and the only essential is know that the R code start with <<>>= and end with @. Apart of this, if you learn that in <<foo,echo=F>>= "foo" is the name of the chunk, and echo=F a option to hide the code in the output, then you are already an expert (3) See here to replace text in multiple files.
    – Fran
    Jul 26 at 16:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .