116

My Tex files get very confusing since I have multiple long TikZ code in them. How do you organize your files when it comes to TikZ?

user695652
  • 1,447

4 Answers4

146

Like with any TeX code you can put your TikZ picture environment into own .tex files and load them in your document with \input{<filename>} (never with \include). Because I faced similar issues like you while writing my thesis I wrote standalone class and package which allows you to add a full preamble to these files and compile them on their own while still be able to \input them into a main document without any changes.

The exact way I organize my TikZ pictures is as follows:

  • One .tex file per TikZ picture.
  • The files include a full preamble which loads all packages and libraries required and use the standalone class.
  • The files can be in a subdirectory, e.g. figures.
  • In the main document I load the standalone package and \input the TikZ pictures where I want to have them, e.g. inside a figure environment.
  • The newer versions of standlone also provide a \includestandalone[<options>]{<filename>} macro which can be used instead of \input but allows you to use the same options like for \includegraphics, e.g. resize and turn the content, etc.
  • It is also possible to compile all the TikZ files to single PDFs and include these in the document. This speeds up the compilation process significantly (except the first one, of course).
  • For existing documents you can also just copy every TikZ picture to a single .tex file without preamble and simply \input that one. However, standalone gives you the great benefit of being able to compile the TikZ picture on its own. This is a huge time safer while coding the picture.

Example

Tikz picture:

% Tikz File 'mytikz.tex'
\documentclass{standalone}
\usepackage{tikz}
%\usetikzlibrary{...}
\begin{document}
\begin{tikzpicture}
  \draw (0,0) -- (1,1);
  %%%
\end{tikzpicture}
\end{document}

Main document:

% Main document
\documentclass{book}
% Repeat required preamble stuff or use `subpreambles` option of the `standalone` package
\usepackage{tikz}
%\usetikzlibrary{...}
\usepackage{standalone}
\begin{document}
Text ...
\begin{figure}
  \includestandalone[width=\textwidth]{mytikz}%     without .tex extension
  % or use \input{mytikz}
  \caption{My TikZ picture}
  \label{fig:tikz:my}
\end{figure}
\end{document}

See the standalone manual for more. There are a couple of more options and features.

Martin Scharrer
  • 262,582
  • 3
    I like the subfiles package, which works like standalone, but has the added benefit of custom commands set with \newcommand in the main file's preamble still available in the other files. Actually, as preambles in the subfiles are simply \documentclass[example.tex]{subfiles}, the whole preamble of the main file is compiled when the single subfile is compiled. A drawback is that all subfiles have to be in the same directory as the main file. – Jānis Lazovskis Oct 29 '12 at 19:17
  • 6
    So glad that you got the rep for this :) Thanks for a great package, and all you do for the community :) – cmhughes Oct 29 '12 at 19:53
  • Doesn't \includestandalone go against the idea of tikz a bit? One reason I like tikz and pgfplots is the consistency of fonts. If I scale a tikzpicture I do with \includegraphics, don't the font sizes get scaled accordingly? What remains of the advantage over a compiling the tikz-file standalone and using \includepdf? – gerrit Oct 29 '12 at 20:04
  • 2
    @gerrit: You don't need to scale the picture when you are using \includestandalone. It is also good for other things, like the build option, which can automatically build and include TikZ files. Also, you mean \includegraphics not \includepdf, right? The latter is only required for full page PDFs. – Martin Scharrer Oct 29 '12 at 22:03
  • Yes, I meant \includegraphics. It's been a while since I used \includegraphics (I use tikz and particularly pgfplots nowadays ;-) so I got confused :). Thanks for the explanation on \includestandalone. – gerrit Oct 29 '12 at 23:45
  • If I use \input{}, the separate .tex is compiled when the main file is compiled? Is this correct? Whereas if I use \includestandalone, the main file inserts the .pdf that is created after tikz.tex is compiled? Also, does this mean the main .tex files preamble doesn't need to duplicate what was in the separate files preamble? – dustin Jul 19 '13 at 10:11
  • \includestandalone can either include the PDF (like \includegraphics; no preamble duplication required) or the source code (like \input) depending on the package options used. Note that there is also an option to extract the preambles from the subfiles automatically. – Martin Scharrer Jul 19 '13 at 12:46
  • So if I use \input, what do I need to set to extract preambles from the subfiles? Just to clarify, with that option set, I could delete the duplicated preamble from the main document then? – dustin Jul 19 '13 at 18:40
  • 1
    Is it correct that \includestandalone[width=\textwidth] first compiles the graphic and then scales it? Because it seems that text is also rescaled. Is it somehow possible to reverse the order of rendering and scaling, such that the font size matches that of the document? (Not sure if I should ask this as a separate question...) – Jost Sep 24 '13 at 16:04
  • @Jost: \includestandalone[width=\textwidth] includes the external file, boxes it (which typesets, i.e. "renders", it) and then scales the box. At that point you can't change the font size anymore. What you describe is AFAIK provided by the related externalize TikZ library. See the PGF/TikZ manual for details. – Martin Scharrer Sep 25 '13 at 17:00
  • I tried to use the standalone package, and got an "exceeded capacity error". Here is the error: [15] [16] [17] (./Figures/geodesic.tex) ! TeX capacity exceeded, sorry [main memory size=1500000]. \collectedbox

    l.561 ...ne[width=0.9\textwidth]{Figures/geodesic} % without .tex extension ! ==> Fatal error occurred, no output PDF file produced! Transcript written on input.log.

    – Herman Jaramillo Nov 05 '15 at 19:11
  • standalone doesn't seem to work well with external documents which themselves make use of \usepackage, e.g. I need to look into these files and check what they need and then copy and paste that into the main document. Is there a way to somehow automatically include the prerequisites in the main document? – Frederick Nord Jun 15 '16 at 13:28
  • 1
    @FrederickNord: Yes, use the subpreambles package option. See the manual of standalone for further details. – Martin Scharrer Jun 21 '16 at 18:46
  • @MartinScharrer can it be used as an alternative to tikzexternalize? – Alessandro Cuttin Dec 28 '17 at 16:40
  • 1
    @AlessandroCuttin: Yes, but it works the other way around. Instead of taking the code out from the main document as tikzexternalize does it, you have the code in separate files and include them in the main document, while still be able to compile them alone or automatically if they changed. – Martin Scharrer Dec 29 '17 at 10:00
  • @MartinScharrer I hope you could help me with my relevant question if you don't mind. – Diaa Aug 08 '18 at 14:12
