1

On a beamer frame, I have two tikzpicture environments one below the other. Both use the axis environment with identical scaling and domains. I need to:

  1. Extract some coordinate from the picture on top.
  2. Convert such coordinate to axis cs: and print its x and y components on the picture.
  3. Store the converted (x,y) components.
  4. Use the converted (x,y) components in the subsequent tikzpicture environment.

I have already tried to tackle these issues through the solutions that have been proposed to some related problems, such as Coordinates of intersections and Extract x, y coordinate of an arbitrary point in TikZ. While admittedly not addressing all of the four points above, the solutions I have consulted typically extract only one of the coordinate components and/or do not jointly tackle the issue of conversion to axis cs:. Instead, I need both coordinate components to be extracted and converted. Moreover, I need to reuse such components in the subsequent tikzpicture environment.

I attach hereby a MWE and the resulting outcome (except for the callout). The comments to the script provide further details to my question.

\documentclass{beamer}
\usepackage[mode=buildnew]{standalone}

% Drawing
\usepackage{tikz,tkz-graph} 
\usetikzlibrary{intersections,positioning}
\tikzset{>=latex}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{frame}
\frametitle{Frame title}
\centering

% Top picture
\begin{tikzpicture}[
    baseline=(current bounding box.north),
    trim axis left,
    trim axis right
]
    \begin{axis}[
        width=5cm,
        xmin=0,
        xmax=24,
        ymin=-8,
        ymax=16,
        xtick={10},
        xticklabels={$y_e=10$},
        ytick={10},
        yticklabels={$r_S=10$},
        clip=true
    ]

    % Constant parameters
    \pgfmathsetmacro{\isv}{22.5}
    \pgfmathsetmacro{\k}{1.25}
    \pgfmathsetmacro{\ye}{10}
    \pgfmathsetmacro{\rs}{10}

    % Vertical line corresponding to ye
    \addplot [name path=ye,red] coordinates {(\ye,\pgfkeysvalueof{/pgfplots/ymin}) (\ye,\pgfkeysvalueof{/pgfplots/ymax})};

    % Horizontal line corresponding to rs
    \addplot [name path=rs,red] coordinates {(\pgfkeysvalueof{/pgfplots/xmin},\rs) (\pgfkeysvalueof{/pgfplots/xmax},\rs)};

    % Downward sloping IS curve
    \addplot [name path=is,smooth,very thick,domain=\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}] {\isv-\k*x} node [anchor=west,pos=0.85] {$IS$};

    % Seek the intersection between the ye line and IS and label the point of intersection as A
    \path [name intersections={of=ye and is,by={A}}] node [anchor=south west,xshift=-1mm,yshift=-1mm] at (A) {$A$};

    % Get the coordinates of point A
    \pgfgetlastxy{\Ax}{\Ay}

    % Print the coordinates next to the A label
    \node [anchor=south west,xshift=2mm,yshift=-1mm] at (A) {\tiny (\Ax,\Ay)}; % <-- Step 1: I need both the x and y components to be expressed (and subsequently stored) in terms of the axis coordinate system (i.e. 'axis cs:'). Also, I still do not understand why the command pints (0.0pt,0.0pt) instead of the standard coordinates of A.

    \end{axis}

\end{tikzpicture}


% Bottom picture
\begin{tikzpicture}[
    baseline=(current bounding box.north),
    trim axis left,
    trim axis right
]
    \begin{axis}[
        width=5cm,
        xmin=0,
        xmax=24,
        ymin=-14,
        ymax=10,
        xtick={10},
        xticklabels={$y_e$},
        ytick={2},
        yticklabels={$\pi^T$}
    ]

        % Constant parameters
        \pgfmathsetmacro{\a}{0.5}
        \pgfmathsetmacro{\pe}{2}
        \pgfmathsetmacro{\pt}{2}
        \pgfmathsetmacro{\ye}{10} % <-- Step 2: I need to specify at least this number as the \Ax coordinate derived from the tikzpciture above. If possible, it would be nice to insert \Ax also in the xtick list.

        % Upward sloping PC curve
        \addplot [name path=pc,color=black,very thick,domain=\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}] {\pe+\a*(x-\ye)} node [anchor=north,pos=0.85] {$PC$};

        % Vertical line corresponding to ye
        \addplot [name path=ye,red] coordinates {(\ye,\pgfkeysvalueof{/pgfplots/ymin}) (\ye,\pgfkeysvalueof{/pgfplots/ymax})};

    \end{axis}

