使用带有 fillbetween 的自定义图层

使用带有 fillbetween 的自定义图层

我想要两层在后面背景层waybackgroundlayerboundingboxlayer 也使用fillbetween

下面的 MWE 用于\AxisEnvironmentFig绘制曲线。*禁用 的选项fill between用于第二张图中,我必须注释掉\DrawBoundingBox

在此处输入图片描述

我希望能够使用两个都fill between 有另外两层可供我使用。

参考:

该网站上有几个相关问题,但我无法让它们发挥作用。

失败的尝试:

pgfplots:填充背景层之间的间隙和手册第 410 页pgfplots,我尝试使用

\pgfplotsset{layers/standard/.define layer set={
        waybackgroundlayer, boundingboxlayer, 
        background,
        axis background,axis grid,axis ticks,axis lines,axis tick labels,
        main,
        axis descriptions,axis foreground
    }{
grid style={/pgfplots/on layer=axis grid},
tick style={/pgfplots/on layer=axis ticks},
axis line style={/pgfplots/on layer=axis lines},
label style={/pgfplots/on layer=axis descriptions},
legend style={/pgfplots/on layer=axis descriptions},
title style={/pgfplots/on layer=axis descriptions},
colorbar style={/pgfplots/on layer=axis descriptions},
ticklabel style={/pgfplots/on layer=axis tick labels},
axis background@ style={/pgfplots/on layer=axis background},
3d box foreground style={/pgfplots/on layer=axis foreground},
}}

并且

\pgfplotsset{layers/PetersLayers/.define layer set={
        waybackgroundlayer, boundingboxlayer, background,
        axis background,axis grid,axis ticks,axis lines,axis tick labels,
        main,
        axis descriptions,axis foreground,
    }{/pgfplots/layers/standard},
}
\pgfplotsset{set layers=PetersLayers}

代码:

\documentclass{standalone}
\usepackage{xstring}
\usepackage{xparse}
\usepackage{pgfplots}
\usetikzlibrary{intersections}
\usetikzlibrary{backgrounds}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=newest}


\pgfdeclarelayer{foreground} 
\pgfdeclarelayer{background}
\pgfdeclarelayer{boundingboxlayer}
\pgfdeclarelayer{waybackgroundlayer}
\pgfsetlayers{waybackgroundlayer,boundingboxlayer,background,main,foreground}

%\pgfplotsset{layers/standard/.define layer set={
%        waybackgroundlayer, boundingboxlayer, 
%        background,
%        axis background,axis grid,axis ticks,axis lines,axis tick labels,
%        main,
%        axis descriptions,axis foreground
%    }{
%grid style={/pgfplots/on layer=axis grid},
%tick style={/pgfplots/on layer=axis ticks},
%axis line style={/pgfplots/on layer=axis lines},
%label style={/pgfplots/on layer=axis descriptions},
%legend style={/pgfplots/on layer=axis descriptions},
%title style={/pgfplots/on layer=axis descriptions},
%colorbar style={/pgfplots/on layer=axis descriptions},
%ticklabel style={/pgfplots/on layer=axis tick labels},
%axis background@ style={/pgfplots/on layer=axis background},
%3d box foreground style={/pgfplots/on layer=axis foreground},
%}}

%\pgfplotsset{layers/PetersLayers/.define layer set={
%        waybackgroundlayer, boundingboxlayer, background,
%        axis background,axis grid,axis ticks,axis lines,axis tick labels,
%        main,
%        axis descriptions,axis foreground,
%    }{/pgfplots/layers/standard},
%}
%\pgfplotsset{set layers=PetersLayers}


\newcommand*{\DrawBoundingBox}{%
  \begin{pgfonlayer}{boundingboxlayer}
    \draw [red, ultra thick, fill=yellow!25, use as bounding box]
        ([shift={(-5pt,-5pt)}]current bounding box.south west)
            rectangle
        ([shift={(5pt,+5pt)}]current bounding box.north east);
  \end{pgfonlayer}%
}

