3

Difficulty with drawing the right coordinates

I use pgfplots to draw a set of data points, fit them with gnuplot and then find the intersection points between the linear fits and a vertical bar. Now I would like to draw a horizontal line from the intersection point to the y-axis. It is no problem to draw the line, but the y-coordinates displayed are wrong. I discovered that the y-value changes when I vary the size of my plot. This makes me suggest I might have done something wrong with the coordinate transformation. So my Question is:

How can I extract and draw the coordinates of the intersection points independently of the plotsize?

In other means, is there a way to store the coordinates and transform them so that they can be used withinn the tikz-picture but outside of the groupplot-environment provided by pgf?

first plot with 11cm height

same plot with 7cm height

Here is my MWE: (You can find the file points.dat under: https://www.dropbox.com/s/7g11enoltnj9fpx/points.dat?dl=0 )

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}

\usetikzlibrary{intersections,plotmarks}
\usepackage{tikz}%Added by Arne Hensel
\definecolor{myblue}{rgb}{.05,.16,.40}
\definecolor{wine-stain}{rgb}{0.5,0,0}
\usetikzlibrary{shapes, calc, shapes, arrows}%Added by Arne Hensel
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots}
\usepgfplotslibrary{statistics}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.13}
\pgfplotsset{width=7cm}
\pgfplotsset{every axis legend/.append style={
at={(0.5,-0.05)},
anchor=north},cycle list name=black white}
%\pgfplotsset{every axis/.append style={font=\footnotesize,
%thin,
%tick style={thin}}}
\usetikzlibrary{positioning,plotmarks,pgfplots.colormaps,external,3d,calc,arrows}
\usetikzlibrary{decorations,decorations.pathmorphing,decorations.pathreplacing}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{patterns}
%Units
\usepackage[decimalsymbol=comma]{siunitx}
\sisetup{%
  inter-unit-product=\ensuremath{{}\cdot{}},
  per-mode=symbol
  }
\usepackage{cancel}