17

I 'll try to describe the approach I used for my master thesis. Since I had a lot of tikz figures, compilation time was significant. In order to reduce it I decided to compile them to standalone pdfs and use \includegraphics{} (Martin's answer already mentioned that - I am just elaborating).

In order to do that I followed the following scheme:

$ tree
.
├── chap1
│   ├── chap1.tex
│   └── figures
│       ├── figure1.tikz
│       └── figure2.tikz
├── chap2
│   ├── chap2.tex
│   └── figures
│       ├── figure1.tikz
│       └── figure2.tikz
├── main.tex
└── tikz_preamble.tex

So I created a folder for each chapter containing a tex file and a subfolder containing the tikz files. In my main.tex i used the import package and I used the command \subimport{chap1/}{chap1.tex} to include the tex files of each chapter. In the tex file of each chapter I was just using \includegraphics{figures/figure1.pdf}

Now, in order to create the tikz figures and convert them to pdfs I used the following approach.

  1. I created them using ktikz and I saved them in the appropriate folder. NOTE: Each tikz file contained only the \begin{tikzpicture}...\end{tikzpicture}. NOT the preamble! NEITHER \begin{document} and \end{document}. You can find an example here.

  2. I created a a file named tikz_preamble.tex containing the necessary preamble for the compilation of the tikz figures AND \begin{document} - \end{document}. You can find an example here.

  3. Lastly I wrote a python script that would search recursively for files with *.tikz extension and would compile them using the tikz_preable.tex. On subsequent runs, only newly created files and files with changes would be compiled. The *.pdf files are created in the same folder as the *.tikz files. So the figures folder would look like this:

    └── figures
        ├── figure1.pdf
        ├── figure1.tikz
        ├── figure2.pdf
        └── figure2.tikz
    

Keeping the tikz files preamble as a separate file may seem as inconvenient but it allows greater flexibility. If you decide to make severe changes in your preamble (e.g. change font or font size - that actually happened to me, one day before the presentation!) then all you have to do is to adjust tikz_preamble and to call the script with a certain command line argument and it will update all your tikz files without any hassle.

PS. I would be interested in reading other people's work-flows.

