Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This is a follow-up to naming paths inside a TikZ foreach loop

I want to plot a series of plots with names generated for each plot (usingname path global) in a foreach loop and place a coordinate at the intersection of each plot with a reference line. The coordinates name is also generated in the loop. The names are generated from \ksdlist, the reference line is called RefLine:

\documentclass{standalone}

\usepackage{tikz,pgfplots}

\usetikzlibrary{intersections}%,backgrounds,calc}

\def\ksdList{5e-2,3e-2,2e-2,1e-2,4e-3,1e-3,4e-4,1e-4,1e-5}

\begin{document}
  \begin{tikzpicture}
    \begin{loglogaxis}[
      xmin=2300,xmax=1e8,ymin=0.008,ymax=0.1
      ]
      \path[draw,name path global=RefLine] (rel axis cs:1,0) -- (rel axis cs:1,1);
      \foreach \ksd in \ksdList {
        \edef\plotopt{name path global=plot-\ksd}
        \expandafter\addplot\expandafter[\plotopt,raw gnuplot] gnuplot {
          set xrange [2300:1e8];
          set yrange [0.008:0.1];
          set logscale xy;
          set samples 100;
          f(R,L) = -2*log10(2.51/(R*sqrt(L))+\ksd/3.71)-1/sqrt(L);
          set cont base;
          set cntrparam levels discrete 0;
          unset surface;
          splot f(x,y) smooth unique;
        };
        \edef\intersectionsopt{name intersections={of plot-\ksd and RefLine}}
        % -----------
        % This fails:
        \expandafter\pgfplotsextra{\expandafter\path\expandafter[\intersectionsopt] (intersection-1) coordinate (end-\ksd);};
      }
      % -----------------------------------------------
      % This is how I can place the coordinate manually
      \pgfplotsextra{\path[name intersections={of=plot-5e-2 and RefLine}] (intersection-1) coordinate (end-5e-2);}
    \end{loglogaxis}
    % ---------------------------
    % And I can now place a label
    \path (end-5e-2) node[right] {0.05};
  \end{tikzpicture}
\end{document}

The options for creating the intersections are in \intersectionsopt, but they include a pair of braces, which I think is the cause for errors during compilation.

share|improve this question
add comment

1 Answer 1

up vote 3 down vote accepted

Instead of going to all that trouble with the \edefs, you can just use \pgfplotsinvokeforeach{<list>}{<code, where the current list element is available as #1>}, which executes the loop code directly (instead of accumulating the commands and executing them at the same time, as \foreach does).

\documentclass{standalone}

\usepackage{pgfplots}

\usetikzlibrary{intersections}

\begin{document}
  \begin{tikzpicture}
    \begin{loglogaxis}[clip=false,
      xmin=2300,xmax=1e8,ymin=0.008,ymax=0.1
      ]
      \path[draw,name path global=RefLine] (rel axis cs:1,0) -- (rel axis cs:1,1);
      \pgfplotsinvokeforeach{5e-2,3e-2,2e-2,1e-2,4e-3,1e-3,4e-4,1e-4,1e-5}{
       \addplot[name path global=plot-#1,raw gnuplot] gnuplot {
          set xrange [2300:1e8];
          set yrange [0.008:0.1];
          set logscale xy;
          set samples 100;
          f(R,L) = -2*log10(2.51/(R*sqrt(L))+#1/3.71)-1/sqrt(L);
          set cont base;
          set cntrparam levels discrete 0;
          unset surface;
          splot f(x,y) smooth unique;
        };
        \pgfplotsextra{\path[name intersections={of=plot-#1 and RefLine}] (intersection-1) node [right] {#1};};
      }
    \end{loglogaxis}
  \end{tikzpicture}
\end{document}

If you need to have the list as a macro, you can \edef the plot command.

\documentclass{standalone}

\usepackage{pgfplots}

\usetikzlibrary{intersections}

\def\ksdList{{5e-2,3e-2,2e-2,1e-2,4e-3,1e-3,4e-4,1e-4,1e-5}}

\begin{document}
  \begin{tikzpicture}
    \begin{loglogaxis}[clip=false,
      xmin=2300,xmax=1e8,ymin=0.008,ymax=0.1
      ]
      \path[draw,name path global=RefLine] (rel axis cs:1,0) -- (rel axis cs:1,1);
      \edef\doplot{
      \noexpand\pgfplotsinvokeforeach{\ksdList}{
       \noexpand\addplot[name path global=plot-\noexpand##1,raw gnuplot] gnuplot {
          set xrange [2300:1e8];
          set yrange [0.008:0.1];
          set logscale xy;
          set samples 100;
          f(R,L) = -2*log10(2.51/(R*sqrt(L))+\noexpand##1/3.71)-1/sqrt(L);
          set cont base;
          set cntrparam levels discrete 0;
          unset surface;
          splot f(x,y) smooth unique;
        };
        \noexpand\pgfplotsextra{\noexpand\path[name intersections={of=plot-\noexpand##1 and RefLine}] (intersection-1) node [right] {\noexpand##1};};
      }}
      \doplot
    \end{loglogaxis}
  \end{tikzpicture}
\end{document}
share|improve this answer
    
Definitely helpful, but I'd like to reuse \ksdList in several parts of the code. Is there any way to do that in your solution? –  Christoph Feb 9 '12 at 12:52
    
That approach (\edefing the whole loop) is something I didn't expect to work and couldn't have come up with anyway, but it work perfectly! Thank you. –  Christoph Feb 9 '12 at 13:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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