绘图说明割线

绘图说明割线

出于教学目的,我试图解释线性回归的基本工作原理以及如何扩展它。由于我不是 TeXpert,我担心我的想法可能很棘手,而且比它可能的难度更大。我见过许多带有和的漂亮tikzpgfplots

我四处寻找,最终找到了下面的图片。

在此处输入图片描述

这幅图看起来非常合适,因为我可以解释回归可能是什么样子。但问题是我无法操作,例如绘制网格、更改x_0resp的命名\epsilon、将红线更改为虚线、添加除 P 和 Q 之外的其他点等。如果函数本身是x^2或某种混合,我不介意解释。我的主要目的是说明基本思想。如果我有一个样本,那么我可以将其进一步扩展到均值、方差等。

有人愿意帮我吗?如果有人能给我提供一些现有的样本,我并不介意。这样也很好。

答案1

使用 TikZ 非常简单。我使用了 Plain TeX,因此您需要在文档末尾使用\input tikz.tex而不是\usepackage{tikz}和 而不是。\begin{document}...\end{document}\bye

使用以下代码排版pdftex

\input tikz.tex
\nopagenumbers% for cropping
\usetikzlibrary{arrows,intersections}
\tikzpicture[
        thick,
        >=stealth',
        dot/.style = {
            draw,
            fill=white,
            circle,
            inner sep=0pt,
            minimum size=4pt
        }
    ]
    \coordinate (O) at (0,0);
    \draw[->] (-0.3,0) -- (8,0) coordinate[label={below:$x$}] (xmax);
    \draw[->] (0,-0.3) -- (0,5) coordinate[label={right:$f(x)$}] (ymax);
    \path[name path=x] (0.3,0.5) -- (6.7,4.7);
    \path[name path=y] plot[smooth] coordinates {(-0.3,2) (2,1.5) (4,2.8) (6,5)};
    \scope[name intersections={of=x and y,name=i}]
        \fill[gray!20] (i-1) -- (i-2 |- i-1) -- (i-2) -- cycle;
        \draw (0.3,0.5) -- (6.7,4.7) node[pos=0.8,below right] {Sekante};
        \draw[red] plot[smooth] coordinates {(-0.3,2) (2,1.5) (4,2.8) (6,5)};
        \draw (i-1) node[dot,label={above:$P$}] (i-1) {} -- node[left] {$f(x_0)$} (i-1 |- O) node[dot,label={below:$x_0$}] {};
        \path (i-2) node[dot,label={above:$Q$}] (i-2) {} -- (i-2 |- i-1) node[dot] (i-12) {};
        \draw (i-12) -- (i-12 |- O) node[dot,label={below:$x_0 + \varepsilon$}] {};
        \draw[blue,<->] (i-2) -- node[right] {$f(x_0 + \varepsilon) - f(x_0)$} (i-12);
        \draw[blue,<->] (i-1) -- node[below] {$\varepsilon$} (i-12);
        \path (i-1 |- O) -- node[below] {$\varepsilon$} (i-2 |- O);
        \draw[gray] (i-2) -- (i-2 -| xmax);
        \draw[gray,<->] ([xshift=-0.5cm]i-2 -| xmax) -- node[fill=white] {$f(x_0 + \varepsilon)$}  ([xshift=-0.5cm]xmax);
    \endscope
\endtikzpicture
\bye

这将产生以下输出(裁剪)

在此处输入图片描述

由于交点是由intersections库计算的,因此该解决方案是自适应的。在此代码中,实际上不是点 Q 移动,而是红线上的某个点移动,这导致 Q 移动(如果仔细观察,您会发现,当 Q 向右移动时,红线会出现难看的凸起)。

我创建动画的工作流程如下:

  • 修改源文件,使得对于每个变化在输出中创建一个单独的页面(大多数情况下使用 PGF\foreach循环,像这里一样)
  • 使用 Heiko Oberdiek 的 裁剪生成的 PDF pdfcrop
  • 导入裁剪后的 PDFGIMP
  • 在 GIMP 中:反转图层顺序并导出,就像选中.gif选项一样As Animation,延迟 200 毫秒(否则对我来说太快了)。

