在 pgfplots 中添加带有箭头和标记的图

在 pgfplots 中添加带有箭头和标记的图

编辑(14/06):感谢土拨鼠的提示,并基于关于这个答案.我定义\markopts如下scatter/@pre marker code/.code

scatter/@pre marker code/.code={
  \pgfmathtruncatemacro{\lasttwomarks}{%
    or((\coordindex==(\numcoords-2)), (\coordindex==(\numcoords-1)))%
  }
  \ifnum\lasttwomarks=1
    \def\markopts{mark=none}
  \else
    \def\markopts{mark=*,mark size=1pt}
  \fi
  \ifnum\coordindex=0
     \def\markopts{mark=*,fill=white,mark size=2pt}
  \fi
  \expandafter\scope\expandafter[\markopts]
}
,scatter/@post marker code/.code={
  \endscope
}

... 隐藏了最后两个标记,我无需将其附加\draw到图中。我现在只需向箭头末端的数据添加两个“虚拟”坐标。参见这个要点

原始问题:

我想模仿这个图表:

显示带标记的箭头图的图表

到目前为止,我一直无法添加绘图,这些绘图以*第一个未填充的数据点的标记开始,其他数据点的填充标记以及指向大致正确方向的箭头末端。我知道这会将pgfplots给出的坐标\draw视为在 axis 环境中的预期,但我想知道我是否可以调整命令以便在那里使用它。

\documentclass[border=5mm,tikz]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\usetikzlibrary{arrows.meta}
\begin{document}
\tikz\draw[{Circle[fill=none]}-Stealth,thick] (0, 0) --
plot[smooth,mark=*] coordinates {(1, .24) (2, .42) (3, .54) (4, .59)} -- (5, .6);
% \begin{tikzpicture}[baseline]
%   \begin{axis}[xtick=\empty,xmin=-1,xmax=6,ymin=-1,ymax=1]
%     \addplot+ [yshift=2pt,red,smooth,mark=*] coordinates {(1, .24) (2, .42) (3, .54) (4, .59) (5, .6)};
%   \end{axis}
% \end{tikzpicture}
\end{document}

mwe 箭头图

编辑:

一些背景:

基本上,该图代表钢琴调音师在应用时的选择拉伸调音:低音弦通常较粗,具有更多的频谱成分。每个图都代表了 1923 年斯坦威钢琴上单个录音音符的泛音序列中突出的泛音。对齐的键盘和网格线(每八度 12 个音符 => xtick distance=12)表示泛音最接近哪个音符,y 轴显示以音分为单位的偏差。调音师选择的听觉折衷通常取决于不同钢琴中的共振泛音。我有不同钢琴的测量值,我想在这样的图表中表示出来。

所用的音符全都是(不同八度的)A。未填充的标记表示基音(图的第一个值),填充的标记表示突出的泛音,固定的标签始终指向相交的图。

与此同时,我写下了以下内容:

