PGFplots:绘制结束箭头而不指定域

PGFplots:绘制结束箭头而不指定域

我想使用 PGFplots 以标准方式(就像您在教科书中看到的一样)绘制函数。这个问题与函数上的结束箭头有关。

对于大多数函数来说,使用restrict x to domain(和y)都是可行的,但是对于渐近线存在问题,例如tan(deg(x))

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        samples=50,smooth,axis lines=middle,axis equal image=true,xmin=-3,xmax=3,ymin=-2,ymax=2,
        restrict y to domain={\pgfkeysvalueof{/pgfplots/ymin}:\pgfkeysvalueof{/pgfplots/ymax}},
        restrict x to domain={\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}}
        ]
        \addplot[ultra thick,<->,samples=150,smooth,red] {tan(deg(x))};
        \end{axis}
    \end{tikzpicture}
\end{document}

Graph of tan(x) using PGFplots

所需的输出应该在其他间隔上有箭头(渐近线的线会很好,但这可能完全是另一个问题)

Graph of tan(x) using PGFplots - desired output

我的目标是用一个命令绘制任何函数,而\addplot[color,arrows] {function(x)};无需微观管理域限制。我知道我可以手动限制域并添加同一函数的三个图。

是否有一种通用方法可以让 PGFplots 显示所有(大多数)函数(包括具有渐近线的函数)的正确箭头?这将包括基本函数,例如,,,x^2。完美的解决方案还将显示极函数,例如,尽管这超出了本问题的直接范围。\frac{1}{x}sin(x)log(x)\frac{1}{1-2*cos(\theta)}

答案1

可以告诉 pgfplots 在跳跃时添加箭头。最初我希望使用和来实现这一点jump mark leftjump mark right请参阅 pgfplotsmanual v.16 的第 80 页。但是,我无法做到这一点。所以我选择了更复杂的方法。

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{decorations.pathreplacing,calc}
\newcounter{ppoint}
\begin{document}
\begin{tikzpicture}[reset ppoint/.code={\setcounter{ppoint}{0}},
my arrows/.style={reset ppoint,
decoration={show path construction,
            curveto code={\stepcounter{ppoint}
      \ifnum\value{ppoint}=1        
      \draw[<-]  (\tikzinputsegmentfirst)  .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..(\tikzinputsegmentlast);
      \else 
      \path let \p1=($(prev0)-(\tikzinputsegmentfirst)$),\n1={veclen(\x1,\y1)}
      in \pgfextra{\ifdim\n1<1cm
      \xdef\NewStart{0}
      \else
      \xdef\NewStart{1}
      \fi};
       \ifnum\NewStart=1
        \draw[<-]  (\tikzinputsegmentfirst)  .. controls
          (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
          ..(\tikzinputsegmentlast);            
        \draw[->]  (prev0)  .. controls
          (preva) and (prevb)
          ..(prev1); 
       \else
        \draw[-]  (\tikzinputsegmentfirst)  .. controls
          (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
          ..(\tikzinputsegmentlast);
       \fi    
      \fi   
      \path (\tikzinputsegmentfirst) coordinate (prev0)
       (\tikzinputsegmentsupporta) coordinate (preva)
       (\tikzinputsegmentsupporta) coordinate (prevb)
       (\tikzinputsegmentlast) coordinate (prev1);
    }}}]
    \begin{axis}[
        samples=50,smooth,axis lines=middle,axis equal image=true,xmin=-3,xmax=3,ymin=-2,ymax=2,
        restrict y to domain={\pgfkeysvalueof{/pgfplots/ymin}:\pgfkeysvalueof{/pgfplots/ymax}},
        restrict x to domain={\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}},
        %unbounded coords=jump,
        ]
        \addplot[ultra thick,samples=150,red,smooth,
        my arrows,postaction={-,decorate},->
        ] {tan(deg(x))};
        \end{axis}
    \end{tikzpicture}
\end{document}

enter image description here

请注意,此版本仅适用于平滑图。如果您希望它也适用于非平滑曲线,您还需要添加类似的lineto code

也可以添加渐近线。但是,此版本默认渐近线是垂直的。

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{decorations.pathreplacing,calc}
\newcounter{ppoint}
\begin{document}
\begin{tikzpicture}[reset ppoint/.code={\setcounter{ppoint}{0}},
my arrows/.style={reset ppoint,
decoration={show path construction,
            curveto code={\stepcounter{ppoint}
      \ifnum\value{ppoint}=1        
      \draw[<-]  (\tikzinputsegmentfirst)  .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..(\tikzinputsegmentlast);
      \else 
      \path let \p1=($(prev0)-(\tikzinputsegmentfirst)$),\n1={veclen(\x1,\y1)}
      in \pgfextra{\ifdim\n1<1cm
      \xdef\NewStart{0}
      \else
      \xdef\NewStart{1}
      \fi};
       \ifnum\NewStart=1
        \draw[<-]  (\tikzinputsegmentfirst)  .. controls
          (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
          ..(\tikzinputsegmentlast);            
        \draw[->]  (prev0)  .. controls
          (preva) and (prevb)
          ..(prev1); 
        \path ($(prev1)!0.5!(\tikzinputsegmentfirst)$) coordinate (aux);
        \draw[dashed,cyan,thick,<->] (prev1-|aux) --
        (aux|-\tikzinputsegmentfirst);
       \else
        \draw[-]  (\tikzinputsegmentfirst)  .. controls
          (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
          ..(\tikzinputsegmentlast);
       \fi    
      \fi   
      \path (\tikzinputsegmentfirst) coordinate (prev0)
       (\tikzinputsegmentsupporta) coordinate (preva)
       (\tikzinputsegmentsupporta) coordinate (prevb)
       (\tikzinputsegmentlast) coordinate (prev1);
    }}}]
    \begin{axis}[
        samples=50,smooth,axis lines=middle,axis equal image=true,xmin=-3,xmax=3,ymin=-2,ymax=2,
        restrict y to domain={\pgfkeysvalueof{/pgfplots/ymin}:\pgfkeysvalueof{/pgfplots/ymax}},
        restrict x to domain={\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}},
        %unbounded coords=jump,
        ]
        \addplot[ultra thick,samples=150,red,smooth,
        my arrows,postaction={-,decorate},->
        ] {tan(deg(x))};
        \end{axis}
    \end{tikzpicture}
\end{document}

enter image description here

相关内容