%Define the show intersection command to show the intersection points between graphs:
\newcommand*{\ShowIntersection}[2]{
\fill 
    [name intersections={of=#1 and #2, name=i, total=\t}] 
    [black, opacity=1, every node/.style={above left, black, opacity=1}] 
    \foreach \s in {1,...,\t}{(i-\s) circle (2pt)
        %node [above right] { \s}
        };
}
%
\makeatletter
\def\markxof#1{
\pgf@process{#1}
\pgfmathparse{(\pgf@y/\pgfplotsunitxlength +\pgfplots@data@scale@trafo@SHIFT@y)/10^\pgfplots@data@scale@trafo@EXPONENT@y}
}
\makeatother
%
\begin{document}

    \begin{tikzpicture}
    \def\verticalbar{0}
        \begin{groupplot}[
                        group style={
                            group size=1 by 1
                            ,horizontal sep=2cm
                            ,vertical sep=3cm
                            }
                        ,height=8cm
                        ,width=10cm
                        ,/tikz/font=\small
                        ]
        \nextgroupplot[%legend pos=north west
                ,xlabel={t [\SI[mode=text]{}{\second}]}
                ,xticklabel pos=upper
                ,xlabel near ticks
                ,ylabel={T [\SI[mode=text]{}{\kelvin}]}
                ,yticklabel pos=left
                ,ylabel near ticks
                ,scaled ticks=false
                ,grid=both%Gridlines
                ,tick align=outside
                ,minor x tick num=1
                ,minor y tick num=1
                ,xmin=-2
                ,xmax=2
                ,ymin=-2
                ,ymax=2
                ,cycle list name=exotic%black white
                ]
        \addplot+[raw gnuplot
            , name path=p1
            , wine-stain
            , mark=none
            , dashed
            %, smooth,domain = 0:2
            %,y domain = -2:2
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=a*x+b;
            fit[x=-2:-0.75] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-2:1] f(x);
            set print "parameters11.dat";
            print a,b;
            };
            \addlegendentry{\pgfplotstableread{parameters11.dat}\parameters
        \pgfplotstablegetelem{0}{0}\of\parameters\pgfmathsetmacro\paramA{\pgfplotsretval}
        \pgfplotstablegetelem{0}{1}\of\parameters\pgfmathsetmacro\paramB{\pgfplotsretval}
        Lineare Regression: $T_1(t)=\pgfmathprintnumber{\paramA} t                      \pgfmathprintnumber[print sign]{\paramB} $ }
        \addplot+[raw gnuplot
            , name path=p2
            ,myblue
            , mark=none
            , dashed
            %, smooth,domain = 0:2
            %,y domain = -2:2
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=a*x+b;
            fit[x=0.75:2] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-1:2] f(x);
            set print "parameters12.dat";
            print a,b;
            };
            \addlegendentry{\pgfplotstableread{parameters12.dat}\parameters
        \pgfplotstablegetelem{0}{0}\of\parameters\pgfmathsetmacro\paramA{\pgfplotsretval}
        \pgfplotstablegetelem{0}{1}\of\parameters\pgfmathsetmacro\paramB{\pgfplotsretval}
        Lineare Regression: $T_2(t)=\pgfmathprintnumber{\paramA} t                      \pgfmathprintnumber[print sign]{\paramB} $ }
        \addplot+[raw gnuplot
            ,name path=p3
            , black
            , mark=none
            %, smooth,domain = 0:2
            %,y domain = -2:2
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=atan(a*x)+b;
            fit[x=-2:2] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-2:2] f(x);
            set print "parameters13.dat";
            print a,b;
            };
            \addlegendentry{\pgfplotstableread{parameters13.dat}\parameters
        \pgfplotstablegetelem{0}{0}\of\parameters\pgfmathsetmacro\paramA{\pgfplotsretval}
        \pgfplotstablegetelem{0}{1}\of\parameters\pgfmathsetmacro\paramB{\pgfplotsretval}
        Fit: $T(t)= \arctan\pgfmathprintnumber{\paramA} t                       \pgfmathprintnumber[print sign]{\paramB} $ }
        \addplot+[black
                    ,mark=+
                    ,only marks
                    %,mark size=0.1pt
                    %,samples=100
                    %,no markers
                    ,error bars/.cd%Errorbars
                    %,y dir=both
                    %,y fixed=0.5
                    %,y explicit
                    ,x dir=both
                    ,x explicit
                    %,x fixed=0.1
                    ]
                    table[
                    x expr=\thisrowno{0}
                    ,y expr=\thisrowno{1}
                    %,x error index=2
                    ] {points.dat};
                    \addlegendentry{$T(t)$: Messwerte}
        %Draw the vertical bar
        \draw [name path=bar,black] (\verticalbar,-2) -- (\verticalbar,2);
        %Compute the filled area without plotting it for the label:
        %\path[name path=lower, intersection segments={of=p1 and p3, sequence=R1 -- L2}];
        %Fill between the different line-segments
        \addplot[wine-stain
                        , area legend,pattern=north west lines
                        , pattern color=wine-stain
                        ] fill between[of=p1 and p3
                                    , soft clip={domain=-2:\verticalbar}
            ];
            \addlegendentry{A$_1$}
        \addplot[myblue
                    ,area legend,pattern=north east lines
                    ,pattern color=myblue] fill between[of=p2 and p3
                                            , soft clip={domain=\verticalbar:2}
            ];
            \addlegendentry{A$_2$}
%Show the two intersection points of the linear regression and the bar
        \ShowIntersection{p1}{bar}
        \ShowIntersection{p2}{bar}