下面包含用于创建动画的代码。我标记了与上面的代码相比需要额外修改的行。

\input tikz.tex
\nopagenumbers% for cropping
\usetikzlibrary{arrows,intersections}
\foreach \Q in {4,4.1,4.2,...,5,4.9,4.8,...,4.1} {%<-- added
\tikzpicture[
        thick,
        >=stealth',
        dot/.style = {
            draw,
            fill=white,
            circle,
            inner sep=0pt,
            minimum size=4pt
        }
    ]
    \coordinate (O) at (0,0);
    \draw[->] (-0.3,0) -- (8,0) coordinate[label={below:$x$}] (xmax);
    \draw[->] (0,-0.3) -- (0,5) coordinate[label={right:$f(x)$}] (ymax);
    \path[name path=x] (0.3,0.5) -- (6.7,4.7);
    \path[name path=y] plot[smooth] coordinates {(-0.3,2) (2,1.5) (\Q,2.8) (6,5)};%<-- modified
    \scope[name intersections={of=x and y,name=i}]
        \fill[gray!20] (i-1) -- (i-2 |- i-1) -- (i-2) -- cycle;
        \draw (0.3,0.5) -- (6.7,4.7) node[pos=0.8,below right] {Sekante};
        \draw[red] plot[smooth] coordinates {(-0.3,2) (2,1.5) (\Q,2.8) (6,5)};%<-- modified
        \draw (i-1) node[dot,label={above:$P$}] (i-1) {} -- node[left] {$f(x_0)$} (i-1 |- O) node[dot,label={below:$x_0$}] {};
        \path (i-2) node[dot,label={above:$Q$}] (i-2) {} -- (i-2 |- i-1) node[dot] (i-12) {};
        \draw (i-12) -- (i-12 |- O) node[dot,label={below:$x_0 + \varepsilon$}] {};
        \draw[blue,<->] (i-2) -- node[right] {$f(x_0 + \varepsilon) - f(x_0)$} (i-12);
        \draw[blue,<->] (i-1) -- node[below] {$\varepsilon$} (i-12);
        \path (i-1 |- O) -- node[below] {$\varepsilon$} (i-2 |- O);
        \draw[gray] (i-2) -- (i-2 -| xmax);
        \draw[gray,<->] ([xshift=-0.5cm]i-2 -| xmax) -- node[fill=white] {$f(x_0 + \varepsilon)$}  ([xshift=-0.5cm]xmax);
    \endscope
\endtikzpicture
\eject%<-- added
}%<-- added
\bye

在此处输入图片描述

答案2

我对 TikZ 的尝试。请注意,代码可能可以更紧凑,但为了使其尽可能易于理解,我选择使其稍微冗长一些。

\documentclass[tikz,border=3pt]{standalone}
\usepackage{tikz}

\usetikzlibrary{arrows,calc}

\begin{document}

\begin{tikzpicture}[>=stealth',
                    dot/.style={circle,draw,fill=white,inner sep=0pt,minimum size=4pt}]

    % draw axis lines
    \draw[->,thick] (-0.5,0) -- ++(11,0) node[below left]{$x$};
    \draw[->,thick] (0,-0.5) -- ++(0,7) node[below right]{$f(x)$};
    \coordinate (O) at (0,0);

    % create path for function curve
    \path[thick,red] (-0.3,2) to[out=-25, in=200] coordinate[pos=0.2] (p) coordinate[pos=0.6] (q) (9,5);
    % fill area
    \fill[blue, opacity=.1] (p) -| (q);
    % draw the secant line with fixed length
    \draw[shorten <=-1.5cm] (p) -- ($ (p)!7.5cm!(q) $) node[below right, pos=0.9]{Sekante};
    % draw function curve
    \draw[thick,red] (-0.3,2) to[out=-25, in=200] (9,5);

    % draw all points
    \node[dot,label={above:$P$}] (P) at (p) {};
    \node[dot,label={above:$Q$}] (Q) at (q) {};
    \node[dot] (p1) at (P |- O) {};
    \node[dot] (p2) at (Q |- O) {};
    \node[dot] (p3) at (P -| Q) {};

    % draw lines between nodes and place text
    \draw (P) -- node[left]{$f(x_{0})$} (p1) node[dot,label={below:$x_{0}$}]{};
    \draw (p2) node[dot,label={below:$x_{0} + \varepsilon$}]{} -- (p3);
    \path (p1) -- node[below]{$\varepsilon$} (p2);

    % draw blue arrows between nodes
    \draw[<->,blue,thick] (P) -- node[below]{$\varepsilon$} (p3);
    \draw[<->,blue,thick] (Q) -- node[right]{$f(x_{0} + \varepsilon) - f(x_{0})$} (p3);

    % draw the explanation for the y-value of point Q
    \draw[help lines] (Q) -- (Q -| {(9.5,0)}) ++(-0.5,0) coordinate (p4);
    \draw[help lines, <->] (p4) -- node[fill=white,text=black]{$f(x_{0} + \varepsilon)$} (p4 |- O);

