我想在同一轴上绘制一组曲线。它们都是两个变量的函数,我们将它们称为 x 和 p。我想绘制 y=f(x,p),其中 x 为 x 轴变量,每条曲线的 p 值为固定值。但是,我还想根据基于 p 值的颜色图为每条曲线着色。我已经设法手动完成此操作(即手动确定每条曲线的颜色应该是什么,然后编写数十条\addplot
命令),但我无法使用循环来完成\foreach
,也无法直接从颜色图中确定颜色。以下代码是 MWE,给出了我当前的方法(有效,但对于许多曲线来说,它非常蛮力且难以使用)和我的第一个稍微好一点的方法,但由于某种我无法理解的原因而失败了。
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\ifdim\thisrow{#1}pt=#2pt
\else
\def\pgfmathresult{nan}
\fi
}
}
}
\begin{filecontents*}{data.tsv}
parameter xvalue yvalue
0 1 1
0 2 2
0 3 3
0.05 1 2
0.05 2 4
0.05 3 6
0.1 1 3
0.1 2 6
0.1 3 9
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
point meta min = 0,
point meta max = 0.1,
colormap={CM}{color=(red) color=(blue)},
colorbar
]
\addplot[color=red, mark=*] table [x=xvalue, y=yvalue, meta=parameter, discard if not={parameter}{0}] {data.tsv};
\addplot[color=red!50!blue, mark=*] table [x=xvalue, y=yvalue, meta=parameter, discard if not={parameter}{0.05}] {data.tsv};
\addplot[color=blue, mark=*] table [x=xvalue, y=yvalue, meta=parameter, discard if not={parameter}{0.1}] {data.tsv};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[
point meta min = 0,
point meta max = 0.1,
colormap={CM}{color=(red) color=(blue)},
colorbar
]
\foreach \point in {0,0.05,0.1}{
\pgfmathsetmacro{\percent}{\point*100}
\addplot[color=red!\percent!blue, mark=*] table [x=xvalue, y=yvalue, meta=parameter, discard if not={parameter}{\point}] {data.tsv};
};
\end{axis}
\end{tikzpicture}
\end{document}
强力方法(第一tikzpicture
):
目前尝试更好的方法(第二次tikzpicture
):
理想的解决方案是允许我简单地指定输入文件和颜色图,然后tex
找出整个文件上每条曲线和循环的颜色。
答案1
我建议采用以下解决方案:
\documentclass{standalone}
\usepackage{pgfplots}
\begin{filecontents*}{data.tsv}
parameter xvalue yvalue
0 1 1
0 2 2
0 3 3
0.05 1 2
0.05 2 4
0.05 3 6
0.1 1 3
0.1 2 6
0.1 3 9
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
point meta min = 0,
point meta max = 0.1,
colormap={CM}{color=(red) color=(blue)},
colorbar,
]
\addplot[
scatter,
mesh,
point meta=explicit,
mark=*,
empty line=jump,
] table [%
x={xvalue},%
y={yvalue},%
meta=parameter,%
] {data.tsv};
% }
\end{axis}
\end{tikzpicture}
\end{document}
我提出的解决方案解决了多个问题:
线条和标记的颜色:用于
point meta=explicit
明确分配来自表源的元值。选项mesh
或scatter
(仅适用于散点图)使图使用映射的颜色。自动查找所有值
parameter
:这可能不是最优雅的解决方案,但如果您可以控制数据表的生成,请按参数对其进行排序并插入空行以对其进行分段。使用 oprionempty line=jump
在您的图中插入不连续性,有效地将表示拆分为多个不同的图。如果您需要图例,那么这将不起作用。
如果我的建议 2. 不符合您的需求,只需使用 1. 中的相关信息并将其与您的 foreach 循环相结合即可。这在我的测试中仍然有效。
警告:我注意到我的一些 PDF 查看器无法正确呈现颜色。请确保这不是显示问题。
答案2
您可以使用命令中的scatter
和选项来实现这一点。这样,您可以将参数列直接映射到颜色图,并完全避免使用循环。scatter src
\addplot
这是MWE:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\ifdim\thisrow{#1}pt=#2pt
\else
\def\pgfmathresult{nan}
\fi
}
}
}
\begin{filecontents*}{data.tsv}
parameter xvalue yvalue
0 1 1
0 2 2
0 3 3
0.05 1 2
0.05 2 4
0.05 3 6
0.1 1 3
0.1 2 6
0.1 3 9
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
point meta min = 0,
point meta max = 0.1,
colormap={CM}{color=(red) color=(blue)},
colorbar
]
\foreach \point in {0,0.05,0.1}{
\addplot[
mesh, % for color interpolation along the line
thin,
point meta=\point, % set meta value for the line
] table [x=xvalue, y=yvalue, discard if not={parameter}{\point}] {data.tsv};
% plot points separately
\addplot[
scatter, only marks, mark=*,
scatter src=explicit, % use explicit value provided in the table for color mapping
] table [x=xvalue, y=yvalue, meta=parameter, discard if not={parameter}{\point}] {data.tsv};
}
\end{axis}
\end{tikzpicture}
\end{document}
它将根据映射到颜色图的参数列生成具有正确颜色的图。
此解决方案允许您根据需要简单地指定输入文件和颜色图。代码将自动确定每个点的颜色并循环遍历整个文件。