# Calculate x-coordinate for given y-value by interpolating data from pgfplotstable

I have a text file data.txt with the following content:

-2 -2 +1
+0 +1 +3
+2 +4 +2


I read it with

\pgfplotstableread{data.txt}\data


and then plot the second column by the first column with

\addplot table [x index = 0, y expr = \thisrowno{1}  ] from \data;


I'd now like to calculate the exact x-value where the graph above crosses the y = 0 line. How can I do that?

I failed using this answer as I don't understand how it is to use. How do I pass the correct dataset to pgfmath?

Jake also offered various solutions, but actually don't want a node, but number. Also his solution does not interpolate and does not give "exact" results.

## MWE

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\begin{tikzpicture}

\pgfplotstableread{data.txt}\data

\begin{axis}
\addplot table [x index = 0, y expr = \thisrowno{1}  ] from \data;

% some calculations to get desired value
\def\xroot{-0.66}
% draw vertical line
\addplot[color=black,thin, dashed] coordinates {(\xroot,4)(\xroot,-2)}
;
% draw zero line
\addplot[color=black,thin, dashed] coordinates {(-2,0)(2,0)}
;

\end{axis}

\end{tikzpicture}

\end{document}


Desired output (with manual calculated value): ## Edit

I now managed to get the intersection point as a node, but how to get the coordinate values?

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}

\pgfplotstableread{data.txt}\data

\begin{axis}
\addplot[name path global = data] table [x index = 0, y expr = \thisrowno{1} ] from \data;

% draw zero line
\addplot[color=black,thin, dashed,name path global = zeroline] coordinates {(-2,0)(2,0)}
;

% some calculations to get desired value
\def\xroot{-0.66}
% draw vertical line
\addplot[color=black,thin, dashed] coordinates {(\xroot,4)(\xroot,-2)}
;

\newcommand*{\getFirstIntersection}{
\coordinate [name intersections={of=#1 and #2, name=i}] [] (i-1) coordinate (#3);
}

\getFirstIntersection{zeroline}{data}{isect}
\node [fill, color=red] at (isect) {};

\end{axis}

\end{tikzpicture}

\end{document} I further tried:

\pgfgetlastxy{\macrox}{\macroy}
\node [small dot, color=red, text=black] at (wdaII) {\pgfplotsconvertunittocoordinate{x}{\macrox}\pgfmathprintnumber[fixed,precision=1]{\pgfmathresult}};


but it returns 0 for x as well as for y.

Though this is a simple example, the solutions needs to be compatible with groupplots and log-scale axes.. For example this great answer just works for linear axes.

## 1 Answer

Here I present a solution using the function graph cut y feature of the PGFPlotsTable package. From that manual I used the example and modified it to fit your requirements using the groupplots library.

For more details on how it works please have a look at the comments of the code.

(The data files can be found in your TeX installation in the file "TeX installation folder\doc\latex\pgfplots\pgfplots.doc.src.tar.bz2" and in there in the subfolder "plotdata".)

% used PGFPlots v1.14
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usetikzlibrary{
pgfplots.groupplots,
}
\pgfplotsset{
% use this compat' level to avoid a "dimension too large" error
compat=1.11,
}
% for simplicity save the y value to which you want to find the x
% value in a variable
% (because we need it several times later in visualization phase)
\pgfmathsetmacro{\ycut}{2.5e-4}
\pgfplotstablenew[
create on use/cut/.style={
%
create col/function graph cut y={
% search for fixed L2 = \ycut
\ycut
}{
% double log, each function is L2(Basis)
x=Basis,
y=L2,
xmode=log,
ymode=log,
}{
% now, provide each single function f_i(Basis):
% (data files copied from PGFPlots source files in "plotdata" folder)
{table=newexperiment1.dat},
{table=newexperiment2.dat},
{table=newexperiment3.dat},
}
},
columns={cut},
]{3}\loadedtable
\begin{document}

%% For debugging purposes only: Show the data
%\pgfplotstabletypeset{\loadedtable}

\begin{tikzpicture}[
/pgf/number format/.cd,
fixed,
precision=2,
]
% also for simplicity store the found "cut" values in variables
% (because we need them to set pins and also want to print the number)
\pgfplotstablegetelem{0}{cut}\of{\loadedtable}
\pgfmathsetmacro{\CutOne}{\pgfplotsretval}
\pgfplotstablegetelem{1}{cut}\of{\loadedtable}
\pgfmathsetmacro{\CutTwo}{\pgfplotsretval}
\pgfplotstablegetelem{2}{cut}\of{\loadedtable}
\pgfmathsetmacro{\CutThree}{\pgfplotsretval}
\begin{groupplot}[
group style={
group size=2 by 1,
},
xmode=log,
ymode=log,
% so it is not needed to repeat this in both \nextgroupplot's
before end axis/.code={
\draw [blue!30!white] (1,\ycut) -- (1e5,\ycut);
},
]
\nextgroupplot
\addplot table [x=Basis,y=L2] {newexperiment1.dat};
\addplot table [x=Basis,y=L2] {newexperiment2.dat};

% add the pins to the cut coordinates and add corresponding labels
% (with the help of the stores variables)
\node [pin=-90:{$x=\pgfmathprintnumber{\CutOne}$}]   at (\CutOne,\ycut) {};
\node [pin=+45:{$x=\pgfmathprintnumber{\CutTwo}$}]   at (\CutTwo,\ycut) {};
\nextgroupplot
\addplot table [x=Basis,y=L2] {newexperiment3.dat};

\node [pin=+45:{$x=\pgfmathprintnumber{\CutThree}$}] at (\CutThree,\ycut) {};
\end{groupplot}
\end{tikzpicture}
\end{document} • thanks for your answer! Could you provide the data you used, so the example is fully executable? I don't have the time right now to recreate the case with my real data from a year ago. But it seems to be a great answer I'd like to accept. – thewaywewalk Feb 27 '17 at 11:42
• I added some explaining words to the text where the data files can be found in the TeX installation. If you really want them to be included, feel free to edit my answer ;) – Stefan Pinnow Feb 27 '17 at 13:47