\end{tikzpicture}

\end{document}

这给出了输出

输出


动画显示了割线如何随着点的不同位置而变化沿着固定的函数曲线,下面的代码应该提供一个起点。

\documentclass[tikz,border=3pt]{standalone}
\usepackage{tikz}

\usetikzlibrary{arrows,calc}

\begin{document}

% create figures with different placement of Q along the function curve
\foreach \i in {0.45,0.46,...,0.72,0.71,0.70,...,0.46}{% <-- specify step

\begin{tikzpicture}[>=stealth',
                    dot/.style={circle,draw,fill=white,inner sep=0pt,minimum size=4pt}]

    % draw axis lines
    \draw[->,thick] (-0.5,0) -- ++(11,0) node[below left]{$x$};
    \draw[->,thick] (0,-0.5) -- ++(0,7) node[below right]{$f(x)$};
    \coordinate (O) at (0,0);

    % create path for function curve
    \path[thick,red] (-0.3,2) to[out=-25, in=200] coordinate[pos=0.2] (p) coordinate[pos=\i] (q) (9,5);
    % fill area
    \fill[blue, opacity=.1] (p) -| (q);
    % draw the secant line with fixed length
    \draw[shorten <=-1.5cm] (p) -- ($ (p)!7.5cm!(q) $) node[below right, pos=0.9]{Sekante};
    % draw function curve
    \draw[thick,red] (-0.3,2) to[out=-25, in=200] (9,5);

    % draw all points
    \node[dot,label={above:$P$}] (P) at (p) {};
    \node[dot,label={above:$Q$}] (Q) at (q) {};
    \node[dot] (p1) at (P |- O) {};
    \node[dot] (p2) at (Q |- O) {};
    \node[dot] (p3) at (P -| Q) {};

    % draw lines between nodes and place text
    \draw (P) -- node[left]{$f(x_{0})$} (p1) node[dot,label={below:$x_{0}$}]{};
    \draw (p2) node[dot,label={below:$x_{0} + \varepsilon$}]{} -- (p3);
    \path (p1) -- node[below]{$\varepsilon$} (p2);

    % draw blue arrows between nodes
    \draw[<->,blue,thick] (P) -- node[below]{$\varepsilon$} (p3);
    \draw[<->,blue,thick] (Q) -- node[right]{$f(x_{0} + \varepsilon) - f(x_{0})$} (p3);

    % draw the explanation for the y-value of point Q
    \draw[help lines] (Q) -- (Q -| {(9.5,0)}) ++(-0.5,0) coordinate (p4);
    \draw[help lines, <->] (p4) -- node[fill=white,text=black]{$f(x_{0} + \varepsilon)$} (p4 |- O);

\end{tikzpicture}
}

\end{document}

将输出 PDF 编译为 GIF(每帧 100 毫秒)后,结果如下

动画片

答案3

