With the BIG help of @njsg (Nuno Silva) I made this plot. The goal is use it as a animation inside a beamer slide.
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage[export]{animate}
%\usepackage{animate}
\usepackage{pythontex}
\usepackage[output-decimal-marker={,}]{siunitx}
% Código copiado de
% https://tex.stackexchange.com/questions/389478/how-can-i-access-a-float-defined-via-pgfmathsetmacro-from-pythontex/389530#389530
\makeatletter
\newcommand{\pythontexassign}[2]{%
\expandafter\pythontexassign@i\expandafter{#2}{#1}}
\newcommand{\pythontexassign@i}[2]{%
\pyc{#2=#1}}
\makeatother
%
\newcommand{\pySI}[2]{\py{'\SI{' + str(#1) + '}{#2}'}}
\begin{document}
\begin{pycode}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sympy import *
x = symbols('x')
xp = 1
func = x**2+2
Deltax = 9
Divisoes= 10
dx = Deltax/Divisoes
func = sympify(func)
dfunc = diff(func, x)
yp = func.subs(x,xp)
mt = dfunc.subs(x,xp)
bt = yp-mt*xp
tang = mt*x+bt
tang = sympify(tang)
def sympy2pgf(expression):
return latex(expression,mul_symbol='times')\
.replace(r'\times','*')\
.replace('{','(').replace('}',')')
def teste(valor):
return valor
def calcpos(i):
xi = (xp+Deltax) - dx*i
yi = func.subs(x,xi)
return(xi,yi)
def recta(i):
if xp == (xp+Deltax) - dx*i:
return sympy2pgf(tang)
else:
ms = (calcpos(i)[1] - yp)/(calcpos(i)[0] - xp)
bs = yp - ms*xp
seca = ms*x+bs
seca = sympify(seca)
return sympy2pgf(seca)
\end{pycode}
\begin{animateinline}[poster=last,autoplay,loop]{5}
\multiframe{10}{rt=1+1}{%
\resizebox{0.5\textwidth}{!}{%
\begin{tikzpicture}[shift={(1,1)},x=1cm, y=1cm,
extended line/.style={shorten >=-#1,shorten <=-#1},
extended line/.default=2cm]
\begin{axis}[%
x=1cm, y=0.1cm,
anchor=target,
enlargelimits=0.05,
axis x line = center,
axis y line = left,
axis line style={line width=1pt,->,opacity=1},
ymin=0,
ymax=120,
xmin=0,
xmax=12,
clip mode=individual,
%clip mode=false,
axis x line=bottom,
axis y line=left,
xtick={0,2,...,10},
ytick={0,20,...,100},
ticklabel style={font=\normalsize,opacity=1},
xlabel={$t/\si{s}$},
ylabel={$x/\si{m}$},
y tick label style={
/pgf/number format/.cd,
fixed,
fixed zerofill,
precision=1,
use comma,
/tikz/.cd},
x tick label style={
/pgf/number format/.cd,
fixed,
fixed zerofill,
precision=1,
use comma,
/tikz/.cd},
every axis x label/.style={
at={(ticklabel* cs:1)},
anchor=north east,
style={font=\normalsize},
opacity=1},
every axis y label/.style={
at={(ticklabel* cs:1)},
anchor=north east,
style={font=\normalsize},
opacity=1},
%ticks=none,
]
% Atribuição da variável \rt a meurt
\pythontexassign{meurt}{\rt}
% curva
\pys{\addplot [domain=0:10, samples=100, color=blue ]{!{sympy2pgf(func)}};}
% rectas
\pys{\addplot [domain=0:10, samples=100, color=blue ]{!{recta(meurt)}};}
% Ponto fixo
\pys{\coordinate (P) at (!{xp},!{yp});}
\node[outer sep=0pt,circle, fill=red,inner sep=1.5pt] (P) at (P) {};
% Ponto variável
\pys{\coordinate (Q) at (!{calcpos(meurt)[0]},!{calcpos(meurt)[1]});}
\node[outer sep=0pt,circle, fill=red,inner sep=1.5pt] (Q) at (Q) {};
% tracejados
\pys{\draw[red,dotted,very thick] (P) -- (!{xp},0);}
\pys{\draw[red,dotted,very thick] (P) -- (0,!{yp});}
\pys{\draw[red,dotted,very thick] (Q) -- (!{calcpos(meurt)[0]},0);}
\pys{\draw[red,dotted,very thick] (Q) -- (0,!{calcpos(meurt)[1]});}
% chavetas
\pys{\draw[decorate,decoration={brace,amplitude=3pt,mirror}] (!{xp},-5.0) -- (!{calcpos(meurt)[0]},-5.0) ; }
\pys{\draw[decorate,decoration={brace,amplitude=3pt,mirror}] (-.90,!{calcpos(meurt)[1]}) -- (-.90,!{yp}) ; }
% Deltas
\pys{\pgfmathsetmacro\XP{!{xp}}}
\pys{\pgfmathsetmacro\YP{!{yp}}}
\pys{\pgfmathsetmacro\XI{!{calcpos(meurt)[0]}}}
\pys{\pgfmathsetmacro\YI{!{calcpos(meurt)[1]}}}
\pgfmathsetmacro\DELTAX{ \XI - \XP }
\pgfmathsetmacro\DELTAY{ \YI - \YP }
\node[text width=3cm] at (\XI,-10.0) {$\Delta x =$ \DELTAX $\si{\second}$};
\node[text width=3cm] at (-1.55,\YI) {$\Delta y =$ \DELTAY $\si{\metre}$ };
\node[coordinate] (target) at (axis cs:0,0){};
\end{axis}
\end{tikzpicture}}}
\end{animateinline}
\end{document}
But, when I change from this
\usepackage[export]{animate}
%\usepackage{animate}
to this
%\usepackage[export]{animate}
\usepackage{animate}
the result is unexpected, as the images show
and the next one, the problematic:
what I can do to solve this issue.
To AlexG
- compile de next code with:
xelatex figura.tex pythontex figura. xelatex figura.tex
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage[export]{animate}
%\usepackage{animate}
\usepackage{pythontex}
\usepackage[output-decimal-marker={,}]{siunitx}
% Código copiado de
% https://tex.stackexchange.com/questions/389478/how-can-i-access-a-float-defined-via-pgfmathsetmacro-from-pythontex/389530#389530
\makeatletter
\newcommand{\pythontexassign}[2]{%
\expandafter\pythontexassign@i\expandafter{#2}{#1}}
\newcommand{\pythontexassign@i}[2]{%
\pyc{#2=#1}}
\makeatother
%
\newcommand{\pySI}[2]{\py{'\SI{' + str(#1) + '}{#2}'}}
\begin{document}
\begin{pycode}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sympy import *
x = symbols('x')
xp = 1
func = x**2+2
Deltax = 9
Divisoes= 10
dx = Deltax/Divisoes
func = sympify(func)
dfunc = diff(func, x)
yp = func.subs(x,xp)
mt = dfunc.subs(x,xp)
bt = yp-mt*xp
tang = mt*x+bt
tang = sympify(tang)
def sympy2pgf(expression):
return latex(expression,mul_symbol='times')\
.replace(r'\times','*')\
.replace('{','(').replace('}',')')
def teste(valor):
return valor
def calcpos(i):
xi = (xp+Deltax) - dx*i
yi = func.subs(x,xi)
return(xi,yi)
def recta(i):
if xp == (xp+Deltax) - dx*i:
return sympy2pgf(tang)
else:
ms = (calcpos(i)[1] - yp)/(calcpos(i)[0] - xp)
bs = yp - ms*xp
seca = ms*x+bs
seca = sympify(seca)
return sympy2pgf(seca)
\end{pycode}
\begin{animateinline}[poster=first,autoplay,loop]{4}
\multiframe{10}{rt=1+1}{%
\resizebox{0.5\textwidth}{!}{%
\begin{tikzpicture}[shift={(1,1)},x=1cm, y=1cm,
extended line/.style={shorten >=-#1,shorten <=-#1},
extended line/.default=2cm]
\begin{axis}[%
x=1cm, y=0.1cm,
anchor=target,
enlargelimits=0.05,
axis x line = center,
axis y line = left,
axis line style={line width=1pt,->,opacity=1},
ymin=0,
ymax=120,
xmin=0,
xmax=12,
clip mode=individual,
axis x line=bottom,
axis y line=left,
xtick={0,2,...,10},
ytick={0,20,...,100},
ticklabel style={font=\normalsize,opacity=1},
xlabel={$t/\si{s}$},
ylabel={$x/\si{m}$},
y tick label style={
/pgf/number format/.cd,
fixed,
fixed zerofill,
precision=1,
use comma,
/tikz/.cd},
x tick label style={
/pgf/number format/.cd,
fixed,
fixed zerofill,
precision=1,
use comma,
/tikz/.cd},
every axis x label/.style={
at={(ticklabel* cs:1)},
anchor=north east,
style={font=\normalsize},
opacity=1},
every axis y label/.style={
at={(ticklabel* cs:1)},
anchor=north east,
style={font=\normalsize},
opacity=1},
]
% Atribuição da variável \rt a meurt
\pythontexassign{meurt}{\rt}
% curva
\pys{\addplot [domain=0:10, samples=100, color=blue ]{!{sympy2pgf(func)}};}
% rectas
\pys{\addplot [domain=0:10, samples=100, color=blue ]{!{recta(meurt)}};}
% Ponto fixo
\pys{\coordinate (P) at (!{xp},!{yp});}
\node[outer sep=0pt,circle, fill=red,inner sep=1.5pt] (P) at (P) {};
% Ponto variável
\pys{\coordinate (Q) at (!{calcpos(meurt)[0]},!{calcpos(meurt)[1]});}
\node[outer sep=0pt,circle, fill=red,inner sep=1.5pt] (Q) at (Q) {};
% tracejados
\pys{\draw[red,dotted,very thick] (P) -- (!{xp},0);}
\pys{\draw[red,dotted,very thick] (P) -- (0,!{yp});}
\pys{\draw[red,dotted,very thick] (Q) -- (!{calcpos(meurt)[0]},0);}
\pys{\draw[red,dotted,very thick] (Q) -- (0,!{calcpos(meurt)[1]});}
% chavetas
\pys{\draw[decorate,decoration={brace,amplitude=3pt,mirror}] (!{xp},-5.0) -- (!{calcpos(meurt)[0]},-5.0) ; }
\pys{\draw[decorate,decoration={brace,amplitude=3pt,mirror}] (-.90,!{calcpos(meurt)[1]}) -- (-.90,!{yp}) ; }
% Deltas
% inicialização
\pgfmathsetmacro\XP{0.0}
\pgfmathsetmacro\YP{0.0}
\pgfmathsetmacro\XI{0.0}
\pgfmathsetmacro\YI{0.0}
% operação
\pys{\pgfmathsetmacro\XP{!{xp}}}
\pys{\pgfmathsetmacro\YP{!{yp}}}
\pys{\pgfmathsetmacro\XI{!{calcpos(meurt)[0]}}}
\pys{\pgfmathsetmacro\YI{!{calcpos(meurt)[1]}}}
\pgfmathsetmacro\DELTAX{ \XI - \XP }
\pgfmathsetmacro\DELTAY{ \YI - \YP }
\node[text width=3cm] at (\XI,-10.0) {$\Delta x =$ \DELTAX $\si{\second}$};
\node[text width=3cm] at (-1.55,\YI) {$\Delta y =$ \DELTAY $\si{\metre}$ };
\node[coordinate] (target) at (axis cs:0,0){};
\end{axis}
\end{tikzpicture}}}
\end{animateinline}
\end{document}
you have just make a pdf with the name figura.pdf
- then, compile the next code with
xelatex beamer.tex
\documentclass[compress]{beamer}
\usepackage{animate}
\begin{document}
\section{Figura}
\begin{frame}
\begin{figure}
\animategraphics[autoplay,loop]{4}{figura}{}{}
\end{figure}
\end{frame}
\end{document}
Works for me.



Undefined control sequence \XI, to get it to work I had to comment out the four lines starting with\pgfmathsetmacro\DELTAX{ \XI - \XP }, runpdflatexthenpythontex, then uncomment those four lines, and runpdflatexagain. I don't quite understand what the problem is though, is there a lot of whitespace in the second image? Edit: that was without changing the code at all though. – Torbjørn T. Sep 14 '19 at 12:14\XIis being defined inside\pys{}, which means it will not be defined until there is some result from pythontex to embed in the document. Either all uses of\XIneed to be wrapped with\pysorpysub(while this looks like it is possible here, it might not be always possible), or\XImust be defined in some way outside pythontex (for example, by adding\pgfmathsetmacro\XI{42}(or some other value, of course) before the\pys{...}command which will set\XI— somebody else might have a more elegant solution, though?). – njsg Sep 14 '19 at 13:17% Deltas
% inicialização
\pgfmathsetmacro\XP{0.0}
\pgfmathsetmacro\YP{0.0}
\pgfmathsetmacro\XI{0.0}
\pgfmathsetmacro\YI{0.0}
% operação
\pys{\pgfmathsetmacro\XP{!{xp}}}
\pys{\pgfmathsetmacro\YP{!{yp}}}
\pys{\pgfmathsetmacro\XI{!{calcpos(meurt)[0]}}}
\pys{\pgfmathsetmacro\YI{!{calcpos(meurt)[1]}}}
\pgfmathsetmacro\DELTAX{ \XI - \XP}
\pgfmathsetmacro\DELTAY{ \YI - \YP}
\node[text width=3cm] at (\XI,-10.0) {$\Delta x =$ \DELTAX $\si{\second}$};
\node[text width=3cm] at (-1.55,\YI) {$\Delta y =$ \DELTAY $\si{\metre}$ };
– Luis Ferreira Sep 14 '19 at 13:45PandQnodes are defined within a\pys, so at the first run they are not available, and you get an error. Do as @njsg suggest, and use a\pysfor those two\nodes as well. Doesn't solve the whitespace problem, but it would make the code compile without errors. – Torbjørn T. Sep 14 '19 at 14:17exportoption in the first place. – Torbjørn T. Sep 14 '19 at 14:20animatecorrectly,exportexports the animation with the still frames as different pages, while, without that option, it is exported as a PDF embedded animation. – njsg Sep 14 '19 at 14:47foo.pdf, you could load theanimatepackage in your presentation and use\animategraphics{2}{foo}{}{}to get an animation running at 2 fps (cf. https://tex.stackexchange.com/q/30683/). I couldn't get it to work, but I don't know if it's because the PDF viewers I tried couldn't handle the animation. – Torbjørn T. Sep 14 '19 at 18:30xelatexalready fails.! Package pgf Error: No shape named P is known.– AlexG Sep 16 '19 at 13:07xelatex -interaction nonstopmode, for example), you should be able to run pythontex and latex itself won't fail anymore after that. – njsg Sep 16 '19 at 14:18previewoption is passed to the document class. But that will also change the output ofanimatewith theexportoption. – njsg Sep 16 '19 at 14:29pygments=falseoption of pythontex. – njsg Sep 16 '19 at 19:58\documentclass{standalone}\usepackage{pythontex}\begin{document}Teste: \py{'1'}\end{document}– njsg Sep 16 '19 at 20:04