我想要做的是绘制一个函数(使用 定义\newcommand{\f}[1]{expression}
),pgfplots
然后使用 绘制 N+1 条线。每条线从(轴 cs:x,0)到(轴 cs:x,f(x)),其中 x 在(0,1/N,2/N,...,1)中。
我尝试使用\foreach
循环,但在 中不起作用pgfplots
。因此我尝试用 替换它\pgfplotsinvokeforeach
,但在将其放入坐标内之前,我仍然必须找到某种方法来计算 f(x)。
我尝试使用\pgfmathsetmacro\foo{\f{#1}}
,但似乎只有最后一个值卡住了,好像它等到循环结束后才绘制线条。因此,我没有得到点
(0,f(0)),(1/N,f(1/N)),...,(1,f(1)),而是
得到了(0,f(1)),(1/N,f(1)),... ,(1,f(1))。
有没有简单的方法可以做到这一点?
代码:
\begin{tikzpicture}
\begin{axis}[
xlabel = ,
ylabel = ,
axis lines = middle,
xtick ={1,4},
ytick ={0},
xticklabels = {$a$,$b$},
ymin = -0.2,
ymax = 3.7,
xmin = -0.2,
xmax = 5.2,
x=2cm,y=2cm,
axis line style = thick,
]
\newcommand{\f}[1]{2+sin(deg(#1-2))+sin(deg(3*#1))/2+sin(deg(5*#1))/8 + sin(deg(7*#1))/28}
\addplot[domain=0:5, samples = 300, line width = 1pt, colorOne, name path = f]{\f{x}};
\path [name path = axis] (axis cs:1,0) -- (axis cs:4,0);
\addplot [thick, color = colorOne, fill = colorOne, fill opacity=0.2]
fill between[of=f and axis, soft clip = {domain=1:4}];
\pgfplotsinvokeforeach{1,1.2,...,4}{
\pgfmathsetmacro\fAtPoint{\f{#1}}
\draw[line width = 1pt, colorOne] (axis cs:#1,0) -- (axis cs: #1,\fAtPoint);
}
\end{axis}
\end{tikzpicture}
注意:我不是从 0 到 1,而是尝试以 1/N = 0.2 从 1 到 4
我最终使用了此解决方案但我想知道如何使用 for 循环来实现它。
答案1
使用 PGFPlots,虽然可以在环境中循环使用“常规”TikZ 命令,但这需要特别注意,因为命令不会在第一次遇到时执行,而是在完成其他操作(如确定轴限值)后存储和执行。一般来说,最好尽可能axis
使用命令。\addplot
就您而言,您无需“手动”绘制垂直线,只需使用ycomb
关闭标记的绘图样式即可。要指定在哪个 x 位置绘制线条,您可以使用samples at={1,1.2,...,4}
(键使用与 相同的语法\foreach
)。
顺便说一句,您可以使用 TikZ 键 ,而不是为该函数定义宏declare function = {f(\x) = ...;}
。这样,您只需使用f(x)
而不是 ,就可以在数学解析器中调用该函数\f{x}
。
而且,您不需要使用库,只需在命令末尾fillbetween
添加即可在绘图和 x 轴之间进行填充。\closedcycle
\addplot
\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{intersections}
\usepgfplotslibrary{fillbetween}
\begin{document}
\begin{tikzpicture}[
declare function={
f(\x)=2+sin(deg(\x-2))+sin(deg(3*\x))/2+sin(deg(5*\x))/8 + sin(deg(7*\x))/28;
}
]
\begin{axis}[
axis lines = middle,
xtick ={1,4},
ytick ={0},
xticklabels = {$a$,$b$},
ymin = -0.2,
ymax = 3.7,
xmin = -0.2,
xmax = 5.2,
x=2cm,y=2cm,
axis line style = thick,
]
\addplot [
domain=1:4,
samples=300,
line width=1pt,
fill=red, draw=none,
fill opacity=0.2
] {f(x)} \closedcycle;
\addplot [
domain=0:5,
samples=300,
line width = 1pt, red
] {f(x)};
\addplot [
ycomb, thick, red,
no markers,
samples at={1,1.2,...,4}
] {f(x)};
\end{axis}
\end{tikzpicture}
\end{document}
如果你确实想使用循环,你可以使用declare function
上面描述的命令定义你的函数,然后使用
\pgfplotsinvokeforeach{1,1.2,...,4}{
\draw [thick, red] (axis cs:#1,0) -- (axis cs:#1, {f(#1)});
}
或者
\pgfplotsextra{
\foreach \x in {1,1.2,...,4}{
\draw [thick, red] (axis cs:\x,0) -- (axis cs:\x, {f(\x)});
}
}
该\pgfplotsextra
方法也适用于您的宏定义和\pgfmathsetmacro
。
如果您设置\pgfplotsset{compat=1.12}
或更高,则可以省略axis cs
,因为它默认被激活。