难以绘制正确的坐标

难以绘制正确的坐标

难以绘制正确的坐标

我使用 pgfplots 绘制一组数据点,用 gnuplot 拟合它们,然后找到线性拟合和垂直条之间的交点。现在我想从交点到 y 轴画一条水平线。画线没有问题,但显示的 y 坐标是错误的。我发现当我改变图的大小时 y 值会发生变化。这让我觉得我可能在坐标转换方面做错了什么。所以我的问题是:

如何提取并绘制与绘图尺寸无关的交叉点坐标?

换句话说,有没有办法存储坐标并对其进行转换,以便它们可以在 tikz 图片内但在 pgf 提供的 groupplot 环境之外使用?

第一个地块高度为 11 厘米

同一地块,高度 7 厘米

这是我的 MWE:(您可以在以下位置找到文件 points.dat: 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}

编辑:

我将 MWE 简化为真正的 MWE,但问题仍然存在:

\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}

产生的输出:

代码减少、版本更新后坐标仍然错误

编辑2

我可能已经发现了问题,但我不知道如何解决它。在 groupplot 结束后插入生成水平线并在 y 轴左侧绘制具有 y 值的节点的代码。它仍然是 tikz 图片的一部分,但 tikz 图片环境似乎在 groupplot 以外的另一个参考系统中进行测量。我尝试将代码片段移动到 groupplot 中,但没有绘制任何节点。有没有简单的方法可以解决这个问题?

\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}

编辑3:

如果没有这样的选项来在 pgf 图外绘制具有正确坐标的节点,那么如果有人指出一种解决方案来绘制类似的图例(至少包括图内交叉点的 y 坐标),那就太棒了。

编辑4:

由于这个问题,我现在已经成功地在图外绘制了所需的坐标:交叉口坐标 但不幸的是,坐标值现在取决于轴环境中 y 最小值的设置。有办法解决这个问题吗?

新代码:

\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}

带完整 y 轴

带部分 y 轴,最小设置为 15

任何帮助都非常感谢!谢谢!

相关内容