绘制来自 CSV 的数据,将点分开,格式化来自数据列的 xlabel,移动网格

绘制来自 CSV 的数据,将点分开,格式化来自数据列的 xlabel,移动网格

几周以来,我一直在收集湿度计的数据,观察它们的漂移。现在我想绘制数据。这是我的第一次尝试,数据看起来是这样的(我希望这能奏效,我无法测试文件内容,因为 TL2021 不允许我再安装它,因为 TL 2022 已经发布,我还没有时间升级):

\documentclass[pagesize]{standalone}

\usepackage{filecontents}

\begin{filecontents*}{test.csv}
t;30.5005, 0916;30.5005, 0818;30.3054.10;30.3208.02, Ch1;30.3208.02, Ch2;30.3208.02, Ch3
2022-03-31 08:56:09;56;59;60;60;59;58
2022-03-31 09:47:22;45;47;52;54;52;53
2022-03-31 10:14:44;48;52;54;55;54;53
2022-03-31 16:00:55;43;46;50;50;50;50
2022-04-01 00:16:09;41;41;49;49;48;49
2022-04-01 00:18:07;42;42;49;49;48;49
2022-04-01 22:01:30;42;46;52;52;51;51
2022-04-02 16:15:50;40;48;51;52;51;51
2022-04-02 20:17:47;38;45;51;51;51;50
2022-04-04 17:44:12;32;40;46;47;46;46
2022-04-06 21:14:45;40;49;52;52;51;51
2022-04-08 11:01:51;42;51;53;55;54;53
2022-04-08 12:00:06;41;51;54;55;53;54
2022-04-08 12:35:03;38;46;50;52;50;51
2022-04-20 00:29:28;33;41;46;47;45;45
2022-04-20 11:42:43;47;55;56;56;54;54
2022-04-20 12:48:44;40;48;51;52;50;51
2022-04-20 13:44:00;35;42;47;50;48;49
\end{filecontents*}

\usepackage{amsmath}

