pgfplots 的草稿模式

pgfplots 的草稿模式

我正在处理一个相当大的文档,其中包含大量函数图 - 到目前为止大约有 200 个,到最后将有大约 1500 个。我pgfplots在每个图形上都使用了这些函数,它们都非常基础:指数、有理、多项式和三角函数。

一旦我对每张图表都满意,我就不必每次编译时都查看它,并希望尽量减少将来草稿的编译时间。当然,文档已经分成了章节文件,但每章包含大约 100 个图表。

研究过相关pgfplots文献后,我还没有找到一种draft模式,但我有兴趣知道是否可以创建一种模式

我正在设想类似于包装draft模式的东西graphicx,其中不包含图形,而是用空白框代替。

我考虑过的一些事情:

  • standalone documentclass;但是如果有大约 1500 个数字,这是否意味着过度模块化?
  • tikzexternalize但这仍然需要初始的“怪物”编译来获取图像外部化,然后draft才能调用该选项

以下是一个可供玩转的 MWE

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

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

\end{document}

答案1

根据@percusse的建议,这是一个(也许太)简单的方法:

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

draft选项设置\overfullrule为 5pt。更安全的方法是检查是否draft出现在全局选项中,保存在\@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

当然,如果信息可用,真正令人满意的解决方案是绘制一个与其所代表的图片一样宽的框,而不是固定的矩形。


前一种方案存在一个问题:所有\tikz...;内联图片都会变成方框,部分文本会丢失。下面是一种更复杂的方法来解决这个问题

\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

\tikzpicture我们保存和的原始含义\endtikzpicture,修补相关的宏以使用别名。

答案2

这个答案实际上只是 zeroth 问答的一个应用:外部化为其他格式,Makefile。向 makefile 添加新规则

\documentclass{article}
\usepackage{pgfplots}

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

\begin{document}

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

\end{document}

这太棒了,因为你可以运行

make -f \jobname.makefile 

一次性生成所有图像-太棒了!

答案3

最后,我花了很多时间才想出了一个可能比其他所有选项都更不适合你需求的方案。但是,既然我做这个方案很有趣,我还是把它贴出来,至少出于好奇。基本思路是构建图形,将它们的尺寸写入外部文件,在“草稿模式”下,用正确尺寸的带框框替换每个图形,而不是构建图形。这样做的主要缺点是,由于结果没有保存,构建图形的工作会丢失。因此,最终文档需要从头开始编译以包含图形。此外,如果不重新编译整个文档,它就不会检测到对早期工作的更改。至少出于这些原因,这不是一个很好的解决方案,但可能作为一个例子很有用。

\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}
                    \addplot {x^2};
                  \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}
        %\addplot {x^2};
    %\end{axis}
%}\par\noindent
%\tikzpic{
    %\begin{axis}
        %\addplot {x^2};
    %\end{axis}
%}\par\noindent

\end{document}

答案4

低技术解决方案:通过在序言中添加此行,仅对曲线的起点和终点进行采样

\pgfplotsset{samples=2}

相关内容