我想在 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}