像往常一样,使用 PSTricks 只是为了好玩。

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-plot,pst-eucl}
\def\f{(x-1)^2/5+1}
\def\L#1#2#3{\psCoordinates[linestyle=dashed](#1)\uput[-90](#1|0,0){$#2\mathstrut$}\uput[180](0,0|#1){$#3$}}
\begin{document}
\begin{pspicture}[algebraic,saveNodeCoors,NodeCoorPrefix=N](-2,-1)(7,5)
    \psaxes[labels=none,ticks=none]{->}(0,0)(-1,-1)(6.5,4.5)[$x$,0][$y$,90]
    \psplot[linecolor=red]{-1}{5}{\f}
    \pstGeonode[PosAngle=90](*1 {\f}){P}(*3.5 {\f}){Q}
    \psdot(Q|P)
    \pcline[nodesep=-2](P)(Q)
    \L{P}{x}{f(x)}
    \L{Q}{x+\varepsilon}{f(x+\varepsilon)}
    \pcline[linecolor=blue](P)(Q|P)\nbput{$\varepsilon$}
    \pcline[linecolor=blue](Q)(!NQx NPy)\naput{$f(x+\varepsilon)-f(x)$}
    \uput[-45]([nodesep=-1]{p}Q){secant}
    \uput[0](*5 {\f}){\textcolor{red}{$y=f(x)$}}
\end{pspicture}
\end{document}

在此处输入图片描述

答案4

MetaPost 和 Asymptote 也非常擅长这种绘图。这是使用 MetaFun 格式的 MetaPost 的尝试。我尝试尽可能地重现初始图片,并使其易于根据需要调整其参数化。它将被处理mpost --mem=metafun --tex=latex file.mp(至少在 Unix 系统上)。

input latexmp; setupLaTeXMP(textextlabel=enable, mode=rerun);

vardef drawemptydot expr z = 
  save circle; path circle; circle = fullcircle scaled 3bp shifted z;
  unfill circle;
  draw circle;
enddef;

u := cm; % Unit length

beginfig(1);

xmin := -0.5; xmax := 9.5; ymin := -0.5; ymax := 6;

path curve; curve = (-0.5, 3.5){dir -30} .. (2.5, 2){dir 15} .. (5, 3.5) .. (8, 6){dir 30};

% Triangle and labels
z.P = point 1 of curve; z.Q = point 2 of curve; 
z.R = (x.Q, y.P); z.S = (x.P, 0); z.T = (x.Q, 0);
fill z.P--z.Q--z.R--cycle scaled u withcolor 0.9[blue, white];
%
drawoptions(withcolor blue);
drawdblarrow (z.P -- z.R) scaled u shortened 2bp;
drawdblarrow (z.R -- z.Q) scaled u shortened 2bp;
label.bot("$\varepsilon$", u*.5[z.P, z.R]);
label.rt("$f(x_0+\varepsilon) - f(x_0)$", u*.5[z.R, z.Q]);
%
drawoptions(withcolor black);
draw ((x.P, 0) -- z.P) scaled u;
draw ((x.Q, 0) -- z.R) scaled u;
draw (z.Q -- (xmax, y.Q)) scaled u;

% The curve
draw curve scaled u withcolor red;

% Axes
drawarrow (xmin*u, 0) -- (xmax*u, 0);
drawarrow (0, ymin*u) -- (0, ymax*u);
label.bot("$x$", (xmax*u, 0));
label.lft("$f(x)$", (0, ymax*u));

% Other labels
label.ulft("$P$", u*z.P);
label.ulft("$Q$", u*z.Q);
label.bot("$x_0$", u*z.S);
label.bot("$x_0+\varepsilon$", u*z.T);
label.bot("$\varepsilon$", u*(.5(x.P+x.Q), 0));
label.lft("$f(x_0)$", u*(.5[z.S, z.P]));

z.U = (0.8[x.Q, xmax], y.Q);
drawdblarrow ((x.U, 0) -- z.U) scaled u shortened .5bp;
picture yQ_label; yQ_label = thelabel("$f(x_0+\varepsilon)$", u*.5[(x.U, 0), z.U]);
unfill bbox yQ_label; draw yQ_label;

% Secante
path secante; secante = 1.8[z.Q, z.P] -- 2.5[z.P, z.Q] ;
draw secante scaled u;
label.lrt("Sekante", u*point .9 of secante);
forsuffixes M = P, Q, R, S, T:
  drawemptydot z.M scaled u;
endfor;

endfig;
end.

在此处输入图片描述

相关内容