我正在尝试在 tikz 中以 3D 形式绘制以下方程。
我有像这样的基本前提设置,并将样本设置为数据表。
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\begin{document}
% sample points
\pgfplotstableread{
X Y Z m
2.2 14 0 0
2.7 23 0 0
3 13 0 0
3.55 22 0 0
4 15 0 0
4.5 20 0 0
4.75 28 0 0
5.5 23 0 0
}\datatablet
% Trying to recreate gnuplot here
% https://en.wikipedia.org/wiki/Partial_derivative
\begin{tikzpicture}
\begin{axis}[
grid=both,
ztick={0,4,...,10},
zmin = 0, zmax = 10,
point meta min=0,
point meta max=10,
colormap/cool,
view={30}{30} %tune here to change viewing angle
]
\addplot3[surf,shader=faceted, domain=-2:2] {(x - y)^2};
\end{axis}
\end{tikzpicture}
\end{document}
让我困惑的是 RHS 上的求和部分。我该如何计算呢?对于每个 x 和 y 值,我需要逐个获取表格条目,计算、求和,然后进行绘图。我想不出一个简单的 for 循环场景来执行此操作。请帮忙。
这里是一份关于如何在 Python 中构建它的简单文档,如果它有帮助的话(尤其是对于循环和求和部分)
答案1
令我惊讶的是,可能的实现这样的求和,甚至不是特别困难。我专注于求和。解决方法是将求和放在一个循环中,然后让 pgfplots 解析它。令人惊讶的是,这有效。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\pgfplotstableread{
X Y Z m
2.2 14 0 0
2.7 23 0 0
3 13 0 0
3.55 22 0 0
4 15 0 0
4.5 20 0 0
4.75 28 0 0
5.5 23 0 0
}\datatablet
% from https://tex.stackexchange.com/a/445369/121799
\newcommand*{\ReadOutElement}[4]{%
\pgfplotstablegetelem{#2}{#3}\of{#1}%
\let#4\pgfplotsretval
}
% based on https://tex.stackexchange.com/a/307032/121799
% and https://tex.stackexchange.com/a/451326/121799
\newcommand{\GetColumn}[2]{
\pgfplotstablegetrowsof{\datatablet}
\pgfmathtruncatemacro{\rownumber}{\pgfplotsretval-1}
\xdef#2{0} % add a zero to have some 0th entry
\foreach \XX in {0,...,\rownumber}
{
\ReadOutElement{\datatablet}{\XX}{#1}{\tmp}
\xdef#2{#2,\tmp}
}
}
% read out x and y values
\GetColumn{X}{\xvalues}
\xdef\xvalues{{\xvalues}}
\GetColumn{Y}{\yvalues}
\xdef\yvalues{{\yvalues}}
% define the single terms in the sum: \x and \y represent x_i and y_i
% while \a and \b stand for \beta_0 and \beta_1, respectively
\tikzset{
declare function={myn(\x,\y,\a,\b)=(\y-(\a+\b*\x))*(\y-(\a+\b*\x));
}}
\pgfplotstablegetrowsof{\datatablet}
\pgfmathtruncatemacro{\rownumber}{\pgfplotsretval}
\pgfmathsetmacro{\tmpx}{\xvalues[1]}
\pgfmathsetmacro{\tmpy}{\yvalues[1]}
\xdef\tmpN{myn(\tmpx,\tmpy,x,y)}
\foreach \X in {2,...,\rownumber}
{
\pgfmathsetmacro{\tmpx}{\xvalues[\X]}
\pgfmathsetmacro{\tmpy}{\yvalues[\X]}
\xdef\tmpN{\tmpN+myn(\tmpx,\tmpy,x,y)}
}
\typeout{N(x,y)=\tmpN}
\begin{tikzpicture}
\begin{axis}[
grid=both,
colormap/cool,
view={30}{30} %tune here to change viewing angle
]
\addplot3[surf,shader=faceted, domain=-40:40,domain y=-40:40] {-1*(\tmpN)};
\end{axis}
\end{tikzpicture}
\end{document}
最多一些x dir=reverse
和/或y dir=reverse
,这看起来非常类似于您的 python 图。性能也比使用 tikzmath 获得的性能要好一点,无论如何,由于发生冲突fpu
。
...这是一个稍微简短的版本,但是功能相同。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\pgfplotstableread{
X Y Z m
2.2 14 0 0
2.7 23 0 0
3 13 0 0
3.55 22 0 0
4 15 0 0
4.5 20 0 0
4.75 28 0 0
5.5 23 0 0
}\datatablet
% from https://tex.stackexchange.com/a/445369/121799
\newcommand*{\ReadOutElement}[4]{%
\pgfplotstablegetelem{#2}{#3}\of{#1}%
\let#4\pgfplotsretval
}
% define the single terms in the sum: \x and \y represent x_i and y_i
% while \a and \b stand for \beta_0 and \beta_1, respectively
\tikzset{
declare function={myn(\x,\y,\a,\b)=(\y-(\a+\b*\x))*(\y-(\a+\b*\x));
}}
\pgfplotstablegetrowsof{\datatablet}
\pgfmathtruncatemacro{\rownumber}{\pgfplotsretval-1}
\ReadOutElement{\datatablet}{0}{X}{\tmp}
\xdef\tmpx{\tmp}
\ReadOutElement{\datatablet}{0}{Y}{\tmp}
\xdef\tmpy{\tmp}
\xdef\tmpN{myn(\tmpx,\tmpy,x,y)}
\foreach \X in {1,...,\rownumber}
{
\ReadOutElement{\datatablet}{\X}{X}{\tmp}
\xdef\tmpx{\tmp}
\ReadOutElement{\datatablet}{\X}{Y}{\tmp}
\xdef\tmpy{\tmp}\xdef\tmpN{\tmpN+myn(\tmpx,\tmpy,x,y)}
}
\typeout{N(x,y)=\tmpN}
\begin{tikzpicture}
\begin{axis}[
grid=both,
colormap/cool,
view={30}{30} %tune here to change viewing angle
]
\addplot3[surf,shader=faceted, domain=-40:40,domain y=-40:40] {-1*(\tmpN)};
\end{axis}
\end{tikzpicture}
\end{document}