pgfplot 使用由两个空白行分隔的第二个数据块

pgfplot 使用由两个空白行分隔的第二个数据块

我想使用 latex 中的 pgfplots 绘制来自已格式化为可使用 gnuplot 索引函数的文件的数据。数据文件包含由两个空白行分隔的 x、y 列集(gnuplot 格式)。

10  10              
20  18      
30  36      


10  11
20  20
30  41

使用 gnuplot,我可以做到

plot 'data.dat' index 0 u 1:1 with p lw 2 pt 4 ps 1 lc rgb 'red' t 'One, \
'' index 1 u 1:2 with p lw 2 pt 5 ps 1 lc rgb 'blue' t 'Two'

无需以其他格式重写数据文件,我可以使用 pgfplots 绘制此数据格式吗?pgfplots 中是否有与 gnuplot 索引等效的内容?据我所知,pgfplot 索引指的是多列数据中的列号,而不是第二个数据块。

答案1

首先,让我们看看 gnuplot 如何解析事物。据我所知,index 0 u 1:2这意味着:查看第一个(零索引)块并使用第 1 列作为X并将第 2 列设为值。这可以通过使用包绘制数据来显示gnuplottex

\documentclass[border=10pt]{standalone}
\usepackage{xcolor, gnuplottex}

\begin{filecontents}[noheader]{data.dat}
10  10              
20  18      
30  36      


10  11
20  20
30  41
\end{filecontents}

\begin{document}

\begin{gnuplot}[terminal=epslatex]
plot 'data.dat' index 0 u 1:2 with p lw 2 pt 4 ps 1 lc rgb 'red'  t 'One', \
             '' index 1 u 1:2 with p lw 2 pt 4 ps 1 lc rgb 'blue' t 'Two'
\end{gnuplot}

\end{document}

在此处输入图片描述


这意味着:我们只需要在每一行后面附加一个标识我们当前所在块的索引。

使用其他软件可能更容易做到这一点,但您可以让 TeX 转换文件并将索引列附加到每行。然后您可以使用这种方法

下面的代码读取文件并附加一个索引(从 1 开始的整数),如果遇到两个连续的空白行,索引就会增加。新数据被写入文件,data_index.dat然后您可以使用 PGFPlots 读取该文件。

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

\begin{filecontents}[noheader]{data.dat}
10  10              
20  18      
30  36      


10  11
20  20
30  41
\end{filecontents}

\ExplSyntaxOn
\cs_generate_variant:Nn \iow_now:Nn { Ne }
\int_new:N \l_csnl_gnutopgf_index_int
\int_set:Nn \l_csnl_gnutopgf_index_int { 1 }
\bool_new:N \l_csnl_gnutopgf_blank_line_bool
\bool_set_false:N \l_csnl_gnutopgf_blank_line_bool
\ior_new:N \g_csnl_gnutopgf_input_ior
\ior_open:Nn \g_csnl_gnutopgf_input_ior { data.dat }
\iow_new:N \g_csnl_gnutopgf_output_iow
\iow_open:Nn \g_csnl_gnutopgf_output_iow { data_index.dat }
\iow_now:Nn \g_csnl_gnutopgf_output_iow { index ~ x ~ y }
\ior_str_map_inline:Nn \g_csnl_gnutopgf_input_ior {
    \bool_if:NT \l_csnl_gnutopgf_blank_line_bool {
        \str_if_empty:nT {#1} {
            \int_incr:N \l_csnl_gnutopgf_index_int
        }
        \bool_set_false:N \l_csnl_gnutopgf_blank_line_bool
    }
    \str_if_empty:nTF {#1} {
        \bool_set_true:N \l_csnl_gnutopgf_blank_line_bool
    } {
        \bool_set_false:N \l_csnl_gnutopgf_blank_line_bool
        \iow_now:Ne \g_csnl_gnutopgf_output_iow { 
            \int_eval:n { \l_csnl_gnutopgf_index_int } ~ #1
        }
    }
}
\ior_close:N \g_csnl_gnutopgf_input_ior
\iow_close:N \g_csnl_gnutopgf_output_iow
\ExplSyntaxOff

\begin{document}

\pgfplotsset{
    only index/.style={
        x filter/.code={
            \edef\tempa{\thisrow{index}}
            \edef\tempb{#1}
            \ifx\tempa\tempb\else
                \def\pgfmathresult{inf}
            \fi
        }
    }
}

\begin{tikzpicture}
\begin{axis}[legend pos=north west]
    \addplot table[x=x, y=y, only index=1]{data_index.dat};
    \addlegendentry{One}
    \addplot table[x=x, y=y, only index=2]{data_index.dat};
    \addlegendentry{Two}
\end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容