텍스트 파일의 데이터를 Tikz 변수에 저장하는 방법은 무엇입니까?

텍스트 파일의 데이터를 Tikz 변수에 저장하는 방법은 무엇입니까?

텍스트 파일을 사용하여 Tikz 플롯에서 사용 중인 변수의 값을 전달하려고 합니다. 데이터를 문자열에서 문자로 변환하는 방법을 잘 모르겠습니다. 여기에서는 automaton.txt일부 배열 값(1x4)을 기반으로 다시 작성하려는 각 행에 문자열로 저장합니다 \statedef. 텍스트 파일의 행 수는 가져올 때마다 다르며 \def문자만 허용됩니다. 또한, 텍스트 파일을 뒷면에 동기화하여 뒷면에서 내 그림에 반영된 변경 사항을 볼 수 있는 방법이 있는지 궁금합니다.

\documentclass[tikz,border=1cm]{standalone}
\usepackage{graphicx} % Required for inserting images
\usepackage{amsthm}
\pdfoutput=1
\usepackage{multirow}
\usepackage{lettrine}
\usepackage{graphicx,float}
\usepackage{tikz}
\usetikzlibrary{automata, positioning, arrows.meta,calc,cd}
\usetikzlibrary{patterns}
\usetikzlibrary{datavisualization}
\tikzset{
->, % makes the edges directed
>=stealth, % makes the arrow heads bold
node distance=3cm, % specifies the minimum distance between two nodes. Change if necessary.
every state/.style={thick, fill=gray!10}, % sets the properties for each ’state’ node
initial text=$ $, % sets the text that appears on the start arrow
}
\usepackage[fleqn]{amsmath}
\usepackage{amssymb}
\usepackage{cite}
\usepackage{lettrine}
\let\labelindent\relax
\usepackage{enumitem}
\usepackage{multicol}
\usepackage{readarray}
\usepackage{pgfplots}
\usepackage{pgfmath}
\makeatletter
\newenvironment{customlegend}[1][]{%
    \begingroup
    % inits/clears the lists (which might be populated from previous
    % axes):
    \pgfplots@init@cleared@structures
    \pgfplotsset{#1}%
}{%
    % draws the legend:
    \pgfplots@createlegend
    \endgroup
}%

% makes \addlegendimage available (typically only available within an
% axis environment):
\def\addlegendimage{\pgfplots@addlegendimage}
\makeatother
\usepackage[T1]{fontenc}
\usepackage[export]{adjustbox}
\usepackage{booktabs,makecell}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage[labelsep=quad,indention=10pt]{subfig}
\usepackage{ifthen}
\begin{document}
\tikzset{
    redfill/.code={
    \definecolor{mycolour1}{rgb}{1,0,0}%
    \pgfkeysalso{/tikz/fill=mycolour1!40}
      }
    }
    \tikzset{
    greenfill/.code={
    \definecolor{mycolour2}{rgb}{0,1,0}%
    \pgfkeysalso{/tikz/fill=mycolour2!30}
      }
    }
    \tikzset{
    bluefill/.code={
    \definecolor{mycolour3}{rgb}{0,0,1}%
    \pgfkeysalso{/tikz/fill=mycolour3!40}
      }
    }
    \tikzset{
    cyanfill/.code={
    \pgfkeysalso{/tikz/fill=teal!60}
      }
    }
    \tikzset{
    twocolorfill/.style n args={2}{path picture={
            \fill[#1] (path picture bounding box.south)--(path picture bounding box.north)--(path picture bounding box.north east)--(path picture bounding box.south east)--cycle;
            \fill[#2] (path picture bounding box.south)--(path picture bounding box.north)--(path picture bounding box.north west)--(path picture bounding box.south west)--cycle;
            }}
    }
    \tikzset{
    threecolorfill/.style n args={3}{path picture={
            \fill[#1] (path picture bounding box.east)--(path picture bounding box.north east)--(path picture bounding box.north west)--(path picture bounding box.west)--cycle;
            \fill[#2] (path picture bounding box.center) -- (path picture bounding box.south)  arc [start angle=-90, delta angle=-90, radius=1] -- cycle;
            \fill[#3] (path picture bounding box.center) -- (path picture bounding box.south)  arc [start angle=-90, delta angle=90, radius=1] -- cycle;
            }}
    }
    \tikzset{
    fourcolorfill/.style n args={4}{path picture={
            \fill[#1] (path picture bounding box.east)--(path picture bounding box.north east)--(path picture bounding box.north)--(path picture bounding box.center)--cycle;
            \fill[#2] (path picture bounding box.center)--(path picture bounding box.north)--(path picture bounding box.north west)--(path picture bounding box.west)--cycle;
            \fill[#3] (path picture bounding box.center)--(path picture bounding box.south)--(path picture bounding box.south west) -- (path picture bounding box.west) -- cycle;
            \fill[#4] (path picture bounding box.center)--(path picture bounding box.south)--(path picture bounding box.south east) -- (path picture bounding box.east) -- cycle;
            }}
    }
    \tikzset{
            colorfill1_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{greenfill}
            \else
            \fi 
            },
            colorfill2_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{redfill}
            \else
            \fi 
            },
            colorfill3_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{bluefill}
            \else
            \fi 
            },
            colorfill4_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{cyanfill}
            \else
            \fi 
            },
            hashfill1_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{pattern=north west lines, pattern color=black}
            \else
            \fi 
            },
            fourcolor1_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{fourcolorfill={cyanfill}{redfill}{greenfill}{blue!50}}
            \else
            \fi 
            },
            threecolor1_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{threecolorfill={cyanfill}{greenfill}{blue!50}}
            \else
            \fi 
            },
            twocolor1_sub/.code=
            {
            \ifnum\pgfkeysvalueof{/tikz/colorfill_item}=#1
            \tikzset{twocolorfill={blue!50}{cyanfill}}
            \else
            \fi 
            },
            colorfill_item/.initial=0,
            colorfill/.code n args={9}
            {
            \tikzset{colorfill_item=#1,colorfill1_sub/.list=#2,colorfill2_sub/.list=#3,colorfill3_sub/.list=#4,colorfill4_sub/.list=#5,hashfill1_sub/.list=#6,fourcolor1_sub/.list=#7,threecolor1_sub/.list=#8,twocolor1_sub/.list=#9}
            } 
    }
    
\begin{figure*}[h]
\centering
    \begin{adjustbox}{minipage=\textwidth,scale=0.8}
    \begin{tikzpicture}[node distance = 2cm, on grid,>={Stealth[inset=0pt,length=6pt,angle'=28,round]}
            ]

    \begin{customlegend}[legend style={at={(10,-8)},anchor=south},legend columns=-1,legend style={column sep=1ex},legend entries={Proposed Method,PCM PTA-MPC,CB PTA-MPC,PTA-MPC,Failed State}]
    \addlegendimage{black,only marks, mark=*, cyanfill,style={scale=4}}
    \addlegendimage{black,only marks, mark=*, bluefill,style={scale=4}}
    \addlegendimage{black,only marks, mark=*, greenfill,style={scale=4}}
    \addlegendimage{black,only marks, mark=*, redfill,style={scale=4}}
    \addlegendimage{black,only marks, mark=*, pattern=north west lines, pattern color=black,style={scale=4}}
   \end{customlegend};

\readarraysepchar{,}
\readdef{automaton.txt}{\mydata}
\readarray\mydata\datacell[-,\ncols]
\def\test{\pgfkeysvalueof{\mydata[3,4]}}


    %% DO NOT put extra space below!!!
    %% {first state xcoor,first state ycoor,first state superscript, last state superscript}
    %% State Definition
    \def\statedef{{2,0,2,10},{8,2,11,14},{8,-2,15,20},{8,-4,21,24},{4,-3,25,26},{5,-6,27,29}}
    %% {first state superscript, last state superscript}
    %% Straight Edge Definition
    \def\straightsolidedge{{1,5},{7,9},{11,12},{14},{15,20},{21,24},{27,29}}
    \def\bendrightsolidedge{{2,25},{25,27},{29,22},{24,19},{18,9},{16,7},{4,15},{4,21},{16,23}}
    \def\bendleftsolidedge{{12,7},{14,9}}
    %% Color Definiton
    \def\rstates{{5,22,23,24,25,27,28,29}}
    \def\gstates{{11,12}}
    \def\bstates{{13}}
    \def\cstates{{17,18,19,20}}
    \def\hashedstates{{6,10,13,26}}
    \def\bicolorstates{{15,16}}
    \def\tricolorstates{{7,8}}
    \def\quadcolorstates{{2,3,4}}

\node[state,initial,fourcolorfill={cyanfill}{redfill}{greenfill}{blue!50}](q1){$q^{1}$};
\foreach \e in \statedef
{\edef\mye{{\e}}
\pgfmathsetmacro{\myx}{\mye[0]}
\pgfmathsetmacro{\myy}{\mye[1]}
\pgfmathsetmacro{\myfirstind}{\mye[2]}
\pgfmathsetmacro{\mystartind}{int(\mye[2]+1)}
\pgfmathsetmacro{\mylastind}{\mye[3]}
\node [state, colorfill/.expanded={\myfirstind}{\gstates}{\rstates}{\bstates}{\cstates}{\hashedstates}{\quadcolorstates}{\tricolorstates}{\bicolorstates}] at (\myx,\myy) (q\myfirstind){$q^{\myfirstind}$};
\foreach \a[evaluate=\a as \b using int(\a-1)] in {\mystartind,...,\mylastind}{
\node[state, right of=q\b, colorfill/.expanded={\a}{\gstates}{\rstates}{\bstates}{\cstates}{\hashedstates}{\quadcolorstates}{\tricolorstates}{\bicolorstates}] (q\a){$q^{\a}$};
}
}

\foreach \r in \straightsolidedge
{\edef\myr{{\r}}
\pgfmathsetmacro{\mystartstate}{\myr[0]}
\pgfmathsetmacro{\myendstate}{\myr[1]-1}
\foreach \d[evaluate=\d as \e using int(\d+1)] in {\mystartstate,...,\myendstate}{
\draw (q\d) edge (q\e);
}
}

\foreach \t in \bendrightsolidedge
{\edef\myt{{\t}}
\pgfmathsetmacro{\f}{\myt[0]}
\pgfmathsetmacro{\g}{\myt[1]}
\draw (q\f) edge[bend right] (q\g);
}

\foreach \u in \bendleftsolidedge
{\edef\myu{{\u}}
\pgfmathsetmacro{\h}{\myu[0]}
\pgfmathsetmacro{\i}{\myu[1]}
\draw (q\h) edge[bend left] (q\i);
}

\draw (q4) edge[bend left] node [below left]{} (q11);
    \end{tikzpicture}
    \end{adjustbox}
\end{figure*}
\end{document}

또한 아래 내용은 automaton.txt.

2,0,2,5
2,2,6,8
2,-2,9,11

답변1

. lualatex​내 접근 방식이 그다지 우아하지 않다는 점을 인정합니다. :P.

\documentclass{scrartcl}

\usepackage{luacode}
\usepackage{pgffor}

\begin{filecontents*}{data.txt}
2,0,2,6
2,2,6,8
2,-2,9,11
\end{filecontents*}

\begin{document}

\begin{luacode}
    function read_file(file,macro)
        f = io.open(file, "r")
        concat_string = ""
        i = 1
        for line in io.lines(file) do
            concat_string = concat_string .. "{" .. line .. "},"
            i = i + 1
        end
        -- remove trailing ","
        concat_string = concat_string:sub(1,-2)
        tex.sprint("\\def" .. "\\" .. macro .. "{" .. concat_string .. "}")
    end
\end{luacode}
    
\directlua{read_file("data.txt", "statedef")}
\noindent
\foreach \s [count=\i from 1] in \statedef{%
    State \i{} entries:
    \foreach \se in \s {%
        \se~
    }
    \\
}
    
\end{document}

여기에 이미지 설명을 입력하세요

답변2

아마도 배열의 행과 열을 반복하기 위한 중첩 루프가 유용할 것입니다. expl3은 \cs_to_str:N제어 시퀀스 토큰의 이름을 안정적으로 전달하는 루틴인 을 제공하기 때문에 다음 MWE에 expl3-syntax를 사용하기로 결정했습니다.

\begin{filecontents*}{MYRENAMEDautomaton.txt}
2,0,2,5
2,2,6,8
2,-2,9,11
1\TeX1,2\TeX2,3\TeX3,4\TeX4
\end{filecontents*}

\documentclass{article}

\usepackage{readarray}

\ExplSyntaxOn
\cs_new:Npn \TwoDArrayToMacro #1#2 {
  \group_begin:
  \nocheckbounds
  \Mostafa_TwoDArrayToMacroLoop:nnnnnnnn {#1}{#2}{1}{1}{}{}{}{}
}
\cs_new:Npn \Mostafa_TwoDArrayToMacroLoop:nnnnnnnn #1#2#3#4#5#6#7#8 {
   %  #1 array 
   %  #2 macro
   %  #3 row number
   %  #4 column number
   %  #5 row separator
   %  #6 column separator
   %  #7 rows gathered
   %  #8 colum in construction
   \int_compare:nNnTF {#3}>{\use:c{\cs_to_str:N #1ROWS}}
   {\group_end: \cs_set:Npn #2{#7}}{
     \int_compare:nNnTF {#4}>{\use:c{\cs_to_str:N #1COLS}}
       {
         \exp_after:wN \use_ii_i:nn \exp_after:wN {
           \exp_after:wN {
             \exp:w\exp_after:wN\exp_after:wN\exp_after:wN\exp_end:
             \int_eval:n{(#3)+1}
           }
         }{\Mostafa_TwoDArrayToMacroLoop:nnnnnnnn{#1}{#2}}{1}{,}{}{#7#5{#8}}{}
       }
       {
         \exp_after:wN \use_ii_i:nn \exp_after:wN {\exp_after:wN { 
           \exp:w \Mostafa_exp_args_otimes:nNn{4} \use_ii_i:nn {#1[#3,#4]}{\exp_end: #8#6}
         }}
         {
           \exp_after:wN \use_ii_i:nn \exp_after:wN {
             \exp_after:wN {
               \exp:w\exp_after:wN\exp_after:wN\exp_after:wN\exp_end:
               \int_eval:n{(#4)+1}
             }
           }{\Mostafa_TwoDArrayToMacroLoop:nnnnnnnn{#1}{#2}{#3}}{#5}{,}{#7}
         }
       }
   }
}
\cs_new:Npn \Mostafa_exp_args_otimes:nNn #1#2#3 {
  \exp_after:wN\use_ii_i:nn\exp_after:wN{\exp_after:wN{\exp:w 
  \exp_after:wN \__Mostafa_exp_args_otimes:nn\exp_after:wN {\exp_after:wN}
  \tex_romannumeral:D \int_eval:n {(#1)*1000}~d #3}}{#2}
}
\cs_new:Npn \__Mostafa_exp_args_otimes:nn #1#2 {
  \__Mostafa_exp_args_otimes:n {#2}{#1\exp_end:}{\__Mostafa_exp_args_otimes:nn{#1#1\exp_after:wN}}
}
\cs_new:Npn \__Mostafa_exp_args_otimes:n #1 {
  \__Mostafa_exp_args_otimes:wnw #1{\use_i:nn}d{\use_ii:nn}dd
}
\cs_new:Npn \__Mostafa_exp_args_otimes:wnw #1d#2#3dd{#2}
\ExplSyntaxOff


\begin{document}

\readarraysepchar{,}
\readdef{MYRENAMEDautomaton.txt}{\mydata}
\readarray\mydata\datacell[-,\ncols]
\TwoDArrayToMacro{\datacell}{\statedef}

\ttfamily\selectfont \frenchspacing

\noindent
\verb|\statedef|=\\
\meaning\statedef

\end{document}

여기에 이미지 설명을 입력하세요

관련 정보