填充单个图中多个函数包围的区域

填充单个图中多个函数包围的区域

我希望填充四个函数所包围的区域,如下图中红色阴影所示:

在此处输入图片描述

到目前为止,我已经能够填充每对函数之间的区域,如下所示:

在此处输入图片描述

第一个生成如下:

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}

\pgfmathdeclarefunction{fun1}{0}{%
  \pgfmathparse{ tan(x)/( cos(x)*( 1 + 3.3*((tan(x))^2) ) ) }}
\pgfmathdeclarefunction{fun2}{0}{%
  \pgfmathparse{ 1.1*tan(x)*(1/cos(x)) }}
\pgfmathdeclarefunction{fun3}{0}{%
  \pgfmathparse{ 0.145*( ( 1 + 3.3*(tan(x))^2 ) / sin(x) ) }}
\pgfmathdeclarefunction{fun4}{0}{%
  \pgfmathparse{ 4 }}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]

% fun1 (start stacking)
\addplot[
domain=1:25.70,
draw=none,fill=none,mark=none,
stack plots=y]
{ fun1 };
%
% stack difference between fun2 and fun1 on top of fun1
\addplot[
domain=1:25.70,
draw=none,draw opacity=0.0,
fill=gray,fill opacity=0.25,
stack plots=y
]
{ max( fun2 - fun1 , 0 ) }
\closedcycle;

% fun1
\addplot[domain=1:89,solid,line width=0.8pt,draw=black,mark=none]{ fun1 };

% fun2 (branch 1)
\addplot[domain=1:25.78,solid,line width=0.8pt,draw=black,mark=none]{ fun2 };
% fun2 (branch 2)
\addplot[domain=25.78:89,dashed,draw=black,mark=none]{ fun2 };

% fun3 (branch 1)
\addplot[domain=1:89,dashed,draw=black,mark=none]{ fun3 };
% fun3 (branch 2)
\addplot[domain=25.78:70,solid,line width=0.8pt,draw=black,mark=none]{ fun3 };
% fun3 (branch 3)
\addplot[domain=70:89,dashed,draw=black,mark=none]{ fun3 };

% fun4 (branch 1)
\addplot[domain=1:70,dashed,draw=black,mark=none]{ fun4 };
% fun4 (branch 2)
\addplot[domain=70:89,solid,line width=0.8pt,draw=black,mark=none]{ fun4 };

\end{semilogyaxis}
\end{tikzpicture}
\end{document}

第二和第三分别是使用以下方法获得的:

  • domain=25.78:70{ max( fun3 - fun1 , 0 ) }
  • domain=70:89{ max( fun4 - fun1 , 0 ) }

我怎样才能在单个图上显示它们?

答案1

您可以定义一个新的分段函数 fun5(x),结合 fun2、fun3 和 fun4,并填充 fun1 和 fun5 之间的区域:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\begin{document}

