标记能级跃迁 pgfplots/Tikz

标记能级跃迁 pgfplots/Tikz

我想建立一个能源转换图(与能级转变 pgfplots/Tikz[下面的代码])。但是,我想在其上添加标签。

\documentclass{standalone}
\usepackage{pgfplots,pgfplotstable}
\usepgflibrary{plotmarks}
\usetikzlibrary{calc}

%%% Label to insert
\pgfplotstableread{
    one two three 
    R   R     R 
    C1   nan   C2
    TS1   TS2   TS3
    C3    C4    C5 
    P1   P2   P3 
}\labeltable

%%% Start of the code for energy level
%%% Example data file
\pgfplotstableread{
one two three 
0.0   0.0     0.0
-64.2   nan  -10
150.4   155.8  47
54.4    63.9   -156
113.9   172.4  -56
}\datatable

\begin{document}
\begin{tikzpicture}[x=2cm, y=0.2mm]
\begin{axis}[
%only marks,
every axis plot post/.style={mark=-,ultra thick,mark size=4mm}, 
ylabel=Energy (kJ.mol$^{-1}$), 
xtick=\empty, 
legend pos=outer north east,
xmin=-0.5,
xmax=5,
ymin=-200,
%ymax=350,
axis lines=left,  
xtick=\empty,
hide x axis,
legend entries={\small one, \small two,\small three},
legend style={draw=none},
title=Insert better title here,
% Extra options added
anchor=origin,
disabledatascaling,
only marks,
x=2cm, y=0.2mm,] 
\pgfplotstablegetcolsof{\datatable}
\pgfmathsetmacro\numberofycols{\pgfplotsretval-1}
\pgfplotsinvokeforeach {0,...,\numberofycols}{  
\addplot table[x expr=\coordindex, y index=#1] {\datatable};
}
\end{axis}

% Extra code added
\foreach \case in {one,two,three} {
    \xdef\previndex{0}
    \xdef\prevlevel{0}
        \pgfplotstableforeachcolumnelement{\case}\of\datatable\as\level{%
        \pgfmathfloatparsenumber{\level}
        \pgfmathfloatgetflagstomacro\pgfmathresult\flags
        \ifnum\flags=3\relax\else
        \draw[densely dotted,thick] ($(\previndex,\prevlevel)+(0.2,0)$) -- ($(\pgfplotstablerow,\level)+(-0.2,0)$);

        \xdef\previndex{\pgfplotstablerow}
        \xdef\prevlevel{\level}
        \fi
    }
}

\end{tikzpicture}
\end{document}

确实,我想在能量级上添加能量值(来自表 \datatable)和级别标签(来自表 \labeltable),如下图所示:

标签能量图例子

提前谢谢了

答案1

如果合并两个表是一种选择,您可以这样做。由于某些标签的位置不同,因此使用 if-else 子句进行了一些特殊处理。因此,这不是一个非常灵活的解决方案,尽管它可以完成当前特定情况的工作。

在此处输入图片描述

\documentclass[border=5mm]{standalone}
\usepackage{pgfplotstable}
\usetikzlibrary{calc}


%%% Start of the code for energy level
%%% Example data file
\pgfplotstableread{
one two three oneL twoL threeL
0.0   0.0     0.0     R   R     R 
-64.2   nan  -10     C1   nan   C2
150.4   155.8  47     TS1   TS2   TS3
54.4    63.9   -156     C3    C4    C5
113.9   172.4  -56     P1   P2   P3 
}\datatable

\begin{document}
\begin{tikzpicture}[x=2cm, y=0.2mm]
\begin{axis}[
%only marks,
every axis plot post/.style={mark=-,ultra thick,mark size=4mm}, 
ylabel=Energy (kJ.mol$^{-1}$), 
xtick=\empty, 
legend pos=outer north east,
xmin=-0.5,
xmax=5,
ymin=-200,
ymax=220,
axis lines=left,  
xtick=\empty,
hide x axis,
legend entries={\small one, \small two,\small three},
legend style={draw=none},
title=Insert better title here,
% Extra options added
anchor=origin,
disabledatascaling,
only marks,
x=2cm, y=0.2mm
] 
\pgfplotstablegetcolsof{\datatable}
\pgfmathsetmacro\numberofycols{int(\pgfplotsretval/2)-1}
\pgfplotsinvokeforeach {0,...,\numberofycols}{  

\addplot +[
  nodes near coords,
  node near coords style={
     anchor={int((#1==1)&&(\coordindex==1||\coordindex==2)?270:90)},
     inner sep=1mm
     }
  ] table[x expr=\coordindex, y index=#1] {\datatable};

\pgfmathtruncatemacro\METAIND{#1+3}  
\addplot [
  draw=none,
  no markers,
  forget plot,
  point meta=explicit symbolic,
  nodes near coords,
  node near coords style={
      anchor={int((#1==0)&&(\coordindex==2||\coordindex==3)?90:270)},
      yshift={(%
           % if third or fourth point in first column
           #1==0&&(\coordindex==2||\coordindex==3)?%
           % shift labels 12 pt down
           -12pt:%
           % else if second or third point in second column
           (#1==1&&(\coordindex==1||\coordindex==2)?%
           % shift labels 12pt up
           12pt:%
           % in all other cases, no shifting
           0)%
           )}
      }
  ] table[x expr=\coordindex, y index=#1, meta index=\METAIND] {\datatable};  
}
\end{axis}

% Extra code added
\foreach \case in {one,two,three} {
    \xdef\previndex{0}
    \xdef\prevlevel{0}
        \pgfplotstableforeachcolumnelement{\case}\of\datatable\as\level{%
        \pgfmathfloatparsenumber{\level}
        \pgfmathfloatgetflagstomacro\pgfmathresult\flags
        \ifnum\flags=3\relax\else
        \draw[densely dotted,thick] ($(\previndex,\prevlevel)+(0.2,0)$) -- ($(\pgfplotstablerow,\level)+(-0.2,0)$);

        \xdef\previndex{\pgfplotstablerow}
        \xdef\prevlevel{\level}
        \fi
    }
}

\end{tikzpicture}
\end{document}

相关内容