来自同一张表索引的多个 pgfplots

来自同一张表索引的多个 pgfplots

我有一个 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 列或成对的列。(同样,这仅在以下情况下才有效全部列与行的数量相同。如果没有,你可以用NaNs 填充剩余部分。)

或者您可以将每个参数变化存储在其自己的数据文件中(当然)。

这样,“维护”也会变得容易得多,特别是当您不想在一个图中绘制所有“数百种变化”时——这很可能也不是一个好主意。

% 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}

该图显示了上述代码的结果

相关内容