\pgfmathdeclarefunction{fun1}{1}{%
  \pgfmathparse{tan(#1)/(cos(#1)*(1+3.3*((tan(#1))^2)))}}
\pgfmathdeclarefunction{fun2}{1}{%
  \pgfmathparse{1.1*tan(#1)*(1/cos(#1))}}
\pgfmathdeclarefunction{fun3}{1}{%
  \pgfmathparse{0.145*((1+3.3*(tan(#1))^2)/sin(#1))}}
\pgfmathdeclarefunction{fun4}{1}{%
  \pgfmathparse{4}}
\pgfmathdeclarefunction{fun5}{1}{%
  \pgfmathparse{%
    (#1>=1 && #1<=25.78)*fun2(#1) +%
    (#1>25.78 && #1<=70)*fun3(#1) +%
    (#1>70 && #1<89)*fun4(#1)}}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]
% area
\addplot [domain=1:89,draw=none,stack plots=y]
         {fun1(x)};
%         
\addplot [domain=1:89,draw=none,fill=gray,fill opacity=0.25,stack plots=y]
         {max(fun5(x) - fun1(x),0)}
\closedcycle;
%
% fun1
\addplot [domain=1:89,line width=0.8pt] {fun1(x)};
% fun2 (branch 1)
\addplot[domain=1:25.78,solid,line width=0.8pt]{fun2(x)};
% fun2 (branch 2)
\addplot[domain=25.78:89,dashed]{fun2(x)};
%
% fun3 (branch 1)
\addplot[domain=1:89,dashed]{fun3(x)};
% fun3 (branch 2)
\addplot[domain=25.78:70,line width=0.8pt]{fun3(x)};
% fun3 (branch 3)
\addplot[domain=70:89,dashed]{fun3(x)};
%
% fun4 (branch 1)
\addplot[domain=1:70,dashed]{fun4(x)};
% fun4 (branch 2)
\addplot[domain=70:89,line width=0.8pt]{fun4(x)};
\end{semilogyaxis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

pgfplots 1.10 版刚刚发布,它为填充图表之间区域的问题提供了新的解决方案。

请注意,旧解决方案仍然可行且有效;此处仅提供可能简化任务的更新。为了使本网站的知识库保持最新,我fillbetween在此提供基于新库的解决方案:

在此处输入图片描述

\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}

\begin{document}

\pgfmathdeclarefunction{fun1}{0}{%
  \pgfmathparse{ tan(x)/( cos(x)*( 1 + 3.3*((tan(x))^2) ) ) }}
\pgfmathdeclarefunction{fun2}{0}{%
  \pgfmathparse{ 1.1*tan(x)*(1/cos(x)) }}
\pgfmathdeclarefunction{fun3}{0}{%
  \pgfmathparse{ 0.145*( ( 1 + 3.3*(tan(x))^2 ) / sin(x) ) }}
\pgfmathdeclarefunction{fun4}{0}{%
  \pgfmathparse{ 4 }}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]


% fun1
\addplot[name path=fun1,domain=1:89,red]{ fun1 };

% fun2 
\addplot[name path=fun2,domain=1:78.89,blue]{ fun2 };

% fun3 
\addplot[name path=fun3,domain=1:89,brown,]{ fun3 };

% fun4 
\addplot[name path=fun4,domain=1:89,orange]{ fun4 };

\path[name path=intermediate,
     %draw, line width=2pt,
    intersection segments={of=fun2 and fun3,
        sequence=A0 -- B1,
    },
];
\path[name path=segments,
    %draw, line width=2pt,
    intersection segments={of=intermediate and fun4,
        sequence=A0 -- B1,
    },
];

\addplot[gray,fill opacity=0.25] fill between[of=segments and fun1];
\end{semilogyaxis}
\end{tikzpicture}

\end{document}

此解决方案仅包含四个函数,没有任何修改。但是,它为每个函数分配了一个标签。然后,我们有\path两个指令来计算相交段:第一\path条指令生成将被丢弃的中间路径。请注意,\path没有drawfill没有可见输出(并且仅在生成的 pdf 中生成范围,没有路径指令)。第一条路径由intermediate的组成,即段,表示“第一个参数()的第一个(第 0 个)段”。从图形上看,这是填充区域(蓝色和棕色)的左下边缘。第一个参数始终在此上下文中调用,段索引从 0 开始。此段与相连,表示第二个参数的第二个(第 1 个)段(即的第二个段)。intersection segmentsfun2 and fun3A0fun2AB1of=fun2 and fun3fun3

第二\path条指令计算intersection segmentsintermediate and fun4请记住fun4是顶部路径(橙色路径)。在这里,我们取A0( 的第一个交叉段intermediate)并将其与B1( 的第二个 = 第 1 个段fun4)连接起来。

这两条指令都\path不会产生可见的输出(除非您插入取消注释的draw键)。它们仅将结果存储在名称下。

最后,最后一条语句填充了我们计算的和\addplot fill between之间的区域。为此,它使用了填充选项。segmentsfun1gray,fill opacity=0.25

相关内容