pgfplot 使用由 2 個空白行分隔的第二個資料區塊

pgfplot 使用由 2 個空白行分隔的第二個資料區塊

我想在 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 列為y價值觀。這可以透過使用包繪製數據來顯示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}

在此輸入影像描述

相關內容