在 PGFplots 轴环境中注释/绘制带斜率的三角形

在 PGFplots 轴环境中注释/绘制带斜率的三角形

在期刊论文中,我经常看到图中的注释,描绘具有特定斜率的三角形,以强调图中不同图形(大致)具有哪些斜率。

例如

是否有宏可以LaTeX轻松进行此类注释?那么,给定轴上的相对位置和斜率,在轴上的相对位置绘制具有此斜率的三角形?

答案1

% Mind section '4.17 Custom annotations' of the PGFplots manual Revision 1.12 (2015/01/31).
\documentclass[margin=1cm]{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=newest}

%%% START MACRO %%%
\newcommand{\slopeTriangle}[5]
{
    % #1. Relative offset in x direction.
    % #2. Width in x direction, so xA-xB.
    % #3. Relative offset in y direction.
    % #4. Slope dydx.
    % #5. Plot options.

    \pgfplotsextra
    {
        \pgfkeysgetvalue{/pgfplots/xmin}{\xmin}
        \pgfkeysgetvalue{/pgfplots/xmax}{\xmax}
        \pgfkeysgetvalue{/pgfplots/ymin}{\ymin}
        \pgfkeysgetvalue{/pgfplots/ymax}{\ymax} 

        % Calculate auxilliary quantities.
        \pgfmathsetmacro{\xA}{\xmin+(#1+#2)*(\xmax-\xmin)}
        \pgfmathsetmacro{\yA}{\ymin+#3*(\ymax-\ymin)}
        \pgfmathsetmacro{\xB}{\xmin+#1*(\xmax-\xmin)}
        \pgfmathsetmacro{\yB}{\yA}
        \pgfmathsetmacro{\xC}{\xA}
        \pgfmathsetmacro{\yC}{\yA+(\xA-\xB)*#4}

        % Define coordinates for \draw.
        \coordinate (A) at (axis cs:\xA,\yA);
        \coordinate (B) at (axis cs:\xB,\yB);
        \coordinate (C) at (axis cs:\xC,\yC);

        % Draw slope triangle.
        \draw[#5]   (A)-- node[pos=0.5,anchor=north] {1}
                    (B)-- 
                    (C)-- node[pos=0.5,anchor=west] {#4}
                    cycle;
    }
}
%%% END MACRO %%%

\begin{document}
    \begin{tikzpicture}
        \begin{axis}
        [
            xtick={-0.1,0,1,1.1},
            xlabel=$x$,
            ytick={-0.2,0,2,2.2},
            ylabel style={rotate=-90},
            ylabel=$y$,
            unit vector ratio=2 1 1,
            clip=false
        ]
            \addplot[blue,domain=0:1] {x};
            \addplot[red,domain=0:1] {2*x};

            \slopeTriangle{0.65}{0.1}{0.1}{1}{blue}; % USE OF MACRO.
            \slopeTriangle{0.825}{0.1}{0.1}{2}{red}; % USE OF MACRO.
        \end{axis}
    \end{tikzpicture}
\end{document}

答案2

MetaPost 解决方案。我刚好已经为我目前正在教授的一门课程设计了这样一个宏,它可以应用于任何函数曲线。这里是它,稍加修改后应用于抛物线y = 4x-x^2。斜率由 MetaPost 本身计算,并借助该包四舍五入为任意位数numprint。(由于已知这里的斜率具有整数值,我已指示numprint将它们四舍五入为最接近的整数:\nprounddigits{0},但可以随意更改。)

为了更加方便,MetaPost 编码已插入 LuaLaTeX 程序中:

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
  \mplibsetformat{metafun}
  \mplibtextextlabel{enable}
  \mplibnumbersystem{double}
\usepackage{numprint}
  \nprounddigits{0}
\begin{document}
  \begin{mplibcode}
    input mpcolornames; 
    % Parameters
    numeric u, v, xmin, xmax, xstep, ymin, ymax;
    u = v = 1cm; xmin = -2; xmax = 6; xstep = 0.1;
    ymin = -6; ymax = 6;
    % Graph definition
    vardef f (expr x) = 4x - x**2 enddef;
    path my_graph; 
    my_graph = function(2, "x", "f(x)", xmin, xmax, xstep);
    % Macro creating triangle with slope
    def triangle_with_slope(expr p, A) =
      % Basis and height
      h := 1; a := xpart A; b := a + h;
      % Direction
      pair vdir, B; 
      vdir = direction ((a-xmin)/xstep) of p; 
      B = A + vdir/xpart(vdir);
      % tangent and triangle
      path tangente, Delta_x, Delta_y, triangle; 
      Delta_x = (A -- (xpart B, ypart A)) xyscaled (u, v);
      Delta_y = ((xpart B, ypart A) -- B) xyscaled (u, v);
      tangente = (A -- B) xyscaled (u, v);      
      triangle = (A -- (xpart B, ypart A) -- B -- cycle) xyscaled (u, v);
      % The drawing
      drawoptions(withcolor DarkRed);
      fill triangle withcolor Pink; draw tangente;
      drawarrow Delta_x; drawarrow Delta_y;
      drawdot A xyscaled (u, v) withpen pencircle scaled 3bp;
      % Labels
      string slope; slope := decimal(ypart(B-A));
      labeloffset := 2bp;
      label. if ypart(B-A)>0: bot else: top fi ("$1$", point .5 of Delta_x);
      freelabel("$\numprint{" & slope & "}$", point .5 of Delta_y, center triangle);
      drawoptions( );
    enddef;
    beginfig(1);
      % Axes        
      drawarrow (xmin*u, 0) -- (xmax*u, 0);
      drawarrow (0, ymin*v) -- (0, ymax*v);
      % Graph and triangles with slope
      for i = -1 upto 4: triangle_with_slope(my_graph, (i, f(i))); endfor
      picture parabola; parabola = image(draw my_graph xyscaled (u, v));
      clip parabola to 
        ((xmin, ymin) -- (xmax, ymin) -- (xmax, ymax) -- (xmin, ymax) -- cycle) 
          xyscaled (u, v); 
      draw parabola;
      % Marks
      labeloffset := 5bp;
      label.bot("$x$", (xmax*u, 0)); label.lft("$y$", (0, ymax*v));
      for i = -2 upto 5: if i<>0: draw (i*u, -3bp) -- (i*u, 3bp); fi endfor
      for j = -6 upto 5: if j<>0: draw (-3bp, j*v) -- (3bp, j*v); fi endfor
      label.bot("$1$", (u, 0)); label.lft("$1$", (0, v));
    endfig;
  \end{mplibcode}
\end{document}

输出:

在此处输入图片描述

相关内容