我希望填充四个函数所包围的区域,如下图中红色阴影所示:
到目前为止,我已经能够填充每对函数之间的区域,如下所示:
第一个生成如下:
\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
没有draw
或fill
没有可见输出(并且仅在生成的 pdf 中生成范围,没有路径指令)。第一条路径由intermediate
的组成,即段,表示“第一个参数()的第一个(第 0 个)段”。从图形上看,这是填充区域(蓝色和棕色)的左下边缘。第一个参数始终在此上下文中调用,段索引从 0 开始。此段与相连,表示第二个参数的第二个(第 1 个)段(即的第二个段)。intersection segments
fun2 and fun3
A0
fun2
A
B1
of=fun2 and fun3
fun3
第二\path
条指令计算intersection segments
。intermediate and fun4
请记住fun4
是顶部路径(橙色路径)。在这里,我们取A0
( 的第一个交叉段intermediate
)并将其与B1
( 的第二个 = 第 1 个段fun4
)连接起来。
这两条指令都\path
不会产生可见的输出(除非您插入取消注释的draw
键)。它们仅将结果存储在名称下。
最后,最后一条语句填充了我们计算的和\addplot fill between
之间的区域。为此,它使用了填充选项。segments
fun1
gray,fill opacity=0.25