对于小班,我想绘制一个二元正态分布,并显示两个变量的均值在空间中相交的位置。有人在 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}
您将看到,该示例不是真正的正态分布,因为它没有被标准化为单位积分(它被标准化为单位最大范数)。
但该示例显示了关键方面:
- 选择
surf
- 指定绘图表达式
- 调整
domain
和domain y
(还考虑samples
和samples y
) - 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