\end{tikzpicture}

\end{frame}

\end{document}

Result of MWE

2

COMPLETE REVISION: ... after some iterations. A similar question has been answered here. Rewriting the code of this answer such that it also computes the y coordinates leads to this answer.

\documentclass{beamer}
\usepackage[mode=buildnew]{standalone}

% Drawing
\usepackage{tikz,tkz-graph} 
\usetikzlibrary{intersections,positioning}
\tikzset{>=latex}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

% from https://tex.stackexchange.com/a/170243/121799
\newlength{\lenx}
\newlength{\plotwidth}
\newlength{\leny}
\newlength{\plotheight}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/pgfplots/#1}}

%output will be given by \pgfmathresult
\newcommand{\Getxycoords}[3]% #1 = node name, #2 x coordinate, #2 y coordinate
{\pgfplotsextra{%
  \pgfextractx{\lenx}{\pgfpointdiff{\pgfplotspointaxisxy{0}{0}}{\pgfpointanchor{#1}{center}}}%
  \pgfextractx{\plotwidth}{\pgfpointdiff{\pgfplotspointaxisxy{\getvalue{xmin}}{0}}%
    {\pgfplotspointaxisxy{\getvalue{xmax}}{0}}}%
  \pgfextracty{\leny}{\pgfpointdiff{\pgfplotspointaxisxy{0}{0}}{\pgfpointanchor{#1}{center}}}%
  \pgfextracty{\plotheight}{\pgfpointdiff{\pgfplotspointaxisxy{0}{\getvalue{ymin}}}%
    {\pgfplotspointaxisxy{0}{\getvalue{ymax}}}}%
  \pgfmathsetmacro{\myx}{\lenx*(\getvalue{xmax}-\getvalue{xmin})/\plotwidth}%
  \pgfmathsetmacro{\myy}{\leny*(\getvalue{ymax}-\getvalue{ymin})/\plotheight}%
  \xdef#2{\myx}
  \xdef#3{\myy}
  %\typeout{\myx,\myy} <- for debugging
}}

\begin{document}

\begin{frame}
\frametitle{Frame title}
\centering

% Top picture
\begin{tikzpicture}[
    baseline=(current bounding box.north),
    trim axis left,
    trim axis right
]
    \begin{axis}[
        width=5cm,
        xmin=0,
        xmax=24,
        ymin=-8,
        ymax=16,
        xtick={10},
        xticklabels={$y_e=10$},
        ytick={10},
        yticklabels={$r_S=10$},
        clip=true
    ]

    % Constant parameters
    \pgfmathsetmacro{\isv}{22.5}
    \pgfmathsetmacro{\k}{1.25}
    \pgfmathsetmacro{\ye}{10}
    \pgfmathsetmacro{\rs}{10}

    % Vertical line corresponding to ye
    \addplot [name path=ye,red] coordinates {(\ye,\pgfkeysvalueof{/pgfplots/ymin}) (\ye,\pgfkeysvalueof{/pgfplots/ymax})};

    % Horizontal line corresponding to rs
    \addplot [name path=rs,red] coordinates {(\pgfkeysvalueof{/pgfplots/xmin},\rs) (\pgfkeysvalueof{/pgfplots/xmax},\rs)};

    % Downward sloping IS curve
    \addplot [name path=is,smooth,very thick,domain=\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}] {\isv-\k*x} node [anchor=west,pos=0.85] {$IS$};

    % Seek the intersection between the ye line and IS and label the point of intersection as A
    \path [name intersections={of=ye and is,by={A}}] node [anchor=south west,xshift=-1mm,yshift=-1mm] at (A) {$A$}
    \pgfextra{\pgfgetlastxy{\myx}{\myy}
    \xdef\Absolutex{\myx}
    \xdef\Absolutey{\myy}
    };


    \draw[blue,fill] (A) circle (2pt);

    % Get the coordinates of point A
    \Getxycoords{A}{\Ax}{\Ay}
    \end{axis}
    \node[anchor=south west,xshift=0.2cm,yshift=1.1cm, text width=3.7cm,
    font=\tiny,draw] (explain) at (A){%
    the node has plot coordinates (\Ax,\Ay) and absolute coordinates 
    (\Absolutex,\Absolutey)};
    \draw[gray,-latex] (explain) to[out=-90,in=90] (A);
\end{tikzpicture}

% Bottom picture
\begin{tikzpicture}[
    baseline=(current bounding box.north),
    trim axis left,
    trim axis right
]
    \begin{axis}[
        width=5cm,
        xmin=0,
        xmax=24,
        ymin=-14,
        ymax=10,
        xtick={10},
        xticklabels={$y_e$},
        ytick={2},
        yticklabels={$\pi^T$},
        enlargelimits=0.1 %<-1
    ]

        % Constant parameters
        \pgfmathsetmacro{\a}{0.5}
        \pgfmathsetmacro{\pe}{2}
        \pgfmathsetmacro{\pt}{2}
        \pgfmathsetmacro{\ye}{\Ax} % <-- Step 2: I need to specify at least this number as the \Ax coordinate derived from the tikzpciture above. If possible, it would be nice to insert \Ax also in the xtick list.

        % Upward sloping PC curve
        \addplot [name path=pc,color=black,very thick,domain=\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax}] {\pe+\a*(x-\ye)} node [anchor=north,pos=0.85] {$PC$};

        % Vertical line corresponding to ye
        \addplot [name path=ye,red] coordinates {(\ye,\pgfkeysvalueof{/pgfplots/ymin}) (\ye,\pgfkeysvalueof{/pgfplots/ymax})};

        \node [label=south:{\tiny (\Ax,\Ay)}] (B) at (axis cs:\Ax,\Ay){}; 
        \Getxycoords{B}{\Bx}{\By}
        \draw[blue,fill] (B) circle (2pt);
    \end{axis}
    \typeout{debug:\space\Bx,\By}
\end{tikzpicture}

\end{frame}

\end{document}

enter image description here

In addition, the absolute coordinates are computed. Both are shown in the upper plot.

  • I had clearly misunderstood the functioning of \pgfgetlastxy. Your answer also makes clear that whichever coordinate is saved in the first picture remains defined also for the second picture. Hence, my question ultimately boils down to a conversion issue. That is, I need \Ax and \Ay to be converted to the axis cs: coordinate system, thus generating two new coordinate components (\AxCS,\AyCS). This would allow me, for instance, to insert the resulting numbers in a line such as \pgfmathsetmacro{\ye}{\AxCS} in the second picture. – Brocardo Reis Mar 16 '18 at 13:41
  • To further clarify, the accepted answer to Convert from physical dimensions to axis cs coordinate values provides a way to transform the floating point associated to \Ax into the corresponding axis cs: coordinate component. Unfortunately, I fail to adapt that code so as to do the same also for \Ay. – Brocardo Reis Mar 16 '18 at 14:12
  • @BrocardoReis Yes, I know, see my revised answer. ;-) – user121799 Mar 16 '18 at 14:22
  • Your updated answer solves the problem of getting both the x- and y-component of the coordinate. However, to stick to the my original question, you should update it by defining \pgfmathsetmacro{\ye}{\Ax} in the second picture instead of \pgfmathsetmacro{\ye}{\Ay}. Also, something is wrong with the blue arrow: its origin should correspond exactly to (\Ax,\Ay), I think. At any rate, to simplify matters feel free to edit both my question and your answers to some common range that will fit all necessary points. – Brocardo Reis Mar 16 '18 at 14:36
  • @BrocardoReis I updated my answer. The reason why B was at the wrong spot was that nodes are extended objects. I fixed this by using a label to display the coordinates. And I did not really have to modify your setting, I only added ` enlargelimits=0.1 ` to the options of the second plot such that the coordinate is shown. – user121799 Mar 16 '18 at 14:52
2

With the release of PGFPlots v1.16 it is now possible to store (axis) coordinates with \pgfplotspointgetcoordinates in data point, which then can be called by \pgfkeysvalueof or \pgfkeysgetvalue. With this it is quite simple to adapt/simplify the \Getxycoords macro given in marmot's answer.

% used PGFPlots v1.16
\documentclass[border=5pt,varwidth]{standalone}
\usepackage{pgfplots}
    \usetikzlibrary{
        intersections,
    }
    % create a custom style to store common `axis' options
    \pgfplotsset{
        my axis style/.style={
            width=5cm,
            xmin=0,
            xmax=24,
            domain=\pgfkeysvalueof{/pgfplots/xmin}:\pgfkeysvalueof{/pgfplots/xmax},
            samples=2,
            clip mode=individual,
        },
    }
    % ---------------------------------------------------------------------
    % Coordinate extraction
    % #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}
        \raggedleft
% Top picture
\begin{tikzpicture}
    \begin{axis}[
        my axis style,
        %
        ymin=-8,
        ymax=16,
        xtick={10},
        xticklabels={$y_e=10$},
        ytick={10},
        yticklabels={$r_S=10$},
    ]

            % Constant parameters
            \pgfmathsetmacro{\isv}{22.5}
            \pgfmathsetmacro{\k}{1.25}
            \pgfmathsetmacro{\ye}{10}
            \pgfmathsetmacro{\rs}{10}

        % Vertical line corresponding to ye
        \addplot [name path=ye,red] coordinates {
            (\ye,\pgfkeysvalueof{/pgfplots/ymin})
            (\ye,\pgfkeysvalueof{/pgfplots/ymax})
        };

        % Horizontal line corresponding to rs
        \addplot [name path=rs,red] coordinates {
            (\pgfkeysvalueof{/pgfplots/xmin},\rs)
            (\pgfkeysvalueof{/pgfplots/xmax},\rs)
        };

        % Downward sloping IS curve
        \addplot [
            name path=is,
            smooth,
            very thick,
        ] {\isv-\k*x}
            node [anchor=west,pos=0.85] {$IS$}
        ;

        % Seek the intersection between the ye line and IS and label the point of intersection as A
        \path [name intersections={of=ye and is,by={A}}]
            node [anchor=south west,xshift=-1mm,yshift=-1mm] at (A) {$A$}
        ;

            % Get the coordinates of point A
            \Getxycoords{A}{\Ax}{\Ay}

        % Print the coordinates next to the A label
        \node [
            anchor=south west,
            xshift=2mm,
            yshift=-1mm,
            /pgf/number format/precision=3,
        ] at (A) {\tiny (%
            \pgfmathprintnumber{\Ax},%
            \pgfmathprintnumber{\Ay}%
        )};

    \end{axis}
\end{tikzpicture}

% Bottom picture
\begin{tikzpicture}
    \begin{axis}[
        my axis style,
        %
        ymin=-14,
        ymax=10,
        xtick={\Ax},            % the stored value can used (almost) wherever you want
        xticklabels={$y_e$},
        ytick={2},
        yticklabels={$\pi^T$},
    ]

            % Constant parameters
            \pgfmathsetmacro{\a}{0.5}
            \pgfmathsetmacro{\pe}{2}
            \pgfmathsetmacro{\pt}{2}
            \pgfmathsetmacro{\ye}{\Ax}          % of course also here

        % Upward sloping PC curve
        \addplot [
            name path=pc,
            very thick,
        ] {\pe+\a*(x-\ye)}
            node [anchor=north,pos=0.85] {$PC$}
        ;

        % Vertical line corresponding to ye
        \addplot [name path=ye,red] coordinates {
            (\ye,\pgfkeysvalueof{/pgfplots/ymin})
            (\ye,\pgfkeysvalueof{/pgfplots/ymax})
        };

    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

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.