我有一个 3 列数据文件,其中第一列指定参数,其他两列应为相应曲线的 x 和 y 坐标。如何确保不同参数的曲线不相连,并且理想情况下可以唯一地标记和/或着色?
我知道我可以使用 gnuplot 或将数据文件拆分为多个列/文件,如类似的问题但是我有几百个不同的参数,所以我希望 pgfplots 可以允许我过滤掉每个图中与其参数不匹配的坐标,或者直接用多条曲线绘制这个数据文件。
例如
\documentclass[preview]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.dat}
1 0 0.5
1 1 1
1 2 1.5
2 0 0
2 0.5 0.5
2 1 0.75
2 1.5 0.865
\end{filecontents}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\begin{axis}[]
\addplot table[x index=1, y index=2]{data.dat};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
这是一份提议。我已经适应了这个答案从如何在 pgfplots 中读取数据文件的特定部分。
使用discard if not={<-parameter-col-num->}{<-parameter-value->}
。
您提到您有几百个参数,因此您可以使用foreach
如下循环:
\foreach \N in {1,2}{
\addplot table[x index=1, y index=2,discard if not={0}{\N}]{data.dat};
}
请参阅本文底部的使用 5 个参数的更大示例。
平均能量损失
\documentclass[margin=0.5cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.dat} % data format: | Parameter | X | Y |
1 0 0.5
1 1 1
1 2 1.5
2 0 0
2 0.5 0.5
2 1 0.75
2 1.5 0.865
\end{filecontents}
% Adapted from https://tex.stackexchange.com/a/178632/128068
% Changed \thisrow{#1} to \thisrowno{#1}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\edef\tempa{\thisrowno{#1}}
\edef\tempb{#2}
\ifx\tempa\tempb
\else
\def\pgfmathresult{inf}
\fi
}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[]
\addplot table[x index=1, y index=2,discard if not={0}{1}]{data.dat};
\addplot table[x index=1, y index=2,discard if not={0}{2}]{data.dat};
\end{axis}
\end{tikzpicture}
\end{document}
foreach
以下是包含 5 个参数的较大数据文件的示例:
\documentclass[margin=0.5cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.dat} % data format: | Parameter | X | Y |
1 0 0.5
1 1 1
1 2 1.5
2 0 0
2 0.5 0.5
2 1 0.75
2 1.5 0.865
3 0 1.5
3 1 2.6
3 2 1.9
4 0 4
4 0.5 3.7
4 1 3.6
5 1.5 4.865
5 2 2.5
\end{filecontents}
% Adapted from https://tex.stackexchange.com/a/178632/128068
% Changed \thisrow{#1} to \thisrowno{#1}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\edef\tempa{\thisrowno{#1}}
\edef\tempb{#2}
\ifx\tempa\tempb
\else
\def\pgfmathresult{inf}
\fi
}
}
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[]
\foreach \N in {1,...,5}{
\addplot table[x index=1, y index=2,discard if not={0}{\N}]{data.dat};
}
\end{axis}
\end{tikzpicture}
\end{document}
答案2
这不是一个完美的解决方案,因为它需要更改数据文件并误用曲线颜色的颜色图。 因为当或出现在数据文件中unbounded coords=jump
时,轴参数将中断绘图(pgfplots 手册第 4.4.10 节)nan
inf
-inf
NaN
因此,每当参数发生变化时,就可以使用 s 线来分离曲线。
1 2 1.5
NaN NaN NaN
2 0 0
可以使用元和颜色图对参数进行颜色编码
\addplot[mesh, point meta = \thisrowno{0}] table[x index=1, y index=2]{data.dat};
它现在是一个网格图,对于彩色点 - 可以使用散点图来代替或另外使用。
颜色图将延伸到参数范围,这会使单条曲线难以区分。point meta = {mod(\thisrowno0,8)}
每 8 个参数将交替颜色。
放在一起:
\documentclass[preview]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.dat}
1 0 0.5
1 1 1
1 2 1.5
NaN NaN NaN
2 0 0
2 0.5 0.5
2 1 0.75
2 1.5 0.865
\end{filecontents}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\begin{axis}[unbounded coords=jump]
\addplot[mesh, scatter, point meta = {mod(\thisrowno0,8)}] table[x index=1, y index=2]{data.dat};
\end{axis}
\end{tikzpicture}
\end{document}
答案3
不修改数据文件
这或多或少是一个高级答案Milo 的回答,它被改编为在 Lua 中进行所有计算 - 使用 LuaLaTeX 进行编译时 - 而不是在 TeX 中进行,同时已经提到过小贴士\pgfplotstableread
使用(来自pgplotstable
包)而不是每个命令都读取整个表一次\addplot
。我还没有测试过这是否真的能提高编译速度,但猜测是的。
修改数据文件
一般情况下,我建议重新构造数据文件。如果所有参数修改都是用相同数量的数据点计算的,那么您可以将它们全部放在一个数据文件中。此外,如果计算是在相同的 x 坐标上进行的,则可以有一个 x 列,然后是所有 y 列或成对的列。(同样,这仅在以下情况下才有效全部列与行的数量相同。如果没有,你可以用NaN
s 填充剩余部分。)
或者您可以将每个参数变化存储在其自己的数据文件中(当然)。
这样,“维护”也会变得容易得多,特别是当您不想在一个图中绘制所有“数百种变化”时——这很可能也不是一个好主意。
% used PGFPlots v1.16
% (borrowed modified data file from Milo's answer
% <https://tex.stackexchange.com/a/448407/95441>)
\begin{filecontents}{data.dat}
% data format: | Parameter | X | Y |
1 0 0.5
1 1 1
1 2 1.5
2 0 0
2 0.5 0.5
2 1 0.75
2 1.5 0.865
3 0 1.5
3 1 2.6
3 2 1.9
4 0 4
4 0.5 3.7
4 1 3.6
5 1.5 4.865
5 2 2.5
\end{filecontents}
\documentclass[margin=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
% use this `compat' level or higher to make use of Lua for computations
% when using LuaLaTeX
\pgfplotsset{compat=1.12}
\pgfplotstableread{data.dat}{\loadedtable}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
% because we know we want to filter data points
% we don't need a warning for every filtered data point in the log
filter discard warning=false,
]
\foreach \i in {1,...,5}{
\addplot table [
x expr={
ifthenelse(
\thisrowno{0} == \i,
\thisrowno{1},
NaN
)
},
y index=2,
] {\loadedtable};
}
\end{axis}
\end{tikzpicture}
\end{document}