# PGFplots: extract coordinates, assign to global with dynamic name

I would like to loop over nodes, extract their coordinates in the axis coordinate system, and assign these to dynamically named macros. (This is a followup on this and this.)

Following this answer, I define a function \Getxycoords that retrieves the coordinates in the axis cs of a node, and assign it to a global macro.

I would like to be able to do this for several points in a loop.

In the MWE, I define three nodes da, db, and dc. I'd like to store their coordinates (in the axis system) as \Xa, \Ya, \Xb, \Yb, \Xc, \Yc, using a loop. Unfortunately, I do not know how to pass a dynamic global name as the second and third arguments to the \Getxycoords function

% used PGFPlots v1.16
\documentclass[
%border=5pt,varwidth
]{article}
\usepackage{pgfplots}
\pgfplotsset{   compat=1.16}
\usetikzlibrary{intersections}

% ---------------------------------------------------------------------
% Coordinate extraction (from tex.stackexchange.com/questions/420498/extract-convert-store-and-reuse-x-y-coordinate-components/426245#426245)
% #1: node name
% #2: output macro name: x coordinate
% #3: output macro name: y coordinate
\newcommand{\Getxycoords}[3]{%
\pgfplotsextra{%
% using \pgfplotspointgetcoordinates' stores the (axis)
% coordinates in data point' which then can be called by
% \pgfkeysvalueof' or \pgfkeysgetvalue'
\pgfplotspointgetcoordinates{(#1)}%
% \global' (a TeX macro and not a TikZ/PGFPlots one) allows to
% store the values globally
\global\pgfkeysgetvalue{/data point/x}{#2}%
\global\pgfkeysgetvalue{/data point/y}{#3}%
}%
}
% ---------------------------------------------------------------------
\begin{document}

\begin{tikzpicture}
\begin{axis}[xmin=0,xmax=80,ymin=0,ymax=80]
\pgfplotsforeachungrouped \i/\j in {
1 / a,
2 / b,
3 / c
}{
\edef\temp{%
\noexpand%
\node [circle,inner sep=2pt,circle,fill,label=above:\j]  (d\j) at (axis cs:\i*10,\i*20+5) {};%
}
\temp
}

\pgfplotsforeachungrouped \j in { a, b, c}{
\Getxycoords{d\j}{\X\j}{\Y\j};
}
\end{axis}
\node[below] (test) at (dc) {\Xc};
\end{tikzpicture}
\end{document}


which results in ! Package pgf Error: No shape named dc is known.

I also tried

\pgfplotsinvokeforeach{a, b, c}{
\Getxycoords{d#1}{\X#1}{\Y#1};
}


which gives: ! Package pgf Error: No shape named da is known. (and so on for db and dc.)

I'm guessing this has to do with when things get expanded or not, but I'm utterly confused on the subject.

• Yes. Any reason why you want to read off the coordinates before \end{axis}? – marmot Jun 22 '18 at 16:35
• Mmm, I think there might be use-cases where I need to use those coordinates in the same axis environment. But happy to see a solution without, to start with! – Peutch Jun 22 '18 at 16:38
• In your code there are several things that are not quite right. For instance, in \Getxycoords{d\j}{\X\j}{\Y\j} \X\j does not evaluate to \Xa etc. But I would also be interested in a solution where I can read off absolute coordinates when the axis is in the make. Therefore +1. – marmot Jun 22 '18 at 16:42

Here is a proposal to extract the coordinates of any object, regardless of whether or not this is a pgfplots axis. Just let TikZ compute the coordinates (relative to the origin) and normalize it to those of the point (1,1) relative to the origin. (And I also define \Xc etc.)

\documentclass[
%border=5pt,varwidth
]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{intersections,calc}

\begin{document}

\begin{tikzpicture}
\begin{axis}[xmin=0,xmax=80,ymin=0,ymax=80]
\pgfplotsforeachungrouped \i/\j in {
1 /a,
2 /b,
3 /c
}{
\edef\temp{%
\noexpand\node [circle,inner sep=2pt,circle,fill,label=above:\j,alias={d\j}]  (d\j) at (axis cs:\i*10,\i*20+5) {};%
}
\temp
}
\coordinate (O) at (0,0);
\coordinate (X) at (1,1);
\end{axis}
\pgfplotsforeachungrouped \j in { a, b, c}{
\path let \p1=($(d\j.center)-(O)$),\p2=($(X)-(O)$),\n1={\x1/\x2},\n2={\y1/\y2} in
\pgfextra{\pgfmathparse{\n1}
\xdef\X{\pgfmathresult}
\pgfmathparse{\n2}
\xdef\Y{\pgfmathresult}};
\typeout{\X,\Y}
\expandafter\xdef\csname X\j\endcsname{\X}
\expandafter\xdef\csname Y\j\endcsname{\Y}
}

\node[below] (test) at (dc) {\Xc};
\end{tikzpicture}
\end{document}
`