\NewDocumentCommand{\AxisEnvironmentFig}{% https://tex.stackexchange.com/a/353688/4301
    s% #1=* means don't apply "fill between"
}{%
    \begin{axis}[
        xmin=-4,    xmax=6,
        ymin=-5,    ymax=6,
        axis lines=middle,
        axis equal image=true,
        axis on top,
        no markers,
        smooth,
        domain=-6:6,
        %set layers=PetersLayers,
    ]

        %% simplest is reformulate the root function to a parabola ...
        %\addplot+ [blue, thick, name path=curve] {sqrt(2*x+6)};
        % ... and draw it as parametric plot
        \addplot+ [blue, thick, name path=curve] (0.5*x^2-3, x);

        \addplot [red, thick, name path=line]  {x-1};

        \IfBooleanF{#1}{% <--- Modification from 353688
            % then you only want to fill the closed segment which number 1
            % (the counting starts from 0)
            % to to so you don't want to fill anything else
            \addplot [fill=none] fill between [
                of=curve and line,
                % to be able to apply styles to each segment
                split,
                % then provide the style to fill the named segment
                every segment no 1/.style={
                    fill=green!50,
                },
            ];
        }%
    \end{axis}
}

\begin{document}
    \begin{tikzpicture}
        \AxisEnvironmentFig*
        \DrawBoundingBox
    \end{tikzpicture}
    ~%% The following does not work as it uses "fill between"
    \begin{tikzpicture}
        \AxisEnvironmentFig
        %\DrawBoundingBox%% <--- What do I need to do above so I can uncomment this ???
    \end{tikzpicture}
\end{document}

答案1

pre main你的尝试完全正确,但不幸的是你忘记声明/设置默认fill between移动内容的层。你没有注意到这一点,因为你.define layer set从中复制内容的手册中也没有这个信息。(我已经记下了纠正这个问题。)

完成此操作后,一切几乎正常,因为您从 复制了图层集default。这将导致填充区域为超过轴线、刻度和刻度标签,这很可能不是您想要的。为了防止这种情况发生,您有几种选择。

  1. 将默认图层更改为fill between写在所有内容下方的图层,例如通过添加fill between/on layer=axis backgroundaxis选项。
  2. 当您定义自己的图层集时使用axis on top图层顺序(我在这里已经完成了)。

% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{xparse}
\usepackage{pgfplots}
    \usetikzlibrary{pgfplots.fillbetween}
    \pgfplotsset{
        compat=1.16,
        % switched layers to the default of `axis on top` and added missing
        % layer `pre main` (which is present in the code, but not in the manual)
        layers/PetersLayers/.define layer set={
            waybackgroundlayer, boundingboxlayer,
            axis background,
            pre main,       % <-- added
            main,
            axis grid,axis ticks,axis lines,axis tick labels,
            axis descriptions,axis foreground,
        }{/pgfplots/layers/axis on top},
        set layers=PetersLayers,
    }

\newcommand*{\DrawBoundingBox}{
  \begin{pgfonlayer}{boundingboxlayer}
    \draw [red, ultra thick, fill=yellow!25, use as bounding box]
        ([shift={(-5pt,-5pt)}]current bounding box.south west)
            rectangle
        ([shift={(5pt,+5pt)}]current bounding box.north east);
  \end{pgfonlayer}
}

\NewDocumentCommand{\AxisEnvironmentFig}{% https://tex.stackexchange.com/a/353688/4301
    s% #1=* means don't apply "fill between"
}{%
    \begin{axis}[
        xmin=-4,    xmax=6,
        ymin=-5,    ymax=6,
        axis lines=middle,
        axis equal image=true,
        no markers,
        smooth,
        domain=-6:6,
    ]

        %% simplest is reformulate the root function to a parabola ...
        %\addplot+ [blue, thick, name path=curve] {sqrt(2*x+6)};
        % ... and draw it as parametric plot
        \addplot+ [blue, thick, name path=curve] (0.5*x^2-3, x);

        \addplot [red, thick, name path=line]  {x-1};

        \IfBooleanF{#1}{% <--- Modification from 353688
            % then you only want to fill the closed segment which number 1
            % (the counting starts from 0)
            % to to so you don't want to fill anything else
            \addplot [fill=none] fill between [
                of=curve and line,
                % to be able to apply styles to each segment
                split,
                % then provide the style to fill the named segment
                every segment no 1/.style={
                    fill=green!50,
                },
            ];
        }
    \end{axis}
}

\begin{document}
    \begin{tikzpicture}
        \AxisEnvironmentFig*
        \DrawBoundingBox
    \end{tikzpicture}
    ~
    \begin{tikzpicture}
        \AxisEnvironmentFig
        \DrawBoundingBox
    \end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容