
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 axis
ambiente está adiando a avaliação de algumas coisas até então \end{axis}
, as variáveis \temps
e \angle
não existem mais até então. Nesse caso, você pode usar \pgfplotsinvokeforeach
isso para substituir imediatamente o contador de loop por qualquer #1
dado 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:
Uma dica adicional: você provavelmente deveria consultar a seção 4.17 "Anotações personalizadas" do pgfplots
manual 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 \temps
e \angle
usar \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, \temps
parece ser uma má escolha para um nome de macro, embora não saiba dizer por quê. Se você remover \node
do 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 \temps
para \temp
, no entanto, funciona!
Mas isso ainda não permite que você use o \node
comando \temp
dentro do loop. Ainda reclama que \temp
é indefinido, pois a \node
macro só é avaliada no final do axis
ambiente. Uma solução alternativa é forçar manualmente a expansão \temp
e \angle
usar \expandafter
assim:
\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 \angle
para -21
, depois \temp
para 0
e 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 pgfplots
aspectos internos possa dar mais informações sobre por que isso é necessário.