pgfplot;动画;pythontex:导数的图

pgfplot;动画;pythontex:导数的图

在@njsg (Nuno Silva) 的大力帮助下,我制作了这个情节。目标是将其用作投影仪幻灯片中的动画。

\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}

但是,当我改变这一点时

\usepackage[export]{animate}
%\usepackage{animate}

对此

%\usepackage[export]{animate}
\usepackage{animate}

结果出乎意料,正如图片所示

在此处输入图片描述

下一个是有问题的:

在此处输入图片描述

我可以做些什么来解决这个问题。


致 AlexG

  1. 使用以下代码编译:

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}

你刚刚创建了一个名为 figura.pdf 的 pdf

  1. 然后,使用以下代码编译

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}

对我有用。

在此处输入图片描述

相关内容