\usepackage{tikz,pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{units}

\newcommand{\xlabelstrut}{\rule[-0.7\baselineskip]{0pt}{1.8\baselineskip}}

\pgfplotsset{%
    compat=1.16,%
    scale only axis,%
    axis x line* = bottom,%
    axis y line* = left,%
    every axis/.append style = {line width=0.5pt},%
    tick align = center,%
    tick style={line width = 0.5pt, color = black},%
    tick label style={font=\footnotesize, /pgf/number format/.cd, use comma, 1000 sep={}},%
    every axis x label/.style={at={(ticklabel* cs:1.02)},anchor=west,},%
    every axis y label/.style={at={(ticklabel* cs:1.05)},anchor=south,},%
    label style={font=\footnotesize},%
    grid = both,%
    every axis plot/.append style={%
        line join = round,%
    },%
%
    legend style = {draw = none, font = \footnotesize},%
    legend cell align = left,%
    legenderechtsauszen/.style = {legend style = {at = {(1.01,0.5)}, anchor = west}},%
    diagramm/.style = {%
        log ticks with fixed point,%
    },%
    hygrovgl/.style = {%
        diagramm,%
        width = 120mm,%
        height = 80mm,%
        legenderechtsauszen,%
        xmin = 1,%
        xmax = 19,%
        xtick distance = 1,%
        ymax = 70,%
        ymin = 10,%
        minor y tick num = 4,%
        xlabel = {sample\xlabelstrut},%
        ylabel = {$\varphi$/\%},%
    },%
}

\pgfplotstableread[col sep = semicolon]{test.csv}\data

\begin{document}

\begin{minipage}{210mm}
\centering\vspace{8mm}
\begin{tikzpicture}[trim axis left, trim axis right]
    \begin{axis}[hygrovgl]
        \pgfplotsinvokeforeach{1,...,6}{%
            \pgfplotstablegetcolumnnamebyindex{#1}\of{\data}\to{\colname}%
            \addplot+ plot [error bars/.cd, y dir=both, y fixed = {5}] table [x expr = \coordindex + #1/7 + 1, y index = #1]{\data};%
            \addlegendentryexpanded{\colname};%
        }
    \end{axis}
\end{tikzpicture}

\vspace{8mm}
\end{minipage}

\end{document}

我删除了这个 MWE 的循环列表,但除此之外,它接近我想要的。

我的第一个想法是在 x 轴上显示日期和时间,但不知何故它不起作用并且我也没有太多时间,所以我最终使用了x expr = \coordindex,它让我可以轻松地通过在索引中添加偏移项来将数据点稍微分开,这样你就可以看到它们了。

当我最终设法使用 t 列代替 时\coordindex,我看到了我已经预料到的结果:这(显然)导致了真正的空间浪费,使 x 轴成为时间轴,并将数据点移动到它们在时间上的各自位置,这导致同一天的数据无法读取,并且在我没有收集数据的那些日子里留下很大的空白。

因此,我想坚持\coordindex并从数据中读取 xticklabels(来自这里):

\documentclass[pagesize]{standalone}

\usepackage{filecontents}

\begin{filecontents*}{test.csv}
t;30.5005, 0916;30.5005, 0818;30.3054.10;30.3208.02, Ch1;30.3208.02, Ch2;30.3208.02, Ch3
2022-03-31 08:56:09;56;59;60;60;59;58
2022-03-31 09:47:22;45;47;52;54;52;53
2022-03-31 10:14:44;48;52;54;55;54;53
2022-03-31 16:00:55;43;46;50;50;50;50
2022-04-01 00:16:09;41;41;49;49;48;49
2022-04-01 00:18:07;42;42;49;49;48;49
2022-04-01 22:01:30;42;46;52;52;51;51
2022-04-02 16:15:50;40;48;51;52;51;51
2022-04-02 20:17:47;38;45;51;51;51;50
2022-04-04 17:44:12;32;40;46;47;46;46
2022-04-06 21:14:45;40;49;52;52;51;51
2022-04-08 11:01:51;42;51;53;55;54;53
2022-04-08 12:00:06;41;51;54;55;53;54
2022-04-08 12:35:03;38;46;50;52;50;51
2022-04-20 00:29:28;33;41;46;47;45;45
2022-04-20 11:42:43;47;55;56;56;54;54
2022-04-20 12:48:44;40;48;51;52;50;51
2022-04-20 13:44:00;35;42;47;50;48;49
\end{filecontents*}

\usepackage{amsmath}

\usepackage{tikz,pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{units}

\newcommand{\xlabelstrut}{\rule[-0.7\baselineskip]{0pt}{1.8\baselineskip}}

\pgfplotsset{%
    compat=1.16,%
    scale only axis,%
    axis x line* = bottom,%
    axis y line* = left,%
    every axis/.append style = {line width=0.5pt},%
    tick align = center,%
    tick style={line width = 0.5pt, color = black},%
    tick label style={%
        font=\footnotesize,%
%        /pgf/number format/.cd, use comma, 1000 sep={}%
    },%
    every axis x label/.style={at={(ticklabel* cs:1.02)},anchor=west,},%
    every axis y label/.style={at={(ticklabel* cs:1.05)},anchor=south,},%
    label style={font=\footnotesize},%
    grid = both,%
    every axis plot/.append style={%
        line join = round,%
    },%
%
    legend style = {draw = none, font = \footnotesize},%
    legend cell align = left,%
    legenderechtsauszen/.style = {legend style = {at = {(1.01,0.5)}, anchor = west}},%
    diagramm/.style = {%
        log ticks with fixed point,%
    },%
    hygrovgl/.style = {%
        diagramm,%
        width = 120mm,%
        height = 80mm,%
        legenderechtsauszen,%
        xmin = 1,%
        xmax = 19,%
        xtick distance = 1,%
        ymax = 70,%
        ymin = 10,%
        minor y tick num = 4,%
        flexible xticklabels from table = {test.csv}{t}{col sep = semicolon},%
        xticklabel style = {rotate = 90, anchor = near xticklabel}, % To make sure the text labels are nicely aligned
        xtick = data,%
        xlabel = {sample\xlabelstrut},%
        ylabel = {$\varphi$/\%},%
    },%
}

\makeatletter
\pgfplotsset{
    /pgfplots/flexible xticklabels from table/.code n args={3}{%
        \pgfplotstableread[#3]{#1}\coordinate@table
        \pgfplotstablegetcolumn{#2}\of{\coordinate@table}\to\pgfplots@xticklabels
        \let\pgfplots@xticklabel=\pgfplots@user@ticklabel@list@x
    }
}
\makeatother

\pgfplotstableread[col sep = semicolon]{test.csv}\data

\begin{document}

\begin{minipage}{210mm}
\centering\vspace{8mm}
\begin{tikzpicture}[trim axis left, trim axis right]
    \begin{axis}[hygrovgl]
        \pgfplotsinvokeforeach{1,...,6}{%
            \pgfplotstablegetcolumnnamebyindex{#1}\of{\data}\to{\colname}%
            \addplot+ plot [error bars/.cd, y dir=both, y fixed = {5}] table [x expr = \coordindex + #1/7 + 1, y index = #1]{\data};%
            \addlegendentryexpanded{\colname};%
        }
    \end{axis}
\end{tikzpicture}

\vspace{8mm}
\end{minipage}

\end{document}

/pgf/number format/.cd, use comma, 1000 sep={}为什么如果我想旋转 xticklabels 就必须将其删除?

我该如何格式化 xticklabels?xticklabel = \day.\,\month.除非我使用,否则类似的东西不起作用date coordinates in = x。我当然可以在数据中进行格式化,但我想将其保留为这种形式,以便 PGF 可以在需要时将其作为数据处理。

似乎xminxmax被忽略了。为什么现在网格向右移动了?

我可以将 xticks(和标签)放在 x 网格线的中间,以便它们标记相应的数据点组吗?


从上面看,第二个 MWE 如下所示: 在此处输入图片描述 我不知道为什么网格向右移动了一点,请注意细节 1。在左边缘,第一条垂直线还有一点空间,而第一个 MWE 中没有这种情况(也请参见下面的第二张图),而在右边缘,最后一条垂直线消失了。每个样本/时间戳的第一个数据点现在都位于其垂直网格线上,即使我给它一个水平偏移。请注意一个样本组内数据点的偏移量不断增加。这些组由垂直网格线分隔。

除此之外:有没有办法将 xticks 向右移动垂直网格线距离的一半,如细节 2 所示?


这就是为什么我不再使用时间戳作为 x 轴的数据(与上面的数据相同): 在此处输入图片描述 这使得我们无法看清哪个数据点处于哪个其他点的不确定性范围内,读数如何漂移,等等。

答案1

这是一个很长的评论,但可以更轻松地解决一些问题。当问题的更多细节得到阐述时,我很乐意将其删除。


如果你想旋转 ,你不必删除use commaand/or 。而且你不能写,因为 TikZ/PGFPlots 不知道那里1000 sepxticklabelsxticklabel = \day.\,\month.日期。为此,请使用dateplot库。因为我不知道您最终想要实现什么,所以这里只是一个使用您的数据的工作示例。

% used PGFPlots v1.18.1
\documentclass[border=5pt]{standalone}
\usepackage{filecontents}
\begin{filecontents*}{test.csv}
    t;30.5005, 0916;30.5005, 0818;30.3054.10;30.3208.02, Ch1;30.3208.02, Ch2;30.3208.02, Ch3
    2022-03-31 08:56:09;56;59;60;60;59;58
    2022-03-31 09:47:22;45;47;52;54;52;53
    2022-03-31 10:14:44;48;52;54;55;54;53
    2022-03-31 16:00:55;43;46;50;50;50;50
    2022-04-01 00:16:09;41;41;49;49;48;49
    2022-04-01 00:18:07;42;42;49;49;48;49
    2022-04-01 22:01:30;42;46;52;52;51;51
    2022-04-02 16:15:50;40;48;51;52;51;51
    2022-04-02 20:17:47;38;45;51;51;51;50
    2022-04-04 17:44:12;32;40;46;47;46;46
    2022-04-06 21:14:45;40;49;52;52;51;51
    2022-04-08 11:01:51;42;51;53;55;54;53
    2022-04-08 12:00:06;41;51;54;55;53;54
    2022-04-08 12:35:03;38;46;50;52;50;51
    2022-04-20 00:29:28;33;41;46;47;45;45
    2022-04-20 11:42:43;47;55;56;56;54;54
    2022-04-20 12:48:44;40;48;51;52;50;51
    2022-04-20 13:44:00;35;42;47;50;48;49
\end{filecontents*}
\usepackage{pgfplots}
    \usepgfplotslibrary{dateplot}
    \pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        date coordinates in=x,
        xticklabel={\day.\month.},
        xticklabel style={
            rotate=90,
        },
    ]
        \pgfplotstableread[col sep = semicolon]{test.csv}\data
        \pgfplotsinvokeforeach{1,...,6}{
            \pgfplotstablegetcolumnnamebyindex{#1}\of{\data}\to{\colname}
            \addplot+ [
                error bars/.cd,
                    y dir=both,
                    y fixed = {5},
            ] table [
                x index = 0,
                y index = #1,
            ] {\data};
            \addlegendentryexpanded{\colname};
        }
    \end{axis}
\end{tikzpicture}
\end{document}

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

相关内容