Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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;
    }
share|improve this question

2 Answers 2

up vote 7 down vote accepted

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

share|improve this answer
    
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

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}
share|improve this answer
    
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

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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