9

I have data stored in files I named x.dat and y.dat. In the file are two columns and each row stands for one point. These points I plot in the beginning. But then I want some arrows from the x-points to the y-points. So I need a foreach over the points. But those points are not stored in a way the foreach-statement can handle.

How can I get the foreach-statement to walk through the points in the files, without changing the files?

\draw plot [only marks, mark=*, mark options={fill=red, scale=0.3}]
    file {x.dat};
\foreach \x  in file {x.dat}
    \foreach \y in file {y.dat}
    {
        \draw [->] \x -- \y;
    }
10

This is a code based on Torbjørn's code but here I try to use pgfplotstable. I'm not a great expert of this package also it's perhaps possible to use some useful macro to read \xA and \yA directly.

\documentclass{scrartcl}
\usepackage{pgfplotstable,tikz,filecontents}

\begin{document} 
  \begin{filecontents*}{coord1.dat}
% x   y
0    0
1    1
2    2
\end{filecontents*}
\begin{filecontents*}{coord2.dat}
%  x   y
0    1
1    2
2    3
\end{filecontents*}
  \pgfplotstableread{coord1.dat}{\firsttable}   
  \pgfplotstableread{coord2.dat}{\secodtable} 
  \pgfplotstablegetrowsof{coord1.dat}
  \pgfmathsetmacro{\rows}{\pgfplotsretval-1}      
\begin{tikzpicture}

\foreach \i in {0,...,\rows}{%
  \pgfplotstablegetelem{\i}{[index] 0}\of{\firsttable} 
  \let\xA\pgfplotsretval 
  \pgfplotstablegetelem{\i}{[index] 1}\of{\firsttable} 
  \let\yA\pgfplotsretval     
  \foreach \j in {0,...,\rows}{%
    \pgfplotstablegetelem{\j}{[index] 0}\of{\secodtable} 
    \let\xB\pgfplotsretval 
    \pgfplotstablegetelem{\j}{[index] 1}\of{\secodtable} 
    \let\yB\pgfplotsretval        
    \draw [-latex] (\xA,\yA) node[below]{\xA,\yA} -- (\xB,\yB) node[above]{\xB,\yB};
  }%
 }%   
\end{tikzpicture}
\end{document} 

enter image description here

  • That worked. Some changes I have made and I had to copy the actual version to my computer. But it worked. :) – pirad Nov 29 '11 at 12:40
8

Solution #1 – datatool

Unless I misunderstand, you can use datatool, similar to Drawing different tikz shapes parameterized by data from a file.

The files with the coordinates are created by the filecontents* environment.

\documentclass[a4paper]{scrartcl}
\usepackage{datatool,tikz,filecontents}
\begin{filecontents*}{coord1.dat}
x,y
0,0
1,1
2,2
\end{filecontents*}
\begin{filecontents*}{coord2.dat}
x,y
0,1
1,2
2,3
\end{filecontents*}
\DTLloaddb[noheader=false]{coordinates1}{coord1.dat}
\DTLloaddb[noheader=false]{coordinates2}{coord2.dat}

\begin{document}
\begin{tikzpicture}
\DTLforeach*{coordinates1}{\xA=x, \yA=y}{%
  \DTLforeach*{coordinates2}{\xB=x, \yB=y}{
     \draw [-latex] (\xA,\yA) node[below]{\xA,\yA} -- (\xB,\yB) node[above]{\xB,\yB};}}
\end{tikzpicture}
\end{document}

produces

enter image description here

Solution #2 – Lua

The following may be, I don't know, horrible. It uses Lua code to read the files and loop over the coordinates, and must therefore be compiled with lualatex. The same files, coord1.dat and coord2.dat were used, written in the same way. I took the easy way, so you cannot access the separate x and y coordinates of each point, as each element in the lua tables Ca and Cb contains one line of the file, e.g., 1,1. Also, as it is, this won't work if the two coordinate lists are of different lengths.

The output is the same as above.

\documentclass{scrartcl}
\usepackage{tikz,luacode,filecontents}
\begin{filecontents*}{coord1.dat}
x,y
0,0
1,1
2,2
\end{filecontents*}
\begin{filecontents*}{coord2.dat}
x,y
0,1
1,2
2,3
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\begin{luacode}
c1 = io.open("./coord1.dat","r")
c2 = io.open("./coord2.dat","r")
local count = 1
Ca = {}
Cb = {}
while true do
  local line1 = c1:read()
  local line2 = c2:read()
  if line1 == nil then break end
  Ca[count], Cb[count] = line1, line2
  count = count + 1
end
c1:close()
c2:close()
rows = \#Ca
for i=2,rows do
  for j=2,rows do
    tex.sprint("\\draw [-latex] (", Ca[i], ")node[below]{", Ca[i], "} -- (", Cb[j], ") node[above] {", Cb[j], "};")
  end
end
\end{luacode}
\end{tikzpicture}
\end{document}
  • Somehow doesn't work for me: " ! Undefined control sequence. <argument> ...entryfromcurrentrow {\noexpand \yA }{\dtl@columnindex {coordi... l.10 ...,\yA} -- (\xB,\yB) node[above]{\xB,\yB};}} ? " – pirad Nov 28 '11 at 20:28
  • @pirad Sorry, don't know what's wrong. Old version of datatool perhaps? (See here for how to check the version, I have v2.03 from 2009/11/15.) – Torbjørn T. Nov 28 '11 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.