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

vrleboss
  • 941
  • 9
  • 27
  • 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 '13 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 '13 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. – Henri Menke Aug 22 '13 at 20:59
  • @HenriMenke unfortunately I will add random noise to the curve after. I need something automated. – vrleboss Aug 23 '13 at 08:04
  • It would be helpful if you converted your code into a fully compilable MWE including \documentclass and the appropriate packages so that a simple cut and paste is enough to get started. – Peter Grill Aug 25 '13 at 19:59
  • @PeterGrill done. To obtain the output shown comment out the second axis definition. – vrleboss Aug 25 '13 at 22:18
  • 1
    I don't know if this helps but I did something similar along the lines of http://tex.stackexchange.com/questions/88386/plot-functions-and-their-point-of-intersection – percusse Aug 25 '13 at 22:38
  • @percusse unfortunately, your solution does not draw the tick. And everything is done manually. I am looking for a way to somehow have an extra x ticks={\x1} after the end of the axis. It does seem complicated but that's why I added the reward :) – vrleboss Aug 25 '13 at 23:09
  • Actually the most helpfull answer I found during my search was this one: http://tex.stackexchange.com/questions/118436/adding-extra-ticks-inside-the-axis-environment. Red reply to it's own post gave me the idea for the second axis environment, but I got stuck there as well. – vrleboss Aug 25 '13 at 23:16
  • It doesn't draw the tick but does the same thing. The question was not to draw the tick but get the position so you can add the tick. – percusse Aug 25 '13 at 23:27
  • @percusse: I don't understand your last reply. – vrleboss Aug 26 '13 at 00:11

2 Answers2

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}

Peter Grill
  • 223,288
  • 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 '13 at 14:49
7

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}
Red
  • 10,181
  • 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 '13 at 11:54