4

I'm trying to plot the following graph using pgfplots:

plot

This plot was generated with matlab.

I can easily plot the two curves with pgfplots but I have no clue how to add the vertical line with the 0.3dB marker on it. Maybe there is a possibility to extract the (interpolated) values for x (SNR) of both plots at y=10^-1. It should be mentioned that only the y values for 20, 22, 24, 26, 28, 30 and 32 dB are available.

This is my the current TeX Code (the plot data does not exactly fit to the matlab pic, but the idea is the same):

\documentclass[a4paper, ngerman]{scrreprt}
\usepackage{color}
% predefined colors
\definecolor{color1}{rgb}{0.44706,0.44706,0.44706}%
\definecolor{color2}{rgb}{0.09412,0.34902,0.66275}%
\definecolor{color3}{rgb}{0.92941,0.17647,0.18039}%
\definecolor{color4}{rgb}{0.00000,0.54902,0.27843}%
% include pgfplots 
\usepackage{pgfplots}
\usepackage{pgfplotstable}
% custom settings
\pgfplotsset{compat=1.3}
\pgfplotsset{every axis/.append style={line width=1pt}}       % line widths
\pgfplotsset{                                                 % customized size (x1.3)
  mysize/.style={
  /pgfplots/width=312pt,
  /pgfplots/height=269pt,
  /pgfplots/max space between ticks=35}
}
\pgfplotsset{                                                 % fer plot config
  ferplotcfg/.style={
    /pgfplots/xmin  = 20,
    /pgfplots/xmax  = 32,
    /pgfplots/ymin  = 10e-3, 
    /pgfplots/ymax  = 10e-1,
    /pgfplots/grid  = both,
    minor grid style = {dashed},
    major grid style = {dashed}}
}
\pgfplotsset{                                                 % reference curve cfg
  line_ref/.style={
    color1,
    /tikz/smooth,
    /tikz/mark=none,
    /tikz/style={dashed}}
}
\pgfplotsset{                                                 % reference curve cfg
  line_1/.style={
    color2,
    /tikz/smooth,
    /tikz/mark=o}
}

\begin{document}

\centering
\begin{tikzpicture}
  \begin{axis} [
    title = FER Performance,
    legend entries = {Reference, Fixed Point},
    xlabel = {SNR (dB)}, ylabel = {FER},
    ferplotcfg, mysize, ymode = log,
    ]
    \addplot[line_ref] table[x=snr, y=reference, col sep=comma, row sep=crcr] {
      snr,matlab_full_sim_fxp,reference\\
      20,0.93682,0.92946\\
      22,0.76335,0.73643\\
      24,0.39312,0.3622\\
      26,0.11584,0.10718\\
      28,0.036743,0.029785\\
      30,0.012695,0.010864\\
      32,0.0064697,0.0039063\\}; 
    \addplot[line_1] table[x=snr, y=matlab_full_sim_fxp, col sep=comma, row sep=crcr] {
      snr,matlab_full_sim_fxp,reference\\
      20,0.93682,0.92946\\
      22,0.76335,0.73643\\
      24,0.39312,0.3622\\
      26,0.11584,0.10718\\
      28,0.036743,0.029785\\
      30,0.012695,0.010864\\
      32,0.0064697,0.0039063\\}; 
  \end{axis}
\end{tikzpicture}
\end{document}
Simon
  • 43
  • Do you mean automatically finding the intersection or just putting an arrow with eyeballing? – percusse Sep 18 '14 at 23:08
  • Yes, I would like to automatically find the intersection of both graphs with y=10^-1 and put a line in between these points. Putting the line if the intersections are known should not be that hard, I guess. – Simon Sep 18 '14 at 23:17
  • Yes that's easy. How about the distance in terms of 0.3 dB? Do you know that already? – percusse Sep 18 '14 at 23:31
  • This should also be calculated. – Simon Sep 19 '14 at 06:11

1 Answers1

3

One way to accomplish this is to combine the techniques from pgfplots: Placing node on a specific x-position and Converting unit to coordinate works for x-coordinate, but not for y-coordinate for first placing coordinates at the specified y position and then calculating the difference:

\documentclass{standalone}
% include pgfplots 
\usepackage{pgfplots}
\usetikzlibrary{intersections, calc}
% custom settings
\pgfplotsset{compat=newest}
\pgfplotsset{                                                 % customized size (x1.3)
  mysize/.style={
  /pgfplots/width=312pt,
  /pgfplots/height=269pt,
  /pgfplots/max space between ticks=35}
}
\pgfplotsset{                                                 % fer plot config
  ferplotcfg/.style={
    /pgfplots/xmin  = 20,
    /pgfplots/xmax  = 32,
    /pgfplots/ymin  = 10e-3, 
    /pgfplots/ymax  = 10e-1,
    /pgfplots/grid  = both,
    %minor grid style = {dashed},
    %major grid style = {dashed}
    }
}
\pgfplotsset{                                                 % reference curve cfg
  line_ref/.style={
    color1,
    /tikz/smooth,
    /tikz/mark=none,
    /tikz/style={dashed}}
}
\pgfplotsset{                                                 % reference curve cfg
  line_1/.style={
    color2,
    /tikz/smooth,
    /tikz/mark=o}
}

\makeatletter
\def\parsenode[#1]#2\pgf@nil{%
    \tikzset{label node/.style={#1}}
    \def\nodetext{#2}
}

\tikzset{
    add node at y/.style 2 args={
        name path global=plot line,
        /pgfplots/execute at end plot visualization/.append={
                \begingroup
                \@ifnextchar[{\parsenode}{\parsenode[]}#2\pgf@nil
            \path [name path global = position line #1]
                ({axis cs:0,#1}-|{rel axis cs:0,0}) --
                ({axis cs:0,#1}-|{rel axis cs:1,1});
            \path [
                name intersections={
                    of={plot line and position line #1},
                    name=intersection
                },
            ] (intersection-1)
            node [label node] {\nodetext};
            \endgroup
        }
    }
}


\begin{document}

\centering
\begin{tikzpicture}
  \begin{axis} [
    ferplotcfg, mysize, ymode = log,
    ]
    \addplot[black, add node at y={0.1}{[coordinate, name=pointA]}] table[x=snr, y=reference, col sep=comma, row sep=crcr] {
      snr,matlab_full_sim_fxp,reference\\
      20,0.93682,0.92946\\
      22,0.76335,0.73643\\
      24,0.39312,0.3622\\
      26,0.11584,0.10718\\
      28,0.036743,0.029785\\
      30,0.012695,0.010864\\
      32,0.0064697,0.0039063\\}; 
    \addplot[blue, add node at y={0.1}{[coordinate, name=pointB]}] table[x=snr, y=matlab_full_sim_fxp, col sep=comma, row sep=crcr] {
      snr,matlab_full_sim_fxp,reference\\
      20,0.93682,0.92946\\
      22,0.76335,0.73643\\
      24,0.39312,0.3622\\
      26,0.11584,0.10718\\
      28,0.036743,0.029785\\
      30,0.012695,0.010864\\
      32,0.0064697,0.0039063\\};
      \draw let \p1=(pointA), \p2=(pointB) in (pointA) -- (pointB) node [pos=0, left] {%
        \pgfplotsconvertunittocoordinate{x}{\x1}%
        \pgfplotscoordmath{x}{datascaletrafo inverse to fixed}{\pgfmathresult}%
        \edef\valueA{\pgfmathresult}%
        \pgfplotsconvertunittocoordinate{x}{\x2}%
        \pgfplotscoordmath{x}{datascaletrafo inverse to fixed}{\pgfmathresult}%
        \pgfmathparse{\pgfmathresult - \valueA}%
        \pgfmathprintnumber{\pgfmathresult} dB
        };
  \end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • Thanks, this solves the problem. Anyway, do you have any idea why the horizontal line is not perfectly on the grid line of y=0.1 ? – Simon Sep 19 '14 at 09:46
  • 1
    @Simon: That's due to an artefact caused by an implementation detail of http://tex.stackexchange.com/questions/88404/pgfplots-placing-node-on-a-specific-x-position. I've edited my answer to provide an approach that positions the label at the precise y coordinate. – Jake Sep 19 '14 at 10:00