%Draw a horizontal line from the intersection point to the y-axis
        \path[name intersections={of={p1 and bar},name=i}, name intersections={of={p2 and bar},name=in}] (i-1) (in-1);
                    \pgfplotsextra{\path(i-1)\pgfextra{\markxof{i-1}\xdef\myfirsttick{\pgfmathresult}}(in-1)\pgfextra{\markxof{in-1}\xdef\mysecondtick{\pgfmathresult}};}
        \end{groupplot}
    \draw[ultra thin, draw=gray] (i-1 -| {rel axis cs:0,0}) node[fill=yellow,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\myfirsttick} -- (i-1);
\draw[ultra thin, draw=gray] (in-1 -| {rel axis cs:0,0}) node[fill=red,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\mysecondtick} -- (in-1);
    \end{tikzpicture}

\end{document}

EDIT:

I reduced the MWE to a real MWE, but the problem still remains:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usetikzlibrary{intersections,plotmarks}
\usepackage{tikz}%Added by Arne Hensel
\usetikzlibrary{shapes, calc, shapes, arrows}%Added by Arne Hensel
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots,fillbetween}
\pgfplotsset{compat=1.13}
\pgfplotsset{width=7cm}
\usetikzlibrary{positioning,plotmarks,pgfplots.colormaps,external,3d,calc,shapes,arrows,patterns,decorations,decorations.pathmorphing,decorations.pathreplacing}
%Define the show intersection command to show the intersection points between graphs:
\newcommand*{\ShowIntersection}[2]{
\fill 
    [name intersections={of=#1 and #2, name=i, total=\t}] 
    [black, opacity=1, every node/.style={above left, black, opacity=1}] 
    \foreach \s in {1,...,\t}{(i-\s) circle (2pt)
        %node [above right] { \s}
        };
}
%
\makeatletter
\def\markxof#1{
\pgf@process{#1}
\pgfmathparse{(\pgf@y/\pgfplotsunitxlength +\pgfplots@data@scale@trafo@SHIFT@y)/10^\pgfplots@data@scale@trafo@EXPONENT@y}
}
\makeatother
%
\begin{document}
    \begin{tikzpicture}
    \def\verticalbar{0}
        \begin{groupplot}[
                        group style={
                            group size=1 by 1
                            ,horizontal sep=2cm
                            ,vertical sep=3cm
                            }
                        ,height=8cm
                        ,width=10cm
                        ,/tikz/font=\small
                        ]
        \nextgroupplot[%legend pos=north west
                ,xmin=-2
                ,xmax=2
                ,ymin=-2
                ,ymax=2
                ]
        \addplot+[raw gnuplot
            , name path=p1
            , mark=none
            , dashed
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=a*x+b;
            fit[x=-2:-0.75] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-2:1] f(x);
            };
        \addplot+[raw gnuplot
            , name path=p2
            , mark=none
            , dashed
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=a*x+b;
            fit[x=0.75:2] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-1:2] f(x);
            };
        \addplot+[raw gnuplot
            ,name path=p3
            , black
            , mark=none
            ,restrict y to domain=-2:2
            ,restrict x to domain=-2:2
        ] gnuplot {%set log y;
            f(x)=atan(a*x)+b;
            fit[x=-2:2] f(x) 'points.dat' using 1:2 via a,b;
            plot [x=-2:2] f(x);
            };
        \addplot+[black
                    ,only marks
                    ]
                    table[
                    x expr=\thisrowno{0}
                    ,y expr=\thisrowno{1}
                    ] {points.dat};
        %Draw the vertical bar
        \draw [name path=bar,black] (\verticalbar,-2) -- (\verticalbar,2);
        %Fill between the different line-segments
        \addplot[black
                        , area legend,pattern=north west lines
                        , pattern color=black
                        ] fill between[of=p1 and p3
                                    , soft clip={domain=-2:\verticalbar}
            ];
        \addplot[black
                    ,area legend,pattern=north east lines
                    ,pattern color=black] fill between[of=p2 and p3
                                            , soft clip={domain=\verticalbar:2}
            ];
%Show the two intersection points of the linear regression and the bar
        \ShowIntersection{p1}{bar}
        \ShowIntersection{p2}{bar}