pmav99
  • 6,060
  • I understand the thinking behind this process, and this is how I started also. However, the main benefit you describe of a change needed in the tikz_preamble can still be achieved with the standalone pacakge by using it as \usepackage{tikz_preamble}. Then the preamble can be easily changed if needed, the pictures are compilable by themselves, and can also be imported into the main document. – Peter Grill Oct 30 '12 at 20:29
  • @PeterGrill Keeping the preamble together with the tikzpicture environment is not so convenient when you work with ktikz. Also you have to ensure that tikz_preamble package is within the TeX path (actually it is trivial to do it - e.g. symlinking to the texmf-local). Anyway, the other main benefit is the ability to compile automatically all your source files with a single command (e.g. if you use version control and you clone your repo). – pmav99 Oct 31 '12 at 20:47
12

Naturally I can't compete with Martins answer :) but I have a different approach which does not include the use of 'yet another' additional package (you know what I mean).

Resulting Document

First of all -- here is the result:

enter image description here

Screeshots of the Folder Structure

Here is my simplified folder structure

enter image description here

The content of every folder is

enter image description here

enter image description here

enter image description here

Main File

The main file looks like this:

\documentclass[parskip]{scrartcl}
% The Usual Suspects
\usepackage[latin1]{inputenc}
\usepackage[english]{babel}
\usepackage{graphicx}
\usepackage{float}
\usepackage{lmodern}
% Nice Captions for Tables and Figures etc.
\usepackage[%
    font={small,sf},
    labelfont=bf,
    format=hang,
]{caption}
\usepackage{tikz}

% For Random Text
\usepackage{blindtext}

% Load Custom Styles
\input{TikZ-Styles/myUnitStyle.tex}
\input{TikZ-Styles/myLineStyle.tex}
\input{TikZ-Styles/myColorStyle.tex}
\input{TikZ-Styles/myGrayStyle.tex}

% -------------------------- Start Document --------------------------
\begin{document}

\section*{Test Section}

\blindtext

% That's all!
\input{Figures-Input-Code/fig_Squares.tex}

\blindtext

\end{document}
% -------------------------- End Document --------------------------

Figure Input Code

The Figure Input Code looks like this:

\begin{figure}[H]
\centering
\input{TikZ-Code/Code_Squares.tex}
\caption{Example TikZ picture that has nothing special to offer.}
\label{fig_Squares}
\end{figure}

The label of the figure always has the filename of the Figure Input Code file. In this case the file is named fig_Squares.tex. So I have a consistent principle. The TikZ code file also shares the filename -- but the prefix is Code. Here it is therefore Code_Squares.tex.

TikZ Code

The TikZ Code looks like this:

\begin{tikzpicture}[myUnitStyle,myLineStyle]
\draw [myColorStyle] (0,0) rectangle (10,10);
\draw [myGrayStyle] (12,0) rectangle (22,10);
\end{tikzpicture}

TikZ Styles

The TikZ Styles look like this:

\tikzset{myColorStyle/.style={fill=yellow,draw=red}}

\tikzset{myGrayStyle/.style={fill=gray,draw=black}}

\tikzset{myLineStyle/.style={line width=2pt}}

\tikzset{myUnitStyle/.style={x=1mm,y=1mm}}

The filenames for the styles reflect the name of the style, as you can see.

Advantages

I see the following advantages

  • Lean and clean main document
  • You don't need to worry how to name/label the figures
  • It's easy to reuse the code in other documents
  • It's easy to only compile parts by commenting the \input commands -- this also makes it easier to debug
  • You do not need to include a separate preamble to every TikZ picture -- I guess it would be annoying to edit every preamble if you need to change it or if you want to reuse the code in other documents

Of course Martins solution is better. But in my experience new LaTeX users are happy if they do not need to understand an additional package.

  • 1
    I understand the problem with adding new packages. I run out of memory using "pdflatex" after including the "standalone" package. I do not want to run "lualatex" or "latexmk" because they had other issues..... – Herman Jaramillo Nov 05 '15 at 19:20
  • 1
    RiWelcome. :-) I have not seen in this period. My best regards. – Sebastiano Aug 29 '20 at 19:11
  • @sebastiani I moved to China and then came back to Germany recently. Currently my life is pretty busy. Therefore I was not active on this site. I am happy that you say hi to me! – Dr. Manuel Kuehner Aug 29 '20 at 23:02
3

You can create a style sheet commandsty.sty with the following contents:

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{commandpackage}
  [2014/12/09 v0.01 LaTeX package for my own purpose]

\RequirePackage{tikz}

\newcommand{\tikzpic}[1][fill=black]{\begin{tikzpicture}

\end{tikzpicture}
}

\endinput

Then you may include it by simply using \usepackage{commandpackage} in your main tex file. Then you may simply use \tikzpic to place it inline.

User
  • 31