在 PGFplot 中对齐固定节点

在 PGFplot 中对齐固定节点

我正在处理生成的图matlab2tikz,并且我有几条彼此接近的图线。标记它们很困难,但我相信一个好看的解决方案可能是列出标签,并绘制垂直线到适当的图。

考虑以下 MWE:

\documentclass{standalone}
\usepackage{tikz, pgfplots}
\begin{document}
\begin{tikzpicture}[scale = 3.5]
    \begin{axis}[xmin=0,xmax=3,ymin=0,ymax=5]
        \addplot[domain=0:3,solid]{(x-4)^2}    node[pos=0.8,pin=-180:{Plot 1}] {} ;
        \addplot[domain=0:3,solid]{(x-3.5)^2}  node[pos=0.8,pin=-180:{Plot 2}] {} ;
        \addplot[domain=0:3,solid]{(x-3)^2}    node[pos=0.8,pin=-180:{Plot 3}] {} ;
    \end{axis}
\end{tikzpicture}
\end{document}

产生

在此处输入图片描述

鉴于我不知道addplot图表会出现在哪里(即在x = 3或周围x = 300),有没有办法将标签/节点以相等的高度间距对齐,并让引脚延伸直到到达图表?

答案1

混合 TikZ 和pgfplots可能会变得棘手。scope显然直接执行给定的选项。

但是,下面这个代码没有使用pin/pos组合。我希望至少输出是你想要的。(实际上,你可以用处理程序覆盖样式at的一部分。)every name plot node/.append style

我愿意接受建议。

命名空间中还存在一些键name plot

relative( relative x/ relative y) 可打开rel axis cs“使用完整轴向量作为单位。这意味着 'x = 0' 表示 x 轴下限范围内的点,而 'x = 1' 表示 x 轴上限范围内的点 […]。”

我建议选择relative [x|y]节点的放置方式(正如你所说,你不知道是否X大约是 3 或 300,这可能也适用于,除非您指定xmin等等)。
您可以混合使用绝对坐标和相对坐标。最后一个例子使用绝对价值,但相对X值。

钥匙backwards从最高处到最低处找到交点价值。

number将使用第 个交点(默认值:)1

anchor可用于校正边缘(如果anchor节点的键既不是west也不是,centereast线不会完全水平。anchor键可用于解决这个问题。.必须包含前面的内容。


一个可能的改进是,它可以\namePlot自行找到最近的点/交叉点(可以选择只向左或向右查看)。

代码

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usetikzlibrary{intersections}
\makeatletter
\newif\ifqrr@nameplot@relative@x
\newif\ifqrr@nameplot@relative@y
\newif\ifqrr@nameplot@backwards
\tikzset{
  every name plot node/.style={
    anchor=east,
    name=\pgfkeysvalueof{/name plot/name}
  },
  name plot/.code={\pgfkeys{/name plot/.cd,#1}}}
\pgfqkeys{/name plot}{
  at x/.initial=0,
  at y/.initial=0,
  at/.style args={#1,#2}{/name plot/at x={#1},/name plot/at y={#2}},
  path name/.initial=,
  name/.initial=,
  anchor/.initial=,
  number/.initial=1,
  relative x/.is if=qrr@nameplot@relative@x,
  relative y/.is if=qrr@nameplot@relative@y,
  relative/.style={
    /name plot/relative x=#1,
    /name plot/relative y=#1
  },
  relative/.default=true,
  backwards/.is if=qrr@nameplot@backwards
}
\newcommand*{\namePlot}[2][]{
  \scope[/name plot/.cd,#1]
    \ifqrr@nameplot@relative@y
      \path (rel axis cs:0,\pgfkeysvalueof{/name plot/at y}) coordinate (qrr@name plot@a)
            (rel axis cs:1,\pgfkeysvalueof{/name plot/at y}) coordinate (qrr@name plot@b);
    \else
      \path (axis cs:\pgfkeysvalueof{/pgfplots/xmin},\pgfkeysvalueof{/name plot/at y}) coordinate (qrr@name plot@a)
            (axis cs:\pgfkeysvalueof{/pgfplots/xmax},\pgfkeysvalueof{/name plot/at y}) coordinate (qrr@name plot@b);
    \fi
    \ifqrr@nameplot@backwards
      \path[name path=qrr@nameplot@horizontal line] (qrr@name plot@b) -- (qrr@name plot@a);
    \else
      \path[name path=qrr@nameplot@horizontal line] (qrr@name plot@a) -- (qrr@name plot@b);
    \fi
    \path[
      name intersections={%
        of=\pgfkeysvalueof{/name plot/path name} and qrr@nameplot@horizontal line,
        name=qrr@nameplot@intersections,
        sort by=qrr@nameplot@horizontal line}
    ];
    \node[
      at={(perpendicular cs: horizontal line through={(qrr@nameplot@intersections-\pgfkeysvalueof{/name plot/number})},
                            vertical line through={(\ifqrr@nameplot@relative@x rel \fi axis cs:\pgfkeysvalueof{/name plot/at x},0)})},
      every name plot node/.try,
      alias=qrr@nameplot@node
    ] {#2} (qrr@nameplot@node\pgfkeysvalueof{/name plot/anchor}) edge[every name plot edge/.try] (qrr@nameplot@intersections-\pgfkeysvalueof{/name plot/number});
  \endscope
}
\makeatother
\tikzset{every name plot edge/.append style={help lines, shorten >=2pt, -latex}}
\begin{document}
\begin{tikzpicture}[
  scale = 3.5,
  /name plot/at x=.7
  ]
    \begin{axis}[xmin=0,xmax=3,ymin=0,ymax=5]
        \addplot[domain=0:3, solid, name path global=plot 1]{(x-4)^2}  ;
        \addplot[domain=0:3, solid, name path global=plot 2]{(x-3.5)^2};
        \addplot[domain=0:3, solid, name path global=plot 3]{(x-3)^2}  ;
        \namePlot[path name=plot 1, at y=2, name=p1] {Plot 1}
        \namePlot[path name=plot 2, at y=3, name=p2] {Plot 2}
        \namePlot[path name=plot 3, at y=4, name=p3] {Plot 3}
        \path [<->] (p1) edge (p2) (p2) edge (p3);% just for fun
    \end{axis}
\end{tikzpicture}
\begin{tikzpicture}[
  scale = 3.5,
  name plot={
    at x=.15,
    relative x},
  every name plot edge/.append style={preaction={draw=white,ultra thick,-}},
  every name plot node/.append style={anchor=west}
  ]
    \begin{axis}[xmin=-1,xmax=10,ymin=-1.5,ymax=1.5]
        \addplot[domain=-1:10, solid, smooth, name path global=sinus]{sin(x/pi*180)}  ;
        \tikzset{/name plot/path name=sinus}
        \namePlot[at y=-.99 ] {$y=-1$}
        \namePlot[at y=-.5, number=2, backwards] {$y=-0.5$}
        \namePlot[at y=0] {$y=0$}
        \namePlot[at y=0, number=2, /tikz/every name plot node/.append style={text opacity=0}] {$y=0$}
    \end{axis}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

在此处输入图片描述

相关内容