%Draw a horizontal line from the intersection point to the y-axis
        \path[name intersections={of={p1 and bar},name=i}, name intersections={of={p2 and bar},name=in}] (i-1) (in-1);
\pgfplotsextra{\path(i-1)\pgfextra{\markxof{i-1}\xdef\myfirsttick{\pgfmathresult}}(in-1)\pgfextra{\markxof{in-1}\xdef\mysecondtick{\pgfmathresult}};}
        \end{groupplot}
    \draw[ultra thin, draw=gray] (i-1 -| {rel axis cs:0,0}) node[fill=yellow,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\myfirsttick} -- (i-1);
\draw[ultra thin, draw=gray] (in-1 -| {rel axis cs:0,0}) node[fill=red,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\mysecondtick} -- (in-1);
    \end{tikzpicture}
\end{document}

The produced Output:

Still wrong ccordinates with reduced code and updated version

EDIT 2

I might have found the problem, but I don't know how to fix it. the code which produces the horizontal lines and draws the node with the y-value on the left of the y-axis is inserted after the groupplot ends. It is still part of the tikz-picture, but the tikz picture environment seems to measure in another reference system than the groupplot. I tried to just move the code snippet into the groupplot, but then there are no nodes drawn. Is there an easy way to fix this?

\end{groupplot}
\draw[ultra thin, draw=gray] (i-1 -| {rel axis cs:0,0}) node[fill=yellow,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\myfirsttick} -- (i-1);
\draw[ultra thin, draw=gray] (in-1 -| {rel axis cs:0,0}) node[fill=red,xshift=-7ex] 
{\pgfmathprintnumber[fixed,precision=3]\mysecondtick} -- (in-1);
\end{tikzpicture}

Edit 3:

If there is no such option to draw the node with correct coordinates outside the pgf-plot it would be awesome if someone points out a solution to draw a similar legend including at least the y-coordinate of the intersection point inside the plot.

Edit 4:

I have now managed to draw the desired coordinates outside the plot, thanks to this question: Coordinates of intersections But unfortunately the value of the coordinates now depends on the settings for the y-minimum in the axis environment. Is there a way to fix this?

