在 TikZ 中绘制二元正态分布

在 TikZ 中绘制二元正态分布

对于小班,我想绘制一个二元正态分布,并显示两个变量的均值在空间中相交的位置。有人在 TikZ 中做过这个吗?

答案1

克里斯蒂安的速度更快,但是因为我投入了时间,所以这里是我展示双变量分布如何由两个单变量分布产生的看法。

代码中有几项可能对你有用:

您可以使用定义数学函数declare function={<name>(<argument macros>)=<function>;},这将有助于保持代码清洁并避免重复。

您可以使用 定义新的颜色图\pgfplotsset{ colormap={<name>}{<color model>(<distance>)=(<value1>); <color model>(<distance 2>)=(<value2>)} }。这是一个非常强大的功能,因此您一定要在手册中阅读它pgfplots

所创建的图例colorbar是一个全新的情节,因此您可以使用所有常用axis选项对其进行配置。

定义 3D 函数有不同的方法:\addplot3 {<function>};<function>在网格上的每个点进行评估并假定结果为 z 值。\addplot3 ({<x>},{<y>},{<z>});在 3D 空间中定义参数函数,这允许您(除其他外)绘制三维线条。

\documentclass{standalone}

\usepackage{pgfplots}

\begin{document}

\pgfplotsset{
colormap={whitered}{color(0cm)=(white); color(1cm)=(orange!75!red)}
}

\begin{tikzpicture}[
    declare function={mu1=1;},
    declare function={mu2=2;},
    declare function={sigma1=0.5;},
    declare function={sigma2=1;},
    declare function={normal(\m,\s)=1/(2*\s*sqrt(pi))*exp(-(x-\m)^2/(2*\s^2));},
    declare function={bivar(\ma,\sa,\mb,\sb)=
        1/(2*pi*\sa*\sb) * exp(-((x-\ma)^2/\sa^2 + (y-\mb)^2/\sb^2))/2;}]
\begin{axis}[
    colormap name=whitered,
    width=15cm,
    view={45}{65},
    enlargelimits=false,
    grid=major,
    domain=-1:4,
    y domain=-1:4,
    samples=26,
    xlabel=$x_1$,
    ylabel=$x_2$,
    zlabel={$P$},
    colorbar,
    colorbar style={
        at={(1,0)},
        anchor=south west,
        height=0.25*\pgfkeysvalueof{/pgfplots/parent axis height},
        title={$P(x_1,x_2)$}
    }
]
\addplot3 [surf] {bivar(mu1,sigma1,mu2,sigma2)};
\addplot3 [domain=-1:4,samples=31, samples y=0, thick, smooth] (x,4,{normal(mu1,sigma1)});
\addplot3 [domain=-1:4,samples=31, samples y=0, thick, smooth] (-1,x,{normal(mu2,sigma2)});

\draw [black!50] (axis cs:-1,0,0) -- (axis cs:4,0,0);
\draw [black!50] (axis cs:0,-1,0) -- (axis cs:0,4,0);

\node at (axis cs:-1,1,0.18) [pin=165:$P(x_1)$] {};
\node at (axis cs:1.5,4,0.32) [pin=-15:$P(x_2)$] {};
\end{axis}
\end{tikzpicture}
\end{document}

答案2

您需要对双变量函数进行采样并选择适当的绘图类型。典型的选择是网格图、曲面图或轮廓图。我认为最常见的是曲面图。

无论如何,TikZ 不支持双变量函数 - 但您可以使用pgfplots它构建的函数,它可以轻松集成到 tikz 中。我应该指出,我是 pgfplots 的作者。以下是它可以提供的帮助:

在此处输入图片描述

\documentclass[a4paper]{article}
\usepackage{pgfplots}

\begin{document}

\def\centerx{2}
\def\centery{-1}
\begin{tikzpicture}
    \begin{axis}
    \addplot3[surf,domain=-2:6,domain y=-5:3] 
        {exp(-( (x-\centerx)^2 + (y-\centery)^2)/3 )};
    \node[circle,inner sep=1pt,fill=blue,pin=90:$\mu$] 
        at (axis cs:\centerx,\centery,1) {};
    \end{axis}
\end{tikzpicture}
\end{document}

您将看到,该示例不是真正的正态分布,因为它没有被标准化为单位积分(它被标准化为单位最大范数)。

但该示例显示了关键方面:

  1. 选择surf
  2. 指定绘图表达式
  3. 调整domaindomain y(还考虑samplessamples y
  4. a\node以“某种方式”描述中心。

Pgfplots 还支持网格图(使用mesh而不是surf)或轮廓图(使用contour gnuplot而不是surf;在这种情况下,您需要 gnuplot 和类似 的 shell-escape 功能pdflatex -shell-escape):

在此处输入图片描述

\def\centerx{2}
\def\centery{-1}
\begin{tikzpicture}
    \begin{axis}[view={0}{90},axis equal]
    \addplot3[contour gnuplot,domain=-2:6,domain y=-5:3] 
        {exp(-( (x-\centerx)^2 + (y-\centery)^2)/3 )};
    \node[circle,inner sep=1pt,fill=blue,pin=90:$\mu$] 
        at (axis cs:\centerx,\centery,1) {};
    \end{axis}
\end{tikzpicture}

第二个例子还表明view可以用来改变视角(水平和垂直角度),并且axis equal可能对获得可比的轴比感兴趣(我必须承认,这种组合view={0}{90},axis equal似乎会产生意外的编译错误 - 我会解决这个问题)。

可能还感兴趣的是手册中列出的shader=interp各种选择。colormap

相关内容