我有以下 Tex 函数,我想在我的 tex 论文中绘制它们,但我不知道如何绘制。我的意思是,我希望 Tex 绘制函数,而不仅仅是向其中包含外部图像。
y[\text{x$\_$},\text{m$\_$},\text{n$\_$}]\text{:=}\text{Abs}\left[1-\left(1-\left(\frac{x+1}{2}\right)^2\right){}^{\wedge}m\right]{}^{\wedge}n;
\text{F}[\text{x$\_$},\text{m$\_$},\text{n$\_$}]\text{:=}(-y[0,m,n]+(y[0,m,n]-1)x+y[x,m,n])/(1-2y[0,m,n])
\text{Plot}[\{\text{F}[x,0.2,0.5],\text{F}[x,1,5],\text{F}[x,1,10]\},\{x,-1,1\}]
答案1
以下是使用 pgfplots + lualatex 的解决方案(即必须使用以下命令进行编译lualatex P.tex
:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\begin{document}
\begin{tikzpicture}
\directlua{
Y = function(x,m,n)
return math.abs(1-(1-((x+1)/2)^2)^m)^n
end
N1 = function(x,m,n)
return (-Y(0,m,n) + (Y(0,m,n)-1)*x + Y(x,m,n))/ (1-2*Y(0,m,n))
end
}
\pgfmathdeclarefunction{N1}{3}{%
\edef\pgfmathresult{\directlua{tex.print(N1(\pgfmathfloatvalueof{#1},\pgfmathfloatvalueof{#2},\pgfmathfloatvalueof{#3}))}}%
}%
\begin{axis}[
axis lines=center,
enlargelimits,
tick align=inside,
no markers,
legend entries={$N1(x,0.2,0.5)$\\$N1(x,1,5)$\\$N1(x,1,10)$\\},
domain=-1:0.99999,
samples=150,
minor tick num=4,
]
\addplot {N1(x,0.2,0.5)};
\addplot {N1(x,1,5)};
\addplot {N1(x,1,10)};
\end{axis}
\end{tikzpicture}
\end{document}
一些评论:
- 我使用 Lua 是为了受益于其更高的精度 - N1 的当前公式在 x=-1 附近存在数值不稳定性(即输入中的小错误会导致输出中的巨大错误)。这需要比 TeX 通过其内置方法提供的更高的精度。
- 我忽略了重复使用 值的可能性
y(0,m,n)
。计算两次并没有什么坏处。 - 添加
cycle list={dashed,black,black}
到轴的选项列表中以获取您的绘图样式 - 我更喜欢默认循环列表(带有no markers
),以便您可以在图例中识别每一个(也是我添加的)。 N1
请注意,我选择通过 来定义 PGF 数学函数。这允许我们在 PGF 数学表达式中\pgfmathdeclarefunction
使用(特别是:在 中)。参数意味着新函数有三个参数,可用作宏中的、和。目前,这些参数采用浮点库(在 TeX 中)生成的某种内部格式,因此我们需要将它们转换回 Lua 可以理解的格式(通过 )。N1(x,m,n)
\addplot {<expression>}
{3}
#1
#2
#3
\pgfmathfloatvalueof
- 因为我从来没有直接绘图
Y
,所以我没有生成\pgfmathdeclarefunction
forY
——毕竟,Lua 代码可以以自包含的方式计算这一点。 - 请注意
\pgfmathdeclarefunction
应该将结果分配给宏\pgfmathresult
,这就是 的目的\edef\pgfmathresult
。这tex.print
是 Lua 将结果报告回 TeX 的方式。
一般来说,使用 PGF 的数学引擎来制定函数是安全的,结果是
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\begin{document}
\begin{tikzpicture}
\pgfmathdeclarefunction{Y}{3}{%
\pgfmathparse{abs(1-(1-((#1+1)/2)^2)^(#2))^(#3)}%
}%
\pgfmathdeclarefunction{N1}{3}{%
\pgfmathparse{(-Y(0,#2,#3) + (Y(0,#2,#3)-1)*(#1) + Y(#1,#2,#3))/ (1-2*Y(0,#2,#3)}%
}%
\begin{axis}[
axis lines=center,
enlargelimits,
tick align=inside,
no markers,
legend entries={$N1(x,0.2,0.5)$\\$N1(x,1,5)$\\$N1(x,1,10)$\\},
domain=-1:0.99999,
samples=150,
minor tick num=4,
]
\addplot {N1(x,0.2,0.5)};
\addplot {N1(x,1,5)};
\addplot {N1(x,1,10)};
\end{axis}
\end{tikzpicture}
\end{document}
请注意 x=-1 附近可见的伪影;它源于 x=-1 附近数值不稳定的函数公式与 TeX 的有限精度相结合(除非我弄错了)。
答案2
你可以使用gnuplot
来绘制这些。例如,你可以使用以下代码:
\documentclass{standalone}
\makeatletter\newwrite\verbatim@out\makeatother
\usepackage{gnuplottex}
\usepackage{epstopdf}
\begin{document}
\begin{gnuplot}[terminal=epslatex]
set samples 2000 # Set to get more accurate, but slower
set parametric
set xtics -1,.5,1
set ytics -1,.5,1
set trange [-1:1] # Parametric plot range
set xrange [-1.1:1.1] # Axis range
set zeroaxis
set border 0
set xtics axis
set ytics axis
y(x,m,n) = (abs(1-(1-((x+1)/2)**2)**m))**n
N(x,m,n) = (-y(0,m,n) + (y(0,m,n) - 1)*x + y(x,m,n))/(1 - 2*y(0,m,n))
plot t,N(t,0.2,0.5) title "", t,N(t,1,5) title "", t,N(t,1,10) title ""
\end{gnuplot}
\end{document}
您需要使用该--shell-escape
选项进行编译,并且格努普特已安装。
正如您在代码中看到的,在 gnuplot 中定义和使用函数非常容易,甚至具有多个参数。
渲染:
答案3
* 编辑 *添加了虚线图案、图例和几个标签;还使用了成对mn[]
数组(m,n)
来创建函数N1(m,n)(x)
,而不是函数数组。
% f.tex:
%
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}
\begin{figure}
\centering
\begin{asy}[width=8cm]
size(9cm);
import graph;
import fontsize;
defaultpen(fontsize(9pt));
pen dashed=linetype(new real[] {4,4});
pen longdashed=linetype(new real[] {12,4});
pen dotted=linetype(new real[] {0,3});
pen[] fpen={
gray+longdashed,
black+dotted,
black+dashed
};
real y(real x,real m,real n){
return abs(1-(1-((x+1)/2)^2)^m)^n;
}
typedef real Func(real);
Func N1(real m,real n){
return
new real(real x){
return (-y(0,m,n)+(y(0,m,n)-1)*x+y(x,m,n))/(1-2y(0,m,n));
};
}
pair[] mn={(0.2,0.5),(1,5), (1,10)};
real xmin=-1, xmax=1;
xaxis(xmin,xmax,LeftTicks(Label(LeftSide),Step=0.5,step=0.1,OmitTick(0)));
yaxis(RightTicks(Step=0.5,step=0.1,OmitTick(0)));
real penwidth=1bp;
real m,n;
for(int i=0;i<mn.length;++i){
m=mn[i].x; n=mn[i].y;
draw(graph(N1(m,n),xmin,xmax,n=400),fpen[i]+penwidth
,legend="$N_1("+string(m)+","+string(n)+")$"
);
}
label("$x$",1.1*(xmax,0),S); // 1.1*(xmax,0) is a location,
// alignment S == (0,-1) means "South"
m=mn[2].x; n=mn[2].y;
label("$("+string(m)+","+string(n)+")$",
(0.6,N1(m,n)(0.6))
,SW
);
add(
legend(linelength=0.5legendlinelength,nullpen) // here nullpen means no frame
,point(NE),SW,UnFill
);
\end{asy}
\caption{Family of functions $N_1(x,m,n)$}
\end{figure}
\end{document}
处理如下:
pdflatex f.tex
asy f-*.asy
pdflatex f.tex
* ======== 第一个版本 ======== *
Asymptote
使用(这是TeXLive
分布的一部分,已经有一段时间了)绘制此类函数系列非常简单。在asy
环境中,函数N1(m,n)
使用参数m
和“n”创建一个新的实值函数,该函数接受一个实数参数。所有需要绘制的函数都收集在数组中f[]
,然后使用准备好的笔数组在循环内绘制fpen[]
。
% f.tex:
%
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}
\begin{figure}
\centering
\begin{asy}[width=7cm]
import graph;
import fontsize;
defaultpen(fontsize(9pt));
pen dashed=linetype(new real[] {4,4});
pen[] fpen={
deepblue+dashed,
black,
orange
};
real y(real x,real m,real n){
return abs(1-(1-((x+1)/2)^2)^m)^n;
}
typedef real Func(real);
Func N1(real m,real n){
return
new real(real x){
return (-y(0,m,n)+(y(0,m,n)-1)*x+y(x,m,n))/(1-2y(0,m,n));
};
}
Func[] f={ N1(0.2,0.5), N1(1,5), N1(1,10) };
real xmin=-1, xmax=1;
xaxis(xmin,xmax,LeftTicks(Label(LeftSide),Step=0.5,step=0.1,OmitTick(0)));
yaxis(RightTicks(Step=0.5,step=0.1,OmitTick(0)));
real penwidth=1bp;
for(int i=0;i<f.length;++i){
draw(graph(f[i],xmin,xmax),fpen[i]+penwidth);
}
\end{asy}
\caption{Family of functions $N_1(x,m,n)$}
\end{figure}
\end{document}
处理如下:
pdflatex f.tex
asy f-*.asy
pdflatex f.tex
PS,我希望你不要将这一步asy f-*.asy
视为太多额外的工作。
答案4
基于一个答案到这个问题,我绘制了如下图所示的图(感谢克里斯蒂安·费尔桑格)。我之所以选择这个答案,是因为它对我这个 LaTeX 基础用户来说很容易,而且我更容易理解流程、功能、代码等。此外,它能够定义不同的功能,而且确实可定制。
\documentclass[varwidth=true, border=10pt, convert={size=640x}]{standalone}
\usepackage{blindtext}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\begin{document}
\begin{tikzpicture}
\directlua{
Y = function(x,m,n)
return math.abs(1-(1-((x+1)/2)^2)^m)^n
end
N1 = function(x,m,n)
return (-Y(0,m,n) + (Y(0,m,n)-1)*x + Y(x,m,n))/ (1-2*Y(0,m,n))
end
}
\pgfmathdeclarefunction{N1}{3}{%
\edef\pgfmathresult{\directlua{tex.print(N1(\pgfmathfloatvalueof{#1},\pgfmathfloatvalueof{#2},\pgfmathfloatvalueof{#3}))}}%
}%
\begin{axis}
[
grid=major,
axis lines=center,
enlargelimits,
tick align=inside,
cycle list ={solid,dotted,dashed},
legend style={at={(0.5,-0.05)},
anchor=north,legend columns=-1},
legend entries={$m=1,n=1$\\$m=1,n=5$\\$m=1,n=10$\\},
domain=-1:0.99999,
samples=200,
minor tick num=5,
xlabel=$x$,
ylabel=$N_{AG - 3}^{\left( 1 \right)}$
]
\addplot {N1(x,1,1)};
\addplot {N1(x,1,5)};
\addplot {N1(x,1,10)};
\end{axis}
\end{tikzpicture}
\end{document}