The new code:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usetikzlibrary{intersections,plotmarks}
\usepackage{tikz}%Added by Arne Hensel
\usetikzlibrary{shapes, calc, shapes, arrows}%Added by Arne Hensel
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots,fillbetween}
\pgfplotsset{compat=1.13}
\pgfplotsset{width=7cm}
\usetikzlibrary{positioning,plotmarks,pgfplots.colormaps,external,3d,calc,shapes,arrows,patterns,decorations,decorations.pathmorphing,decorations.pathreplacing}
%Define the show intersection command to show the intersection points between graphs:
\newcommand*{\ShowIntersection}[2]{
\fill 
    [name intersections={of=#1 and #2, name=i, total=\t}] 
    [black, opacity=1, every node/.style={above left, black, opacity=1}] 
    \foreach \s in {1,...,\t}{(i-\s) circle (2pt)
        %node [above right] { \s}
        };
}
%
\makeatletter
\newcommand\transformxdimension[1]{
    \pgfmathparse{((#1/\pgfplots@x@veclength)+\pgfplots@data@scale@trafo@SHIFT@x)/10^\pgfplots@data@scale@trafo@EXPONENT@x}
}
\newcommand\transformydimension[1]{
    \pgfmathparse{((#1/\pgfplots@y@veclength)+\pgfplots@data@scale@trafo@SHIFT@y)/10^\pgfplots@data@scale@trafo@EXPONENT@y}
}
\makeatother
%
\begin{document}
    \begin{tikzpicture}
    \def\verticalbar{385}
        \begin{groupplot}[
                        group style={
                            group size=1 by 1
                            ,horizontal sep=2cm
                            ,vertical sep=3cm
                            }
                        ,height=8cm
                        ,width=10cm
                        ,/tikz/font=\small
                        ]
        \nextgroupplot[%legend pos=north west
                ,xmin=0
                ,xmax=1000
                ,ymin=15
                ,ymax=25
                ,clip=false
                ]
        \addplot+[raw gnuplot
            , name path global=p1
            , mark=none
            , dashed
        ] gnuplot {%set log y;
            f(x)=0.005*(x-400)+20;
            plot [x=0:1000] f(x);
            };
        \addplot+[raw gnuplot
            , name path global=p2
            , mark=none
            , dashed
        ] gnuplot {%set log y;
            f(x)=-0.005*(x-400)+22;
            plot [x=0:1000] f(x);
            };
        \addplot+[raw gnuplot
            ,name path global=p3
            , black
            , mark=none
        ] gnuplot {%set log y;
            f(x)=3*atan(0.1*(x-400))+20;
            plot [x=0:1000] f(x);
            };
        %Draw the vertical bar
        \draw [name path global=bar,black] (\verticalbar,0) -- (\verticalbar,25);
        %Fill between the different line-segments
        \addplot[black
                        , area legend,pattern=north west lines
                        , pattern color=black
                        ] fill between[of=p1 and p3
                                    , soft clip={domain=0:\verticalbar}
        ];
        \addplot[black
                    ,area legend,pattern=north east lines
                    ,pattern color=black] fill between[of=p2 and p3
                                            , soft clip={domain=\verticalbar:1000}
            ];
%Show the two intersection points of the linear regression and the bar
        \ShowIntersection{p1}{bar}
        \ShowIntersection{p2}{bar}
%Draw a horizontal line from the intersection point to the y-axis
\draw[dashed,name intersections={of=p2 and bar, by={A}}] (axis cs:0,0)|-(intersection-1);
\coordinate [] (A) at (A);
\draw let \p1=(A) in (0,\y1) node [anchor=east, fill=white, fill opacity=0.8,text opacity=1,xshift=0ex
                ]
    {
        \pgfgetlastxy{\macrox}{\macroy}
        %\transformxdimension{\macrox}
        %\pgfmathprintnumber{\pgfmathresult},%
        \transformydimension{\macroy}%
        \pgfmathprintnumber{\pgfmathresult} 
    }
;   
\draw[dashed,name intersections={of=p1 and bar, by={B}}] (axis cs:0,0)|-(intersection-1);
\coordinate [] (B) at (B);
\draw let \p1=(B) in (0,\y1) node [anchor=east, fill=white, fill opacity=0.8,text opacity=1,xshift=-4ex
                ]
    {
        \pgfgetlastxy{\macrox}{\macroy}
        %\transformxdimension{\macrox}
        %\pgfmathprintnumber{\pgfmathresult},%
        \transformydimension{\macroy}%
        \pgfmathprintnumber{\pgfmathresult}
    }
;   
        \end{groupplot}
    \end{tikzpicture}
\end{document}

with full y-axis

with partial y-axis, minimum set to 15

Any help is appreciated! Thanks!

closed as unclear what you're asking by Stefan Pinnow, Bobyandbob, TeXnician, Mensch, Troy Apr 15 '18 at 18:26

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Can you try using \pgfplotsset{compat=1.12} in your preamble to see if that fixes the problem? If it doesn't, it would be good if you could reduce your code down to the essentials needed to reproduce the problem: at the moment, there's a lot of stuff in there that doesn't seem to be related to the problem, which makes it harder for others to come up with a solution. – Jake May 30 '16 at 7:16
  • I am using version 1.13 and updated that part of the code, deleted all .aux files and recompiled several times, but unfortunately the problem still remains. Same with 1.12... – Arne H. May 30 '16 at 11:38
  • Maybe there is a solution with the upcoming PGFPlots v1.16, but unfortunately the points.dat is no longer available ... – Stefan Pinnow Apr 6 '18 at 18:53

Browse other questions tagged or ask your own question.