PGFPlots Draft Mode – How to Enable and Use

draftpgfplotsworkflow

I'm working on a fairly big document that has a lot of graphs of functions- so far it has around 200, by the end it will have around 1500. I use pgfplots for each graphic, and the functions are pretty basic: exponential, rational, polynomial, and trigonometric.

Once I am happy with each graph, I don't necessarily need to see it every time I compile, and would like to minimize compilation time for future drafts. Naturally, the document is already chopped up into chapter files, but each chapter contains around 100 figures.

Having studied the pgfplots documentation, I haven't found a draft mode, but I'm interested in knowing if one could be created.

I'm envisaging something similar to the draft mode of the graphicx package, in which graphics are not included, and blank boxes are put in their place.

Some things I've considered:

  • the standalone documentclass; but with about 1500 figures, wouldn't this mean over-modulization?
  • tikzexternalize, but this still requires an initial 'monster' compilation to get the images externalized before the draft option could be invoked

Here's a MWE to play with

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
    \begin{axis}
        \addplot {x^2};
    \end{axis}
\end{tikzpicture}

\end{document}

Best Answer

Following a suggestion of @percusse, here's a (perhaps too) simple way:

\documentclass{article}
\usepackage{pgfplots}

\ifdim\overfullrule>0pt % draft option is active
  \usepackage{environ}
  \let\tikzpicture\relax
  \let\endtikzpicture\relax
  \NewEnviron{tikzpicture}{%
    \begin{pgfpicture}
    \pgfpathrectanglecorners{\pgfpointorigin}{\pgfpoint{3cm}{3cm}}%
     \pgfusepath{stroke}\end{pgfpicture}%
  }
\fi

\begin{document}

\begin{tikzpicture}
  \begin{axis}
    \addplot[thick] {x^2};
  \end{axis}
\end{tikzpicture}

\end{document}

The draft option sets \overfullrule to 5pt. A safer way would be to check whether draft appears in the global options, saved in \@classoptionslist:

\makeatletter
\@tempswafalse
\def\@tempa{draft}
\@for\next:=\@classoptionslist\do
  {\ifx\next\@tempa\@tempswatrue\fi}
\if@tempswa % draft option is active
  \usepackage{environ}
  \let\tikzpicture\relax
  \let\endtikzpicture\relax
  \NewEnviron{tikzpicture}{%
    \begin{pgfpicture}
    \pgfpathrectanglecorners{\pgfpointorigin}{\pgfpoint{3cm}{3cm}}%
    \pgfusepath{stroke}
    \end{pgfpicture}%
  }
\fi

Of course a really satisfying solution would draw a box as wide as the picture it represents, provided the information is available, instead of a fixed rectangle.


There's a problem with the former solution: all \tikz...; inline pictures will be transformed into boxes and some text would be lost. Here's a more complicated way to cope with this problem

\makeatletter
\@tempswafalse
\def\@tempa{draft}
\@for\next:=\@classoptionslist\do
  {\ifx\next\@tempa\@tempswatrue\fi}
\if@tempswa % draft option is active

  \usepackage{environ,etoolbox}

  \let\tikz@@tikzpicture\tikzpicture
  \let\tikz@@endtikzpicture\endtikzpicture
  \patchcmd\tikz@opt{\tikzpicture}{\tikz@@tikzpicture}{}{}
  \patchcmd\tikz@collectnormalsemicolon{\endtikzpicture}{\tikz@@endtikzpicture}{}{}
  \chardef\@tempa=\catcode`\;
  \catcode`\;=\active
  \patchcmd\tikz@collectactivesemicolon{\endtikzpicture}{\tikz@@endtikzpicture}{}{}
  \catcode`\;=\@tempa

  \let\tikzpicture\relax
  \let\endtikzpicture\relax
      \NewEnviron{tikzpicture}{%
        \begin{pgfpicture}
        \pgfpathrectanglecorners{\pgfpointorigin}{\pgfpoint{3cm}{3cm}}%
        \pgfusepath{stroke}
        \end{pgfpicture}%
      }
    \fi

We save the original meanings of \tikzpicture and \endtikzpicture, patching the relevant macros to use the aliases.

Related Question