Я хочу использовать pgfplots в latex для построения графика данных из файла, который был отформатирован для использования с индексной функцией 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 какИкси столбец 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}