我想使用 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}