5

I'm trying to generate a couple of intersecting peaks with pgfplots with dashed/dotted paths where they overlap. I'm having some trouble though with path names inside a foreach loop. Here's the code:

    \documentclass[tikz]{standalone}
    \usepackage{tikz, pgfplots}

    \usetikzlibrary{positioning, intersections}
    \usepgfplotslibrary{fillbetween}

    \pgfmathdeclarefunction{peak}{1}{%
      \pgfmathparse{abs(#1) > 1 ? 0 : cos((0.5*pi*#1) r)^3}%
    }%
    \begin{document}
    \begin{tikzpicture}
    \begin{axis}[width=400pt, height=250pt]

      % overlapping peaks
      \pgfplotsinvokeforeach{-1,0,1}{
        \addplot [name path global = { line#1 },
        domain=#1-1:#1+1, samples=20, smooth, thick, black]
        {peak(x-#1)};
      }

      \path[draw=white, dotted, ultra thick,
      intersection segments={of=line1 and line0}];

      \path[draw=white, dotted, ultra thick,
      intersection segments={of=line0 and line-1}];

    \end{axis}
    \end{tikzpicture}
    \end{document}

I'd like to put the last two path calls inside some kind of loop. The issue is how to get the line names. Tried line#1 and line#1-1 inside a pgfplots foreach but it doesn't work (obviously? it is still not so clear to me where math does and doesn't work with pgf), tried line\i and line\i-1 in a \foreach \i loop. Doesn't work either...

Also tried putting the subtraction in a \pgfmathparse{int(#1-1)}\pgfmathresult pair but it always complains about missing \endcsname.

Any idea? Also any suggestion about better ways to achieve what I'd like are more than welcome... thanks!

2

See below. This works by fully expanding the arguments for \path before it is called. Note that you are missing a % at the opening brace for peak which is shifting the entire plot.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}

\usetikzlibrary{positioning,intersections}
\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{peak}{1}{%
    \pgfmathparse{abs(#1) > 1 ? 0 : cos((0.5*pi*#1) r)^3}%
    }%
\begin{document}
\begin{tikzpicture}
    \begin{axis}[width=400pt, height=250pt]
        % overlapping peaks
        \pgfplotsinvokeforeach{-1,0,1}{%
            \addplot [name path = { line#1 },
            domain=#1-1:#1+1, samples=20, smooth, thick, black]
            {peak(x-#1)};
        }
        \foreach \x in {0,...,1}{%
            \pgfmathparse{int(\x-1)};
            \def\arg{of=line\x\space and line\pgfmathresult}%
            \edef\expath{\noexpand\path[draw=white, dotted, ultra thick,
                intersection segments={\arg}];}
            \expath%
        }
    \end{axis}
\end{tikzpicture}
\end{document}

result

  • Thank you, I suspected I needed to expand the args but couldn't find how. Works perfectly now. Will edit the code to add the missing % – filippo Dec 17 '15 at 20:43
1

A Metapost alternative. Simpler syntax? you decide. I've cheated slightly by plotting only one curve, then copying it by simply shifting it left and right. The working of intersectiontimes is explained in the MP manual.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

vardef f(expr x) = if abs x > 1: 0 else: (cosd(90x))**3 fi enddef;

path xx, yy, line[];

xx = (left--right) scaled 220 shifted 20 down;
yy = (origin--up)  scaled 180 shifted point 0 of xx;

drawarrow xx withcolor .5 white;
drawarrow yy withcolor .5 white;

s = 1/32;
line2 = ((-1,f(-1)) for x=s-1 step s until 1: -- (x,f(x)) endfor) yscaled 150 xscaled 100;
line1 = line2 shifted 100 left;
line3 = line2 shifted 100 right;

numeric t[];
(t1,t2) = line1 intersectiontimes line2;
(t3,t4) = line2 intersectiontimes line3;

drawoptions(withcolor .67 red);
draw subpath( 0,t1)       of line1; 
draw subpath(t2,t3)       of line2;
draw subpath(t4,infinity) of line3;

drawoptions(dashed withdots scaled 0.7);
draw subpath(t1,infinity) of line1;
draw subpath(t3,infinity) of line2;
draw subpath(0,t2)        of line2;
draw subpath(0,t4)        of line3;

drawoptions();

endfig;
end.
  • Thanks! will keep it in mind, maybe for the next project. Too invested in tikz and pgfplots with this one to change now ;) – filippo Dec 17 '15 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.