我想说明参数化引起的拉伸。我正在使用 pgfplots 绘制参数曲线,我想根据样本索引更改曲线的颜色(例如,如果我绘制一条包含 80 个样本的曲线,我希望能够说,如果样本的索引为偶数,则线段应为红色,如果样本的索引为奇数,则线段应为蓝色)。
我使用以下代码伪造了这种效果
\documentclass[tikz,border=2mm]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-1,xmax=8,
ymin=-1,ymax=2.5,
xtick=\empty,ytick=\empty,
axis lines=middle,
]
\addplot[domain=0:.5, samples=20, ultra thick, red] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\addplot[domain=0.5:1, samples=20, ultra thick, blue] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\addplot[domain=1:1.5, samples=20, ultra thick, red] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\addplot[domain=1.5:2, samples=20, ultra thick, blue] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\end{axis}
\end{tikzpicture}
\end{document}
要得到
但我不想手动指定一堆具有不同域的图。理想情况下,我还可以指定颜色渐变,并使用它来确定曲线每部分的颜色。
答案1
这个怎么样:
\documentclass[tikz,border=2mm]{standalone}
\usepackage{pgfplots}
\makeatletter
\newcount\alternatinglineparity
\newdimen\tempx
\newdimen\tempy
\tikzset{alternating/.code={\let\tikz@plot@handler\pgfplothandleralternatinglineto}}
% Copied from \pgfplothandlerlineto.
\def\pgfplothandleralternatinglineto{
\pgfkeys {/pgf/plots/@handler options/.cd,
start=\relax,
end macro=\relax,
point macro=\pgfutil@gobble,
jump macro=\relax,
special macro=\pgfutil@gobble,
% only difference is \alternatinglinetolinehandler instead of \pgfpathlineto:
point macro=\alternatinglinetolinehandler ,
jump=\global \let \pgf@plotstreampoint\pgf@plot@line@handler@move
}
}
\def\alternatinglinetolinehandler#1{
\pgfpathmoveto{#1}%
% I added this line -- initialize parity to even:
\global\alternatinglineparity=0\relax
\global\let\pgf@plotstreampoint=\alternatinglineto%
}
\def\alternatinglineto#1{
\global\advance\alternatinglineparity1\relax
\ifodd\alternatinglineparity\relax
\color{blue}
\else
\color{red}
\fi
\tempx=\pgf@x % save registers
\tempy=\pgf@y
\pgfpathlineto{#1}
\pgfusepath{draw} % this screws up the registers
\pgf@x=\tempx % restore them
\pgf@y=\tempy
\pgfpathmoveto{#1} % set up next line segment
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-1,xmax=8,
ymin=-1,ymax=2.5,
xtick=\empty,ytick=\empty,
axis lines=middle,
]
\addplot[domain=0:2, samples=80, ultra thick,alternating] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\end{axis}
\end{tikzpicture}
\end{document}
输出(请注意,实际结果不是锯齿状的,这只是图片的伪影):
答案2
通过尝试坐标过滤器,我能够以另一种方式实现效果。
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{decorations.text}
\usepackage{tikz}
\tikzset{>=latex}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usetikzlibrary{patterns,decorations.pathreplacing}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\begin{tikzpicture}
\begin{axis}[
xmin=-1,xmax=8,
ymin=-1,ymax=2.5,
xtick=\empty,ytick=\empty,
axis lines=middle,
]
\pgfmathsetmacro{\samplestep}{2}
\addplot[domain=0:2, samples=80, ultra thick, red,
x filter/.code={%
\pgfmathsetmacro{\orig}{\pgfmathresult}
\pgfmathsetmacro{\modcoord}{mod(int(mod(\coordindex, 2*\samplestep)),2*\samplestep)}
\pgfmathparse{\modcoord <= \samplestep ? \orig : nan}
}, unbounded coords=jump] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\addplot[domain=0:2, samples=80, ultra thick, blue,
x filter/.code={%
\pgfmathsetmacro{\orig}{\pgfmathresult}
\pgfmathsetmacro{\modcoord}{mod(int(mod(\coordindex, 2*\samplestep)),2*\samplestep)}
\pgfmathparse{\modcoord == 0 || \modcoord >= \samplestep ? \orig : nan}
}, unbounded coords=jump] ({-(x+1)*x*(x-3)*(1+x^2)/4},{-x*(x-1)*(x-2)*4*(1+x^3)/4});
\end{axis}
\end{tikzpicture}
\end{document}
我根据坐标进行过滤\coordindex
并绘制两次函数图,每次丢弃一半的坐标。 \samplestep
会影响每次绘制的线段数量。 \samplestep
必须至少为 2。
我发现我需要mod
在我的 pgf 代码中使用两次,因为使用mod
一次不会产生正确的结果。