# Draft mode for pgfplots

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}
\end{axis}
\end{tikzpicture}

\end{document}

-
Maybe you can renewenvironment the tikzpicture to nothing or \draw only a rectangle? –  percusse Jun 19 '12 at 20:28
@percusse I've tried a few things along those lines, but with no success. It sounds like a promising idea though :) –  cmhughes Jun 19 '12 at 21:44
Actually the externalize feature together with the makefile option enables "draft". Just use /tikz/external/mode=list and make. This will generate dummy text on each picture and add text instead. This also enables one to generate the 1500 pictures in parallel. :) –  zeroth Jun 20 '12 at 14:36
@zeroth thanks, that's fantastic! you should post that as an answer- perhaps just add it into my MWE –  cmhughes Jun 20 '12 at 18:54
@zeroth with the reconfiguration \pgfkeys{/pgf/images/include external/.code={\includegraphics{#1}}} your solution would allow real draft mode - it would externalize the graphics, but would not reinclude them - only boxes of the right size (using the draft mode of the graphics package) –  Christian Feuersänger Jun 20 '12 at 20:31

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}
\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.

-

This answer is really just an application of zeroth's question & answer: Externalization to other format, Makefile. Add new rules to the makefile

\documentclass{article}
\usepackage{pgfplots}

\usetikzlibrary{external}
\tikzexternalize[mode=list and make]

\begin{document}

\begin{tikzpicture}
\begin{axis}
\end{axis}
\end{tikzpicture}

\end{document}


This is awesome, because you can then run

make -f \jobname.makefile


to generate all of the images in one go- sweet!

-
Sweet! I also tried the answer marked as accepted but failed to work it out. I think this answer is cleaner, easier to use/understand and it works, indeed! –  Ali Jul 9 '12 at 20:45

In the end I managed to spend a lot of time coming up with something that probably suits your needs less than all of the other options. However, since I had fun making it, I might as well post it, at least for curiosities sake. The basic idea is to build the graphics, write their dimensions to an external file and, when in "draft mode", rather than building the graphics replace each with a framed box of the correct dimensions. The main disadvantage of this would be that the work done in building the graphics is lost because the result isn't saved. Thus, the final document would need to be compiled from scratch to include the graphics. In addition, it won't detect changes to earlier work without recompiling the entire document. For at least those reasons it's not a great solution but might be useful as an example.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{xparse}

\ExplSyntaxOn
\bool_new:N \g_draft_bool
\bool_new:N \g_set_dimens_bool
\iow_new:N \put_dimens_iow
\ior_new:N \get_dimens_ior
\box_new:N \l_my_box
\clist_new:N \g_my_dimens_clist
\int_new:N \g_num_dimens_int
\int_new:N \g_num_pics_int
\int_new:N \l_count_int

\cs_new:Npn \tikz_pic:w #1 \q_stop
{
\int_gincr:N \g_num_pics_int
\bool_if:NTF \g_set_dimens_bool
{%if rescanning, then box and write dimensions to file
\tl_set:Nn \l_tmpa_tl { \begin{tikzpicture} #1 \end{tikzpicture} }
\hbox_set:Nw \l_my_box \l_tmpa_tl \hbox_set_end:
\iow_now:Nn \exp_args:No \put_dimens_iow {\dim_eval:n {\box_wd:N \l_my_box},\dim_eval:n {\box_ht:N \l_my_box}}
%\box_use:N \l_my_box % uncomment to see pics on \SetDims run
}
{
\bool_if:NTF \g_draft_bool
{
\int_compare:nTF {\g_num_pics_int > \g_num_dimens_int}
{%if new pics, add dimensions to clist and draw pic
\tl_set:Nn \l_tmpa_tl { \begin{tikzpicture} #1 \end{tikzpicture} }
\hbox_set:Nw \l_my_box \l_tmpa_tl \hbox_set_end:
\clist_gput_right:Nx \g_my_dimens_clist {\dim_eval:n {\box_wd:N \l_my_box},\dim_eval:n {\box_ht:N \l_my_box}}
\box_use:N \l_my_box
}
{%if not, then draw boxes
\clist_set_eq:NN \l_tmpa_clist \g_my_dimens_clist
\clist_pop:NN \l_tmpa_clist \l_tmpa_tl
\clist_pop:NN \l_tmpa_clist \l_tmpb_tl
\fbox{\rule{\dim_eval:n \l_tmpa_tl}{0pt}\rule{0pt}{\dim_eval:n \l_tmpb_tl}}
}

}
{%if not draft or scanning, do as normal
\begin{tikzpicture} #1 \end{tikzpicture}
}
}
}

%this will grab dimensions of all existing pics
\NewDocumentCommand \SetDims {}
{
\bool_gset_true:N \g_set_dimens_bool
\iow_open:Nn \put_dimens_iow {dims.aux}
}

%after setting dims, this will replace all pics with their bounding boxes.
%graphics added after setting dims (except the most recently added), will be
%replaced by their bounding boxes on subsequent compiles
\NewDocumentCommand \DraftOn {}
{
\bool_gset_true:N \g_draft_bool
\ior_open:Nn \get_dimens_ior {dims.aux}
\bool_until_do:nn { \ior_if_eof_p:N \get_dimens_ior }
{%write saved dimensions to clist and count pics
\ior_to:NN \get_dimens_ior \l_tmpa_tl
\clist_gput_right:NV \g_my_dimens_clist \l_tmpa_tl
\int_gincr:N \g_num_dimens_int
}

\ior_close:N \get_dimens_ior
\clist_remove_all:Nn \g_my_dimens_clist {\par}%the above puts a par in the clist
\int_gdecr:N \g_num_dimens_int%compensate for the par
}

\NewDocumentCommand \tikzpic { +m }
{
\tikz_pic:w #1 \q_stop
}

\AtEndDocument{
\bool_if:NT \g_draft_bool
{
\int_compare:nT {\g_num_pics_int > \g_num_dimens_int+1}
{%if more than one new pic
\iow_open:Nn \put_dimens_iow {dims.aux}
\int_until_do:nn {\l_count_int >= \g_num_pics_int-1}
{%re-write dims file, excluding last pic
\int_incr:N \l_count_int
\clist_pop:NN \g_my_dimens_clist \l_tmpa_tl
\clist_pop:NN \g_my_dimens_clist \l_tmpb_tl
\iow_now:Nn \exp_args:No \put_dimens_iow {\dim_eval:n \l_tmpa_tl,\dim_eval:n \l_tmpb_tl}
}
}
}
}

\NewDocumentCommand \makelotsoftikzpics {o}
{
\prg_replicate:nn {50}
{
\tikzpic{
\begin{axis}
\end{axis}
}\par\noindent
}
}
\ExplSyntaxOff
\fboxsep=0pt

\begin{document}
%first run with \SetDims switch
\SetDims
%comment \SetDims and uncomment \DraftOn to get bounding boxes
%\DraftOn
Here are some tikz pics...\par\noindent
\makelotsoftikzpics
%As additional pics are added (with \DraftOn) all but the most recent will be replaced by their bounding boxes
%on subsequent compiles
%\tikzpic{
%\begin{axis}
`