I have a CSV from which I'm trying to draw dots using \node
within a tikzpicture. I can get it to read the data and draw something, but it only draws the last row, and multiple times.
I know that normally foreach
loops only get handled inside the axis
environment at the end, and so I have tried this both with pgfplotsinvokeforeach
and the datatool
package, but there is no difference.
Below is a MWE, with \DTLforeach
commented out but otherwise working identically to the pgfplotsinvokeforeach
loop.
Note I've added a manual dot with the "a" label as well to show the difference in thickness between that and the looped ones, showing that it's drawing it multiple times in the loop.
What am I doing wrong here? I should see three dots with labels placed according to the data in filecontents
(not including the manual one).
\documentclass{article}
\usepackage{datatool}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{filecontents}
\begin{document}
\begin{filecontents*}{formants.csv}
label,f1,f2
"i",1800,275
"o",235,487
"a",650,810
\end{filecontents*}
% using datatool
\DTLloaddb[keys={formantlabel,formantone,formanttwo}]{formants}{formants.csv}
\DTLforeach*{formants}{\formantlabel=formantlabel,\formantone=formantone,\formanttwo=formanttwo}{%
\formantlabel, \formantone, \formanttwo \\
}
% using pgfplots functions
\pgfplotstableread[col sep=comma]{formants.csv}{\formants}
\pgfplotstablegetrowsof\formants
\pgfmathsetmacro\numberofrows{\pgfplotsretval-1}
\begin{figure}[h]
\begin{tikzpicture}
\begin{axis}[
xmin = 0,
xmax = 2000,
ymin = 0,
ymax = 1000
]
% this works but only shows the last one
\pgfplotsinvokeforeach{0,...,\numberofrows}{
\pgfplotstablegetelem{#1}{label}\of\formants
\pgfmathsetmacro{\flabel}{\pgfplotsretval}
\pgfplotstablegetelem{#1}{f1}\of\formants
\pgfmathsetmacro{\fone}{\pgfplotsretval}
\pgfplotstablegetelem{#1}{f2}\of\formants
\pgfmathsetmacro{\ftwo}{\pgfplotsretval}
\node[label={180:{\flabel}},circle,fill,inner sep=2pt] at (axis cs:\fone, \ftwo) {}; %
}
% this also works but again only shows the last one
% \DTLforeach*{formants}{
% \formantlabel=formantlabel,\formantone=formantone,\formanttwo=formanttwo}{%
% \node[label={180:{\formantlabel}},circle,fill,inner sep=2pt] at (axis cs:\formantone, \formanttwo) {}; %
% }
\node[label={180:{a}},circle,fill,inner sep=2pt] at (axis cs:650.886, 910.603) {}; % test
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
Also note this is XeLaTeX, in case that matters.
Here's how that looks on my end, with the lower "a" dot being the looped one, and darker than the higher one. The text above the plot is a loop showing that the data is being properly read.