gnuplot의 인덱스 기능과 함께 사용하도록 형식이 지정된 파일의 데이터를 플롯하기 위해 latex에서 pgfplots를 사용하고 싶습니다. 데이터 파일에는 두 개의 빈 행(gnuplot 형식)으로 구분된 x,y 열 세트가 있습니다.
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를 사용하여 이 데이터 형식을 그릴 수 있나요? gnuplot의 인덱스와 동일한 것이 pgfplots에 있습니까? pgfplot 인덱스는 내가 이해하는 한 데이터의 두 번째 블록이 아닌 여러 열 데이터의 열 번호를 나타냅니다.
답변1
먼저 gnuplot이 어떻게 구문 분석하는지 살펴보겠습니다. 내가 이해하는 한 index 0 u 1:2
: 첫 번째(0 인덱스) 블록을 보고 열 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}