How can I draw dirac deltas with arrow heads with pgfplots

I would like to draw this in pgfplots:

I've tried this, but I can't figure out how to get the arrowheads.

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[ xlabel=$x$, ylabel=$y$, axis x line=center, axis y line = center,
xmin=-3.5, xmax=3.5, ymin=-1.5, ymax=1.5]
\end{axis}
\end{tikzpicture}

\end{document}


-

Just replace

\addplot+[ycomb,mark=triangle] plot coordinates {(-3,1) (3,-1)};


with

\draw[-latex,blue] (axis cs:3,0) -- (axis cs:3,1);
\draw[-latex,blue] (axis cs:-3,0) -- (axis cs:-3,1);


As you can read at page 187 of pgfplots manual you can access to the axis coordinates system by using axis cs and this allows you to put (I think) every TikZ code in your picture. If you need to draw only vertical lines (like dirac's deltas) you can use the \addplot command but dividing positive and negative deltas:

\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[ xlabel=$x$, ylabel=$y$, axis x line=center, axis y line = center, xmin=-3.5, xmax=3.5, ymin=-1.5, ymax=1.5]
\addplot+[ycomb,mark=triangle,mark options={rotate=180}] plot coordinates {(3,-1) (2,-0.5)};
\addplot+[ycomb,mark=triangle,mark options={rotate=0}] plot coordinates {(-3,1) (-2,0.5)};
\draw[->] (axis cs:3,0) -- (axis cs:3,1);
\end{axis}
\end{tikzpicture}
\end{document}

-
Thanks. Is there any way to modify the arrowheads of the pgfplots comb? It's a bit cumbersome to have to draw each the arrows separately. – kristi Jun 9 '11 at 7:55
Updated my answer! I think that this is the best I can do – Spike Jun 9 '11 at 8:18

If you need to have finer control over the plot marks (as you do in this case), you can use the scatter style in addition to ycomb. By enabling scatter, a new hook called scatter/@pre marker code becomes available that allows you to execute code before each mark is drawn.

The option visualization depends on allows you to perform mathematical operations on the current plot coordinates and store the result in a macro. I use it in the example below to determine the sign of the y-coordinate. This sign is then used in the @pre marker code to rotate only those arrows that have a negative y coordinate.

As Spike points out in a comment, the triangles extend beyond the line. This is due to the fact that marks are always centered on the coordinate. A quick fix for this is to add yshift=-2pt after the rotate command:

\documentclass{article}
\usepackage{pgfplots}

\pgfplotsset{
dirac/.style={
mark=triangle*,
mark options={scale=2},
ycomb,
scatter,
visualization depends on={y/abs(y)-1 \as \sign},
scatter/@pre marker code/.code={\scope[rotate=90*\sign,yshift=-2pt]}
}
}

\begin{document}
\begin{tikzpicture}
\makeatletter
\begin{axis}[axis lines=middle,xmin=-3,xmax=3,ymin=-2,ymax=2,grid=both]
\end{axis}
\end{tikzpicture}
\end{document}


-
The question is not about the problem, but the arrows with the mark are not long as expected. There is a way to fix this? – Spike Jun 9 '11 at 21:43
@Spike: Good point! I've edited the answer to correct this. – Jake Jun 9 '11 at 21:53
You are quite great! :) – Spike Jun 10 '11 at 6:23

another PSTricks solution with a variable number of coordinates:

\documentclass{article}
\usepackage{pst-plot}
\makeatletter
\def\psDirac{\pst@object{psDirac}}
\def\psDirac@i(#1,#2){\use@par\psline(#1,0)(#1,#2)%
\@ifnextchar({\psDirac@i}{}}
\makeatother
\begin{document}

\begin{pspicture}[showgrid](-3,-2.25)(3,2.25)
\psaxes[labels=none]{->}(0,0)(-3,-2)(3,2)[$t$,0][$f(t)$,90]
\psDirac[arrows=->,arrowscale=1.5,arrowinset=0,
linewidth=1.5pt,linecolor=blue](2.1,1)(2.5,-1)(-2,-1)(1,1)
\end{pspicture}

\end{document}


-
Very nice post. – Svend Tveskæg Apr 12 '13 at 10:51

i changed it to the following:

\addplot +[mark=triangle*,
mark options={scale=1},
scatter,ycomb,
visualization depends on={(y-abs(y))/abs(y-abs(y)) \as \sign},
scatter/@pre marker code/.code={\scope[rotate=180*\sign,yshift=-2pt]}
] table[x=t_sig, y=sig] {\filename};


then it works for negative numbers other than -1.

-
Ah yes, good point. Or, slightly simpler, use y/abs(y)-1 together with rotate=90*\sign. – Jake Apr 12 '13 at 9:12

With PSTricks. Just for completeness. It can also accept infinite number of points.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot,pst-node}

\makeatletter
\newcommand\psdirac[1][]{\getnodelist{ps@dirac@name}{\ps@dirac[#1]}}
\def\ps@dirac[#1]{{%
\psset{#1}%
\multido{\i=0+1}{\the\numexpr\pst@args+1\relax}{%
\psline(\PST@root\i|0,0)(\PST@root\i)
}}}
\makeatother

\psset{arrows=->}
\def\dirac(#1,#2){\psline(#1,0)(#1,#2)}

\begin{document}
\begin{pspicture}(-1,-3)(5,4)
\psaxes(0,0)(-1,-3)(4.5,3.5)[$t$,0][$f(t)$,90]
\psdirac[linecolor=blue,linewidth=2\pslinewidth](0.5,-1)(2,3)(3.5,-2.5)
\end{pspicture}
\end{document}


Warning:

I don't understand why \PST@root uses capital letters while \pst@args does not. It is a good naming convention. :-)

-
Very nice post. – Svend Tveskæg Apr 12 '13 at 10:52
What is the difference between your post and the one @Herbert posted? – Svend Tveskæg Apr 12 '13 at 10:57
@SvendTveskæg: I used a list of nodes but Herbert used a recursive method. There is an advantage when using a list of nodes because we can use the nodes for other purposes, for example, putting a circle on the diract arrow heads. :-) – kiss my armpit Apr 12 '13 at 11:00
I see. Thank you. – Svend Tveskæg Apr 12 '13 at 11:00
@SvendTveskæg: Defining a new macro as a PStricks object makes more sense because you have the same syntax as for other objects: \psDirac[options]{arrows}(coors).... For simple macros one can also use \pstnewobject – Herbert Apr 12 '13 at 11:23