工作草案

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta,plotmarks,decorations.markings,intersections}
\tikzset{%
  every pin/.style={black,fill=white,rectangle,outer sep=1pt,inner sep=1pt, rounded corners=3pt,font=\tiny}%
  ,every mark/.append style={scale=.5}%
  ,n/.style={xshift=-1ex,yshift=1em,font=\bfseries}
}
\pgfplotsset{%
  width=16cm%
  ,height=7cm%
  ,scale only axis%
  ,compat=1.15%
  ,major grid style={dotted,thin,gray}
  ,tick label style={font=\small}
  ,tickwidth=0pt
  ,label style={font=\small}
  ,axis x line=bottom
  ,axis y line=left
}
\begin{document}
\begin{tikzpicture}[baseline,pin distance=4ex]
  \begin{axis}[%
    name=main plot
    ,clip=false
    ,xtick distance=12
    ,xticklabels={0, A0, A1, A2, A3, A4, A5, A6, A7},
    ,ylabel={Deviation (cents)}
    ,ytick={-25,-20,...,45}
    ,ymin=-34
    ,ymax=50
    ,xmin=-4
    ,xmax=90
    ,grid=major
    ,major grid style={black!50}
    ,axis y discontinuity=crunch
    ,enlargelimits=false
  ]
    % A0
    \draw[blue,{Circle[fill=none]}-Stealth,thick] (axis cs:-.55, -26) node[n](a0) {A0} --
    plot[smooth,mark=*] coordinates {
      (axis cs:12,-25) (axis cs:19,-23) (axis cs:24,-19.5) (axis cs:28,-14) (axis cs:31,-13)
      (axis cs:34,-7) (axis cs:36,-3) (axis cs:38,3) (axis cs:40,7) (axis cs:42,14) (axis cs:43,19)
      (axis cs:44,25) (axis cs:45,33)
    } -- (axis cs:45.5,39);
    % A1
    \draw[black,{Circle[fill=none]}-Stealth,thick] (axis cs:11.55, -6) node[n](a1) {A1} --
    plot[smooth,mark=*] coordinates {
      (axis cs:24, -5)   (axis cs:31, -3.5)   (axis cs:36, -3) (axis cs:40, -2) (axis cs:43, -1)
      (axis cs:46, 1)   (axis cs:48, 2)  (axis cs:50, 4) (axis cs:52, 6) (axis cs:54, 9) (axis cs:55, 11)
    } -- (axis cs:58, 18);
    % A2
    \draw[cyan,{Circle[fill=none]}-Stealth,thick] (axis cs:23.55, -2) node[n](a2) {A2} --
    plot[smooth,mark=*] coordinates {
      (axis cs:36, -1.4) (axis cs:43, -1) (axis cs:48, -1) (axis cs:52, -.8) (axis cs:55, -.6)
      (axis cs:58, 0) (axis cs:60, 1) (axis cs:62, 2.5) (axis cs:64, 4.5) (axis cs:66, 6.5) (axis cs:68, 9)
    } -- (axis cs:71, 14);
    % A3
    \draw[darkgray,{Circle[fill=none]}-Stealth,thick] (axis cs:35.55, -1.4) node[n](a3) {A3} --
    plot[smooth,mark=*] coordinates {
      (axis cs:48, -1) (axis cs:55, -.5) (axis cs:60, 1) (axis cs:64, 3) (axis cs:67, 5.2)
      (axis cs:70, 8.6) (axis cs:72, 11)
    } -- (axis cs:74.5, 17);
    % A4
    \draw[purple,{Circle[fill=none]}-Stealth,thick] (axis cs:47.55, 0) node[n](a4) {A4} --
    plot[smooth,mark=*] coordinates {
      (axis cs:60, .5) (axis cs:67, 5) (axis cs:72, 12) (axis cs:75, 18)
    } -- (axis cs:78, 26);
    % A5
    % .. controls (axis cs:66,3.6) and (axis cs:67,4.2) .. 
    \draw[orange,{Circle[fill=none]}-Stealth,thick] (axis cs:59.55,1.2) node[n](a5) {A5}
    to[out=10, in=210] (axis cs:72, 12) --
    plot[smooth,mark=*] coordinates {
      (axis cs:72, 12) (axis cs:79, 26) (axis cs:84, 39)
    } -- (axis cs:85.5, 46);
    % A6
    % how to include a marking at (84, 38)? this breaks the path for some reason: (axis cs:84, 38) circle(2pt) --
    % .. controls (axis cs:73,13) and (axis cs:77,20) ..
    \draw[teal,{Circle[fill=none]}-Stealth,thick] (axis cs:71.6, 11.55) node[n](a6) {A6}
    to[out=35, in=240] (axis cs:84, 39) to[out=60, in=250] (axis cs:87, 54);
    % A7
    % .. controls (axis cs:85,43) and (axis cs:86,45) ..
    \draw[gray,{Circle[fill=none]}-Stealth,thick] (axis cs:83.75, 38) node[n](a7) {A7}
    to[out=60, in=250] (axis cs:88, 58);
    \node [pin=320:$A0^8-A1^4$] at (36,-3)  {};
    \node [pin=85:$A1^6-A2^3$]       at (43, -1) {};
    \node [pin=below right:$A2^4-A3^2$] at (48, -1) {};
    \node [pin=below right:$A3^4-A4^2$] at (60, 1)  {};
    \node [pin=above left:$A4^4-A5^2$]  at (72, 12) {};
    \node [pin=below right:$A5^2-A6^1$] at (72, 12) {};
    \node [pin=below right:$A6^2-A7^1$] at (84, 38) {};
  \end{axis}
\end{tikzpicture}
\end{document}

注意:

  • 我对起点进行了一些丑陋的调整,以伪造圆形箭头的中心锚点(“基本点”确实应该位于网格上)
  • 我无法获得直线to[]plot[smooth]产生平滑的曲线,尤其是橙色路径
  • 我不知道如何在不破坏路径(箭头消失或跳转到奇怪的地方)*的情况下手动在 A6 路径中包含标记形状circle(参见注释),并且缩放其他标记意味着我不确定要硬编码哪个直径

forget plot我想知道如何覆盖或丢弃特定标记。可以用和来完成吗postaction

编辑:

根据@marmot 的要求,在文件中绘制数据:

\begin{filecontents*}{A0.txt}
0  -26
12 -25
19 -23
24 -19.5
28 -14
31 -13
34 -7
36 -3
38 3
40 7
42 14
43 19
44 25
45 33
45 38
\end{filecontents*}

\begin{filecontents*}{A1.txt}
12 -6
24 -5
31 -3.5
36 -3
40 -2
43 -1
46 1
48 2
50 4
52 6
54 9
55 11
58 18
\end{filecontents*}

\begin{filecontents*}{A2.txt}
24 -2
36 -1.4
43 -1
48 -1
52 -.8
55 -.6
58 0
60 1
62 2.5
64 4.5
66 6.5
68 9
71 14
\end{filecontents*}

\begin{filecontents*}{A3.txt}
36 -1.4
48 -1
55 -.5
60 1
64 3
67 5.2
70 8.6
72 11
74 16
\end{filecontents*}

\begin{filecontents*}{A4.txt}
48 0
60 .5
67 5
72 12
75 18
78 26
\end{filecontents*}

\begin{filecontents*}{A5.txt}
60 1.2
72 12
72 12
79 26
84 39
86 44
\end{filecontents*}

\begin{filecontents*}{A6.txt}
72 11.55
84 39
87 54
\end{filecontents*}

\begin{filecontents*}{A7.txt}
84 38
88 58
\end{filecontents*}

(我的数据仍需处理,因此这些值不完整且仅供参考)

答案1

这不是一个完整的答案,但可以想象会成为一个完整的答案。问题是我不知道填写或不填写标记的标准是什么。因此,这是每三个标记填写一次的东西,但一旦标准明确,就可以修改为您想要的。我之所以要求提供数据文件,是因为我希望你能指出应该填写哪些标记。然后可以使用此信息。

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}


\begin{filecontents*}{A0.txt}
0  -26
12 -25
19 -23
24 -19.5
28 -14
31 -13
34 -7
36 -3
38 3
40 7
42 14
43 19
44 25
45 33
45 38
\end{filecontents*}

\begin{filecontents*}{A1.txt}
12 -6
24 -5
31 -3.5
36 -3
40 -2
43 -1
46 1
48 2
50 4
52 6
54 9
55 11
58 18
\end{filecontents*}

\begin{filecontents*}{A2.txt}
24 -2
36 -1.4
43 -1
48 -1
52 -.8
55 -.6
58 0
60 1
62 2.5
64 4.5
66 6.5
68 9
71 14
\end{filecontents*}

\begin{filecontents*}{A3.txt}
36 -1.4
48 -1
55 -.5
60 1
64 3
67 5.2
70 8.6
72 11
74 16
\end{filecontents*}

\begin{filecontents*}{A4.txt}
48 0
60 .5
67 5
72 12
75 18
78 26
\end{filecontents*}

\begin{filecontents*}{A5.txt}
60 1.2
72 12
72 12
79 26
84 39
86 44
\end{filecontents*}

\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{arrows.meta,plotmarks,decorations.markings,intersections}
\tikzset{%
  every pin/.style={black,fill=white,rectangle,outer sep=1pt,inner sep=1pt, rounded corners=3pt,font=\tiny}%
  ,every mark/.append style={scale=.5}%
  ,n/.style={xshift=-1ex,yshift=1em,font=\bfseries}
}
\pgfplotsset{%
  width=16cm%
  ,height=7cm%
  ,scale only axis%
  ,compat=1.15%
  ,major grid style={dotted,thin,gray}
  ,tick label style={font=\small}
  ,tickwidth=0pt
  ,label style={font=\small}
  ,axis x line=bottom
  ,axis y line=left
}
\begin{document}
\begin{tikzpicture}[baseline,pin distance=4ex]
  \begin{axis}[%
    name=main plot
    ,clip=false
    ,xtick distance=12
    ,xticklabels={0, A0, A1, A2, A3, A4, A5, A6, A7},
    ,ylabel={Deviation (cents)}
    ,ytick={-25,-20,...,45}
    ,ymin=-34
    ,ymax=50
    ,xmin=-4
    ,xmax=90
    ,grid=major
    ,major grid style={black!50}
    ,axis y discontinuity=crunch
    ,enlargelimits=false,
    scatter/@pre marker code/.code={
       \pgfmathtruncatemacro{\itest}{mod(\coordindex,3)}
       \ifnum\itest=0
         \def\markopts{mark=*,fill=white,mark size=3pt}
       \else
         \def\markopts{mark=*}
       \fi  
       \expandafter\scope\expandafter[\markopts]
       },
       scatter/@post marker code/.code={
    \endscope
    },  
  ]
  \addplot[scatter,color=blue] table {A1.txt};
  \end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容