problema de loop foreach com duas variáveis

problema de loop foreach com duas variáveis

Quero desenhar um trem de pulsos no qual escrevo algumas informações como o ângulo correspondente, etc... Mas acho que tenho um problema com as duas variáveis ​​do loop foreach porque não consigo nem compilar desde que adicionei esta linha

\addplot[dirac] coordinates {(\temps,0.75)};

O código inteiro é:

\documentclass[tikz]{standalone}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage{pgfplots}

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

\begin{document}
  \begin{tikzpicture}
  \tikzset{
    every pin/.style={fill=yellow!50!white,rectangle,rounded                corners=3pt,font=\scriptsize},
    small dot/.style={fill=black,circle,scale=0.2}
}

\begin{axis}[axis lines=middle,x=1,xmin=-25,xmax=375,y=100,ymin=0,ymax=1,
  title={Train d'impulsions à 40MHz},ylabel={Tx},xlabel={Temps/ns},
  every axis y label/.style={at={(ticklabel cs:1)},anchor=near ticklabel},
  every axis x label/.style={at={(ticklabel cs:1)},anchor=near ticklabel},
  ytickmin=2, xtickmax=350, axis y line=left
  ]

  \foreach \temps/\angle in {0/-21, 25/-18, 50/-15, 75/-12}{
     \edef\temp{\noexpand
     \addplot[dirac] coordinates {(\temps,0.75)};
     \node[small dot,pin={$\angle\degres$}]  at (25+\temps,70) {};}
     \temp
  }

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

Agradecemos antecipadamente por me ajudar. Para minha defesa, sou iniciante no Tikz-PGF

Responder1

Como o axisambiente está adiando a avaliação de algumas coisas até então \end{axis}, as variáveis \temps​​e \anglenão existem mais até então. Nesse caso, você pode usar \pgfplotsinvokeforeachisso para substituir imediatamente o contador de loop por qualquer #1dado no corpo do loop. A única desvantagem é que ele não suporta múltiplas variáveis ​​de loop, então você tem que calcular uma a partir da outra assim:

\pgfplotsinvokeforeach{0,25,...,75}{
  \addplot[dirac] coordinates {(#1,0.75)};
  \node[small dot,pin={
    \pgfmathtruncatemacro{\angle}{#1/25*3-21}%
    $\angle\degres$
  }]  at (25+#1,70) {};
}

Isso produz:

Resultado

Uma dica adicional: você provavelmente deveria consultar a seção 4.17 "Anotações personalizadas" do pgfplotsmanual para ver como você pode especificar as coordenadas dos nós no sistema de coordenadas do gráfico usando axis cs.


Detalhes técnicos

Parece que você tentou forçar a expansão \tempse \angleusar \edef, mas, ao fazer isso, você terá que proteger tudo o que não deseja expandir \noexpand, o que é bastante tedioso. Se você mover a criação dos pinos para fora do ambiente do eixo funciona, mas fica difícil alinhar os pinos com o gráfico...

Além disso, \tempsparece ser uma má escolha para um nome de macro, embora não saiba dizer por quê. Se você remover \nodedo loop, ainda não funcionará:

\foreach \temps/\angle in {0/-21, 25/-18, 50/-15, 75/-12}{
   \addplot[dirac] coordinates {(\temps,0.75)};
}

falha com Incomplete \iffalse; all text was ignored after line <N>, por razões desconhecidas para mim. Se você renomear \tempspara \temp, no entanto, funciona!

Mas isso ainda não permite que você use o \nodecomando \tempdentro do loop. Ainda reclama que \tempé indefinido, pois a \nodemacro só é avaliada no final do axisambiente. Uma solução alternativa é forçar manualmente a expansão \tempe \angleusar \expandafterassim:

\def\LoopBody#1#2{%
  \addplot[dirac] coordinates {(#1,0.75)};
  \node[small dot,pin={$#2\degres$}]  at (25+#1,70) {};
}
\let\EA=\expandafter% For shorter code
\foreach \temp/\angle in {0/-21, 25/-18, 50/-15, 75/-12}{
   \EA\EA\EA\LoopBody\EA\EA\EA{\EA\temp\EA}\EA{\angle}
}

Isso se expande primeiro \anglepara -21, depois \temppara 0e então \LoopBody{0}{-21}(etc). No entanto, isso não é algo que eu possa realmente recomendar porque é difícil de entender e depurar. Talvez alguém com uma melhor compreensão dos pgfplotsaspectos internos possa dar mais informações sobre por que isso é necessário.

informação relacionada