14

Consider the following code where I detect the crossing of a function to a given threshold. I am plotting the line from the intersection to the x-axis, and storing the intersection in \p1

I would like to add a second axis environment identical to the first one with only an additional tick at \x1

\documentclass{article}

\usepackage{pgfplots,tikz}
\usetikzlibrary{intersections,calc}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    clip=true,
    axis x line=bottom,
    axis y line=left,
    grid = major,
        grid style={dashed},
    xmin=1,
    xmax=64,
    samples =32,
    ymax = 1.6,
    ymin  = -0.2,
    xlabel={\emph{sample number}},
    xlabel style={at={(1,-0.1)}, anchor=south},
    legend cell align=left,
    legend pos=outer north east,
  ]
\addplot[name path global=one,blue,mark=+,domain=1:64] {exp(-log10(2)/(8^2/4)*(\x-32)^2)};
\addplot[name path global=two,red,domain=1:64] {0.5};
\path [name intersections={of=one and two, name=i}];
\path let \p1=($(i-1)$) in (\x1,\y1);
\draw[dashed] (i-1) -- ($(axis cs:0,-0.2)!(i-1)!(axis cs:64,-.2)$);

\legend{Sampled signal,Threshold}
\end{axis}

\begin{axis}[
    clip=true,
    axis x line=bottom,
    axis y line=left,
    xmin=1,
    xmax=64,
    samples =32,
    ymax = 1.6,
    ymin  = -0.2,
    xtick=\empty,
    ytick=\empty,
    extra x ticks={\x1},
    extra x tick labels={$t_{step}$},
  ]
\end{axis}
\end{tikzpicture} 

\end{document}

My attempt to use \x1 directly in the axis environment is failing.

enter image description here

11
  • 2
    The content of \x1 is only available within the context of the let command, so you'll need to store it in a global macro to access it later on. However, I doubt that that will be of much use, since \x1 is in "paper units", not "data units", so you can't simply feed it to extra x tick. Do you actually want a second axis (i.e. are you going to add plots to that axis), or do you simply want to label the x position of the intersection?
    – Jake
    Aug 22, 2013 at 14:21
  • @Jake no I just want to add an extra tick to the axis at the given position \x1. But I would like it to have the same style than the axis. I figure adding an other axis would be the simplest solution. Is there no way to cast \x1 into "data units"?
    – vrleboss
    Aug 22, 2013 at 14:49
  • @vrleboss Why don't you just solve exp(-log10(2)/(8^2/4)*(\x-32)^2) == 0.5 by hand? It might be not portable, but sometimes you have to lower your sights relating to automation. Aug 22, 2013 at 20:59
  • @HenriMenke unfortunately I will add random noise to the curve after. I need something automated.
    – vrleboss
    Aug 23, 2013 at 8:04
  • 1
    I don't know if this helps but I did something similar along the lines of tex.stackexchange.com/questions/88386/…
    – percusse
    Aug 25, 2013 at 22:38

2 Answers 2

7
+50

This solves the problem but using two axis environments.

enter image description here

Or if you want the number value of the tick just comment the extra x tick labels={$t_{step}$}, line.

enter image description here

Code

\documentclass{article}

\usepackage{pgfplots,tikz}
\pgfplotsset{compat=1.8}
\pgfplotsset{every axis/.append style={font=\small}}
\usetikzlibrary{intersections,calc}

\makeatletter
\def\markxof#1{
    \pgf@process{#1}
    \pgfmathparse{\pgf@x/\pgfplotsunitxlength+\pgfplots@data@scale@trafo@SHIFT@x)/10^\pgfplots@data@scale@trafo@EXPONENT@x}
}
\makeatother

\pgfplotsset{mystyle/.style={%
    clip=true,
    axis x line=bottom,
    axis y line=left,
    xmin=1, xmax=64,
    samples =32,
    ymax = 1.6, ymin  = -0.2}
}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[
        mystyle,
        grid = major,
        grid style={dashed},
        xlabel={\emph{sample number}},
        xlabel style={at={(1,-0.2)}, anchor=south},
        legend cell align=left,
        legend pos=outer north east
    ]
        \addplot[name path global=one,blue,mark=+,domain=1:64] {exp(-log10(2)/(8^2/4)*(\x-32)^2)};
        \addplot[name path global=two,red,domain=1:64] {0.5};
        \path [name intersections={of=one and two, name=i}];
        \pgfplotsextra{
            \path (i-1) \pgfextra{\markxof{i-1}\xdef\mytick{\pgfmathresult}};
        }
        \path let \p1=($(i-1)$) in (\x1,\y1);
        \draw[dashed] (i-1) -- ($(axis cs:0,-0.2)!(i-1)!(axis cs:64,-.2)$);
        \legend{Sampled signal,Threshold}
    \end{axis}

    \begin{axis}[
        mystyle,
        xtick=\empty, ytick=\empty,
        extra x ticks={\mytick},
        extra x tick labels={$t_{step}$},
        extra x tick style={
            xticklabel style={yshift=-10}
        }
    ]
    \end{axis}
\end{tikzpicture} 

\end{document}
1
  • Very nice! I think a way using only one axis environment would be to store the curves in global path without plotting them. Finding the intersections of the paths and saving it in mytick. Then define the axis env. Then plot the global paths.
    – vrleboss
    Aug 30, 2013 at 11:54
9

You can achieve a similar result as desired by placing a node [below] the x-intercept based on the computed intersection:

enter image description here

The above version does not have the x tick mark at the x-intercept as I think it works better. However, if uncomment the \draw in the pgfonlayer environment you obtain the tick:

enter image description here

Code:

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc,intersections}

\pgfdeclarelayer{foreground layer} 
\pgfsetlayers{main,foreground layer}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    clip=true,
    axis x line=bottom,
    axis y line=left,
    grid = major,
    grid style={dashed},
    xmin=1,
    xmax=64,
    samples =32,
    ymax = 1.6,
    ymin  = -0.2,
    xlabel={\emph{sample number}},
    xlabel style={at={(1,-0.1)}, anchor=south},
    legend cell align=left,
    legend pos=outer north east,
  ]
\addplot[name path global=one,blue,mark=+,domain=1:64] {exp(-log10(2)/(8^2/4)*(\x-32)^2)};
\addplot[name path global=two,red,domain=1:64] {0.5};
\path [name intersections={of=one and two, name=i}];
\path let \p1=($(i-1)$) in (\x1,\y1);

\coordinate (XIntercept) at ($(axis cs:0,-0.2)!(i-1)!(axis cs:64,-0.2)$);
\draw[dashed] (i-1) -- (XIntercept);


\begin{pgfonlayer}{foreground layer} 
    %\draw [gray,very thin] (XIntercept) -- ++(0,-2.25pt);
    \node [below, rotate=90, anchor=east,] at (XIntercept) {$t_{step}$};
\end{pgfonlayer}

\legend{Sampled signal,Threshold}
\end{axis}
\end{tikzpicture}
\end{document}
1
  • This is a valid answer but not the one I am looking for. I am looking for a way to modify the axis based on my plot. I had the node option also but wasn't satisfied with it.
    – vrleboss
    Aug 29, 2013 at 14:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .