texlive[60958] Master/texmf-dist: bodeplot (5nov21)
commits+karl at tug.org
commits+karl at tug.org
Fri Nov 5 23:01:31 CET 2021
Revision: 60958
http://tug.org/svn/texlive?view=revision&revision=60958
Author: karl
Date: 2021-11-05 23:01:30 +0100 (Fri, 05 Nov 2021)
Log Message:
-----------
bodeplot (5nov21)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/latex/bodeplot/bodeplot.pdf
trunk/Master/texmf-dist/source/latex/bodeplot/bodeplot.dtx
trunk/Master/texmf-dist/tex/latex/bodeplot/bodeplot.sty
Modified: trunk/Master/texmf-dist/doc/latex/bodeplot/bodeplot.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/source/latex/bodeplot/bodeplot.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/bodeplot/bodeplot.dtx 2021-11-05 02:03:52 UTC (rev 60957)
+++ trunk/Master/texmf-dist/source/latex/bodeplot/bodeplot.dtx 2021-11-05 22:01:30 UTC (rev 60958)
@@ -27,7 +27,8 @@
%
%<*driver>
\documentclass{ltxdoc}
-\usepackage{bodeplot,cprotect,hyperref}
+\usepackage{bodeplot,cprotect}
+\usepackage[colorlinks]{hyperref}
\usetikzlibrary{decorations.markings,arrows.meta}
\EnableCrossrefs
\CodelineIndex
@@ -40,7 +41,7 @@
%</driver>
% \fi
%
-% \CheckSum{1162}
+% \CheckSum{1287}
%
% \changes{v1.0}{2021/10/25}{Initial release}
%
@@ -49,8 +50,8 @@
% \DoNotIndex{\newcommand,\xdef,\gdef,\def,\edef,\addplot,\approx,\arabic,\opt,\typ,\obj,\else,\if at pgfarg,\fi,\begin,\end,\feature,\footnotesize,\draw,\detokenize,\DeclareOption,\foreach,\ifdim,\ifodd,\Im,\Re,\let,\newif,\nextgroupplot,\noexpand,\expandafter,\unexpanded,\PackageError,\PackageWarning,\relax,\RequirePackage,\tikzset,\pgfmathsetmacro,\pgfmathtruncatemacro,\ProcessOptions}
%
% \title{The \textsf{bodeplot} package\thanks{This document
-% corresponds to \textsf{bodeplot}~\fileversion,
-% dated \filedate.}}
+% corresponds to \textsf{bodeplot}~v1.0.3,
+% dated November 3, 2021.}}
% \author{Rushikesh Kamalapurkar \\ \texttt{rlkamalapurkar at gmail.com}}
%
% \maketitle
@@ -57,7 +58,7 @@
% \tableofcontents
% \section{Introduction}
%
-% Generate Bode, Nyquist, and Nichols plots for transfer functions in the canonical (TF) form \begin{equation}G(s) = e^{-Ts}\frac{b_ms^m+\cdots+b_1s+b_0}{a_ns^n+\cdots+a_1s+a_0}\label{eq:TF}\end{equation} and the zero-pole-gain (ZPK) form \begin{equation}G(s) = Ke^{-Ts}\frac{(s-z_1)(s-z_2)\cdots(s-z_m)}{(s-p_1)(s-p_2)\cdots(s-p_n)}.\label{eq:ZPK}\end{equation} In the equations above, $b_m,\cdots,b_0$ and $a_n,\cdots,a_0$ are real coefficients, $T\geq 0$ is the loop delay, $z_1,\cdots,z_m$ and $p_1,\cdots,p_n$ are complex zeros and poles of the transfer function, respectively, and $K\in \Re$ is the loop gain. For transfer functions in the ZPK format in (\ref{eq:ZPK}) with zero delay, this package also supports linear and asymptotic approximation of Bode plots.
+% Generate Bode, Nyquist, and Nichols plots for transfer functions in the canonical (TF) form \begin{equation}G(s) = e^{-Ts}\frac{b_ms^m+\cdots+b_1s+b_0}{a_ns^n+\cdots+a_1s+a_0}\label{eq:TF}\end{equation} and the zero-pole-gain (ZPK) form \begin{equation}G(s) = Ke^{-Ts}\frac{(s-z_1)(s-z_2)\cdots(s-z_m)}{(s-p_1)(s-p_2)\cdots(s-p_n)}.\label{eq:ZPK}\end{equation} In the equations above, $b_m,\cdots,b_0$ and $a_n,\cdots,a_0$ are real coefficients, $T\geq 0$ is the loop delay, $z_1,\cdots,z_m$ and $p_1,\cdots,p_n$ are complex zeros and poles of the transfer function, respectively, and $K\in \Re$ is the loop gain. For transfer functions in the ZPK format in (\ref{eq:ZPK}) with zero delay, this package also supports linear and asymptotic approximation of Bode plots. \textbf{Limitation:} in TF form, the phase angles are always between 0 and 360$^\circ$, As such, the Bode phase plots and the Nyquist and Nichols plots will have phase wrapping discontinuities. I do not know how this can be rectified, pull requests are welcome!
%
% \section{Usage}
% \subsection{Bode plots}
@@ -81,6 +82,7 @@
% \item |plot/{opt}|: adds options |{opt}| to |\addplot| macros for both the magnitude and the phase plots.
% \item |axes/{opt}|: adds options |{opt}| to |\nextgroupplot| macros for both the magnitude and the phase plots.
% \item |group/{opt}|: adds options |{opt}| to the |groupplot| environment.
+% \item |tikz/{opt}|: adds options |{opt}| to the |tikzpicture| environment.
% \item |approx/linear|: plots linear approximation.
% \item |approx/asymptotic|: plots asymptotic approximation.
% \end{itemize}
@@ -114,7 +116,7 @@
%
% \begin{figure}
% \begin{center}
-% \BodeZPK[plot/mag/{red,thick},plot/ph/{blue,thick},axes/mag/{ytick distance=40,xmajorticks=true,xlabel={Frequency (rad/s)}},axes/ph/{ytick distance=90},approx/linear,group/{group style={group size = 2 by 1,horizontal sep=2cm},width=4cm,height=2cm},] {z/{0,{-0.1,-0.5},{-0.1,0.5}},p/{{-0.5,-10},{-0.5,10}},g/10} {0.01} {100}
+% \BodeZPK[plot/mag/{red,thick},plot/ph/{blue,thick},axes/mag/{ytick distance=40,xmajorticks=true,xlabel={Frequency (rad/s)}},axes/ph/{ytick distance=90},approx/linear,group/{group style={group size = 2 by 1,horizontal sep=2cm},width=4cm,height=2cm}] {z/{0,{-0.1,-0.5},{-0.1,0.5}},p/{{-0.5,-10},{-0.5,10}},g/10} {0.01} {100}
% \cprotect\caption{\label{customBode}Customization of the default |\BodeZPK| macro.}
% \end{center}
% \end{figure}
@@ -166,7 +168,7 @@
%\end{BodePlot}
%
%\begin{BodePlot}[ylabel={Phase ($^{\circ}$)},
-% height=2cm, width=4cm, ytick distance=90,] {0.01} {100}
+% height=2cm, width=4cm, ytick distance=90] {0.01} {100}
% \addBodeZPKPlots[
% true/{black,thick},
% linear/{red,dashed,thick},
@@ -188,7 +190,7 @@
% {z/{0,{-0.1,-0.5},{-0.1,0.5}},p/{{-0.1,-10},{-0.1,10}},k/10}
% \end{BodePlot}
% \begin{BodePlot}[ylabel={Phase ($^{\circ}$)},
-% height=2cm, width=4cm, ytick distance=90,] {0.01} {100}
+% height=2cm, width=4cm, ytick distance=90] {0.01} {100}
%
% \addBodeZPKPlots[
% true/{black,thick},
@@ -303,7 +305,7 @@
% \hspace*{2em}\marg{z/\marg{zeros},p/\marg{poles},k/\marg{gain},d/\marg{delay}}\\
% \hspace*{2em}\marg{min-freq}\marg{max-freq}
%
-% \noindent Plots the Nyquist plot of a transfer function given in ZPK format with a thick red $+$ marking the critical point (-1,0). The mandatory arguments are the same as |\BodeZPK|. Since there is only one plot in a Nyquist diagram, the |\typ| specifier in the optional argument tuples is not needed. As such, the supported optional argument tuples are |plot/{opt}|, which passes |{opt}| to |\addplot| and |axes/{opt}|, which passes |{\opt}| to the |axis| environment. Asymptotic/linear approximations are not supported in Nyquist plots. If just |{opt}| is provided as the optional argument, it is interpreted as |plot/{opt}|. Arrows to indicate the direction of increasing $\omega$ can be added by adding |\usetikzlibrary{decorations.markings}| and |\usetikzlibrary{arrows.meta}| to the preamble and then passing a tuple of the form\\
+% \noindent Plots the Nyquist plot of a transfer function given in ZPK format with a thick red $+$ marking the critical point (-1,0). The mandatory arguments are the same as |\BodeZPK|. Since there is only one plot in a Nyquist diagram, the |\typ| specifier in the optional argument tuples is not needed. As such, the supported optional argument tuples are |plot/{opt}|, which passes |{opt}| to |\addplot|, |axes/{opt}|, which passes |{\opt}| to the |axis| environment, and |tikz/{opt}|, which passes |{\opt}| to the |tikzpicture| environment. Asymptotic/linear approximations are not supported in Nyquist plots. If just |{opt}| is provided as the optional argument, it is interpreted as |plot/{opt}|. Arrows to indicate the direction of increasing $\omega$ can be added by adding |\usetikzlibrary{decorations.markings}| and |\usetikzlibrary{arrows.meta}| to the preamble and then passing a tuple of the form\\
%|plot/{postaction=decorate,decoration={markings,|\\
%| mark=between positions 0.1 and 0.9 step 5em with|\\
%| {\arrow{Stealth| |[length=2mm, blue]}}}}|\\
@@ -423,6 +425,7 @@
% \begin{macro}{\n at pow}
% \begin{macro}{idGnuplot}
% \begin{macro}{gnuplot def}
+% \changes{v1.0.3}{2021/11/03}{Added jobname to gnuplot prefix}
% \begin{macro}{gnuplot degrees}
% This code is needed to support both |pgfplots| and |gnuplot| simultaneously. New macros are defined for the |pow| and |mod| functions to address differences between the two math engines. We start by processing the |pgf| class option.
% \begin{macrocode}
@@ -448,7 +451,7 @@
\tikzset{%
gnuplot def/.style={%
id=\arabic{idGnuplot},
- prefix=gnuplot/
+ prefix=gnuplot/\jobname
}%
}
% \end{macrocode}
@@ -753,55 +756,59 @@
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{\opt at approx}{#2}%
% \end{macrocode}
-% The |\noexpand| macros below are needed to so that only the macro |\opt at group| is expanded.
+% The |\noexpand| macros below are needed to so that only the macro |\opt at group| is expanded. \changes{v1.0.3}{2021/11/03}{Added Tikz option}
% \begin{macrocode}
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{groupplot}[%
- bodeStyle,
- xmin={#3},
- xmax={#4},
- domain=#3:#4,
- height=2.5cm,
- xmode=log,
- group style = {group size = 1 by 2,vertical sep=0.25cm,},
- \opt at group,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{groupplot}[%
+ bodeStyle,
+ xmin={#3},
+ xmax={#4},
+ domain=#3:#4,
+ height=2.5cm,
+ xmode=log,
+ group style = {group size = 1 by 2,vertical sep=0.25cm},
+ \opt at group
+ ]%
+ }%
\temp at cmd
% \end{macrocode}
% To ensure frequency tick marks on magnitude and the phase plots are always aligned, we use the |groupplot| library. The |\expandafter| chain below is used to expand macros in the plot and group optional arguments.
% \begin{macrocode}
- \if at pgfarg
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd {\func at mag};
- \optmag at commands;
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd {\func at ph};
- \optph at commands;
- \else
+ \if at pgfarg
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd {\func at mag};
+ \optmag at commands;
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd {\func at ph};
+ \optph at commands;
+ \else
% \end{macrocode}
% In |gnuplot| mode, we increment the |idGnuplot| counter before every plot to make sure that new and reusable |.gnuplot| and |.table| files are generated for every plot.
% \begin{macrocode}
- \stepcounter{idGnuplot}
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
- \optmag at commands;
- \stepcounter{idGnuplot}
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
- \optph at commands;
- \fi
- \end{groupplot}\end{tikzpicture}
+ \stepcounter{idGnuplot}
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
+ \optmag at commands;
+ \stepcounter{idGnuplot}
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
+ \optph at commands;
+ \fi
+ \end{groupplot}
+ \end{tikzpicture}
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\BodeTF}
-% Implementation of this macro is very similar to the |\BodeZPK| macro above. The only difference is the lack of linear and asymptotic plots and slightly different parsing of the mandatory arguments.
+% Implementation of this macro is very similar to the |\BodeZPK| macro above. The only difference is the lack of linear and asymptotic plots and slightly different parsing of the mandatory arguments. \changes{v1.0.3}{2021/11/03}{Added Tikz option}
% \begin{macrocode}
\newcommand{\BodeTF}[4][]{%
\parse at opt{#1}%
@@ -808,42 +815,46 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{groupplot}[%
- bodeStyle,
- xmin={#3},
- xmax={#4},
- domain=#3:#4,
- height=2.5cm,
- xmode=log,
- group style = {group size = 1 by 2,vertical sep=0.25cm,},
- \opt at group,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{groupplot}[%
+ bodeStyle,
+ xmin={#3},
+ xmax={#4},
+ domain=#3:#4,
+ height=2.5cm,
+ xmode=log,
+ group style = {group size = 1 by 2,vertical sep=0.25cm},
+ \opt at group
+ ]%
+ }%
\temp at cmd
- \if at pgfarg
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd {\func at mag};
- \optmag at commands;%
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd {\func at ph};
- \optph at commands;%
- \else
- \stepcounter{idGnuplot}%
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
- \optmag at commands;%
- \stepcounter{idGnuplot}%
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
- \optph at commands;%
- \fi
- \end{groupplot}\end{tikzpicture}
+ \if at pgfarg
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd {\func at mag};
+ \optmag at commands;
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd {\func at ph};
+ \optph at commands;
+ \else
+ \stepcounter{idGnuplot}%
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
+ \optmag at commands;
+ \stepcounter{idGnuplot}%
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
+ \optph at commands;
+ \fi
+ \end{groupplot}
+ \end{tikzpicture}
}
% \end{macrocode}
% \end{macro}
@@ -905,11 +916,12 @@
% \end{macrocode}
%\end{macro}
% \begin{environment}{BodePlot}
-% An environment to host macros that pass parametric functions to |\addplot| macros. Uses the defaults specified in |bodeStyle| to create a shortcut that includes the |tikzpicture| and |semilogaxis| environments.
+% An environment to host macros that pass parametric functions to |\addplot| macros. Uses the defaults specified in |bodeStyle| to create a shortcut that includes the |tikzpicture| and |semilogaxis| environments. \changes{v1.0.3}{2021/11/03}{Added tikz option to environments}
% \begin{macrocode}
\newenvironment{BodePlot}[3][]{%
- \begin{tikzpicture}
- \begin{semilogxaxis}[%
+ \parse at env@opt{#1}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]
+ \noexpand\begin{semilogxaxis}[%
bodeStyle,
xmin={#2},
xmax={#3},
@@ -916,9 +928,12 @@
domain=#2:#3,
height=2.5cm,
xlabel={Frequency (rad/s)},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
}{
- \end{semilogxaxis}
+ \end{semilogxaxis}
\end{tikzpicture}
}
% \end{macrocode}
@@ -1075,7 +1090,7 @@
% \end{macrocode}
%\end{macro}
% \begin{macro}{\parse at opt}
-% Parses options supplied to the main Bode macros. A |for| loop over tuples of the form |\obj/\typ/\opt| with a long list of nested if-else statements does the job. The input |\obj| is either |plot|, |axes|, |group| or |approx|, and the corresponding |\opt| are passed to the |\addplot| macro, the |\nextgroupplot| macro, the |groupplot| environment, and the |\build at ZPK@plot| macros, respectively. The input tuples should not contain any macros that need to be passed to respective |pgf| macros unexpanded. If an input tuple needs to contain such a macro, the |\xdef| macros below need to be defined using |\unexpanded\expandafter{\opt}| instead of just |\opt|. For example, the |\parse at N@opt| macro in Section \ref{sec:NInternal} can pass macros in its arguments, unexpanded, to |pgf| plot macros and environments, which is useful, for example, when the user wishes to add direction arrows to Nyquist plots. I did not think such a use case would be encountered when plotting Bode plots.
+% Parses options supplied to the main Bode macros. A |for| loop over tuples of the form |\obj/\typ/\opt| with a long list of nested if-else statements does the job. If the input |\obj| is |plot|, |axes|, |group|, |approx|, or |tikz| the corresponding |\opt| are passed, unexpanded, to the |\addplot| macro, the |\nextgroupplot| macro, the |groupplot| environment, the |\build at ZPK@plot| macro, and the |tikzpicture| environment, respectively. If |\obj| is |commands|, the corresponding |\opt| are stored, unexpanded, in the macros |\optph at commands| and |\optmag at commands|, to be executed in appropriate |axis| environments. \changes{v1.0.3}{2021/11/03}{Added Tikz option}
% \begin{macrocode}
\newcommand{\parse at opt}[1]{%
\gdef\optmag at axes{}%
@@ -1084,38 +1099,39 @@
\gdef\optmag at plot{}%
\gdef\opt at group{}%
\gdef\opt at approx{}%
- \xdef\optph at commands{}%
- \xdef\optmag at commands{}%
+ \gdef\optph at commands{}%
+ \gdef\optmag at commands{}%
+ \gdef\opt at tikz{}%
\foreach \obj/\typ/\opt in {#1} {%
\ifnum\pdfstrcmp{\obj}{plot}=0
\ifnum\pdfstrcmp{\typ}{mag}=0
- \xdef\optmag at plot{\optmag at plot,\opt}%
+ \xdef\optmag at plot{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\typ}{ph}=0
- \xdef\optph at plot{\optph at plot,\opt}%
+ \xdef\optph at plot{\unexpanded\expandafter{\opt}}%
\else
- \xdef\optmag at plot{\optmag at plot,\opt}%
- \xdef\optph at plot{\optph at plot,\opt}%
+ \xdef\optmag at plot{\unexpanded\expandafter{\opt}}%
+ \xdef\optph at plot{\unexpanded\expandafter{\opt}}%
\fi
\fi
\else
\ifnum\pdfstrcmp{\obj}{axes}=0
\ifnum\pdfstrcmp{\typ}{mag}=0
- \xdef\optmag at axes{\optmag at axes,\opt}%
+ \xdef\optmag at axes{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\typ}{ph}=0
- \xdef\optph at axes{\optph at axes,\opt}%
+ \xdef\optph at axes{\unexpanded\expandafter{\opt}}%
\else
- \xdef\optmag at axes{\optmag at axes,\opt}%
- \xdef\optph at axes{\optph at axes,\opt}%
+ \xdef\optmag at axes{\unexpanded\expandafter{\opt}}%
+ \xdef\optph at axes{\unexpanded\expandafter{\opt}}%
\fi
\fi
\else
\ifnum\pdfstrcmp{\obj}{group}=0
- \xdef\opt at group{\opt at group,\opt}%
+ \xdef\opt at group{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\obj}{approx}=0
- \xdef\opt at approx{\opt}%
+ \xdef\opt at approx{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\obj}{commands}=0
\ifnum\pdfstrcmp{\typ}{phase}=0
@@ -1124,8 +1140,12 @@
\xdef\optmag at commands{\unexpanded\expandafter{\opt}}%
\fi
\else
- \xdef\optmag at plot{\optmag at plot,\obj}%
- \xdef\optph at plot{\optph at plot,\obj}%
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\optmag at plot{\optmag at plot,\unexpanded\expandafter{\obj}}%
+ \xdef\optph at plot{\optph at plot,\unexpanded\expandafter{\obj}}%
+ \fi
\fi
\fi
\fi
@@ -1135,10 +1155,30 @@
}
% \end{macrocode}
%\end{macro}
+% \begin{macro}{\parse at env@opt}
+% Parses options supplied to the Bode, Nyquist, and Nichols environments. A |for| loop over tuples of the form |\obj/\opt|, processed using nested if-else statements does the job. The input |\obj| should either be |axes| or |tikz|, and the corresponding |\opt| are passed, unexpanded, to the |axis| environment and the |tikzpicture| environment, respectively. \changes{v1.0.3}{2021/11/03}{Added tikz option to environments}
+% \begin{macrocode}
+\newcommand{\parse at env@opt}[1]{%
+ \gdef\opt at axes{}%
+ \gdef\opt at tikz{}%
+ \foreach \obj/\opt in {#1} {%
+ \ifnum\pdfstrcmp{\obj}{axes}=0
+ \xdef\opt at axes{\unexpanded\expandafter{\opt}}%
+ \else
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\opt at axes{\opt at axes,\unexpanded\expandafter{\obj}}%
+ \fi
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
% \subsection{Nyquist plots}
% \subsubsection{User macros}
% \begin{macro}{\NyquistZPK}
-% Converts magnitude and phase parametric functions built using |\build at ZPK@plot| into real part and imaginary part parametric functions. A plot of these is the Nyquist plot. The parametric functions are then plotted in a |tikzpicture| environment using the |\addplot| macro. Unless the package is loaded with the option |pgf|, the parametric functions are evaluated using |gnuplot|. A large number of samples is typically needed to get a smooth plot because frequencies near 0 result in plot points that are very close to each other. Linear frequency sampling is unnecessarily fine near zero and very coarse for large $\omega$. Logarithmic sampling makes it worse, perhaps inverse logarithmic sampling will help, merge requests are welcome!
+% Converts magnitude and phase parametric functions built using |\build at ZPK@plot| into real part and imaginary part parametric functions. A plot of these is the Nyquist plot. The parametric functions are then plotted in a |tikzpicture| environment using the |\addplot| macro. Unless the package is loaded with the option |pgf|, the parametric functions are evaluated using |gnuplot|. A large number of samples is typically needed to get a smooth plot because frequencies near 0 result in plot points that are very close to each other. Linear frequency sampling is unnecessarily fine near zero and very coarse for large $\omega$. Logarithmic sampling makes it worse, perhaps inverse logarithmic sampling will help, pull requests to fix that are welcome! \changes{v1.0.3}{2021/11/03}{Added commands and tikz options}
% \begin{macrocode}
\newcommand{\NyquistZPK}[4][]{%
\parse at N@opt{#1}%
@@ -1145,14 +1185,17 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={$\Re$},
- ylabel={$\Im$},
- samples=500,
- \opt at axes,]}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={$\Re$},
+ ylabel={$\Im$},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
\edef\temp at cmd{\noexpand\addplot[thick,\unexpanded\expandafter{\opt at plot}]}%
@@ -1159,11 +1202,13 @@
\if at pgfarg
\temp at cmd ( {\n at pow{10}{((\func at mag)/20)}*cos(\func at ph)},
{\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric,gnuplot degrees,gnuplot def] {%
\n at pow{10}{((\func at mag)/20)}*cos(\func at ph),
\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)};
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -1171,7 +1216,7 @@
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NyquistTF}
-% Implementation of this macro is very similar to the |\NyquistZPK| macro above. The only difference is a slightly different parsing of the mandatory arguments via |\build at TF@plot|.
+% Implementation of this macro is very similar to the |\NyquistZPK| macro above. The only difference is a slightly different parsing of the mandatory arguments via |\build at TF@plot|. \changes{v1.0.3}{2021/11/03}{Added commands and tikz options}
% \begin{macrocode}
\newcommand{\NyquistTF}[4][]{%
\parse at N@opt{#1}%
@@ -1178,14 +1223,17 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={$\Re$},
- ylabel={$\Im$},
- samples=500,
- \opt at axes,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={$\Re$},
+ ylabel={$\Im$},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
\edef\temp at cmd{\noexpand\addplot[thick,\unexpanded\expandafter{\opt at plot}]}%
@@ -1192,11 +1240,13 @@
\if at pgfarg
\temp at cmd ( {\n at pow{10}{((\func at mag)/20)}*cos(\func at ph)},
{\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric,gnuplot degrees,gnuplot def]{%
\n at pow{10}{((\func at mag)/20)}*cos(\func at ph),
\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)};
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -1242,17 +1292,21 @@
% \end{macrocode}
%\end{macro}
%\begin{macro}{NyquistPlot}
-% An environment to host |\addNyquist...| macros that pass parametric functions to |\addplot|. Uses the defaults specified in |bodeStyle| to create a shortcut that includes the |tikzpicture| and |axis| environments.
+% An environment to host |\addNyquist...| macros that pass parametric functions to |\addplot|. Uses the defaults specified in |bodeStyle| to create a shortcut that includes the |tikzpicture| and |axis| environments. \changes{v1.0.3}{2021/11/03}{Added tikz option to environments}
% \begin{macrocode}
\newenvironment{NyquistPlot}[3][]{%
- \begin{tikzpicture}
- \begin{axis}[%
+\parse at env@opt{#1}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
bodeStyle,
height=5cm,
domain=#2:#3,
xlabel={$\Re$},
ylabel={$\Im$},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
}{%
\end{axis}
@@ -1261,12 +1315,14 @@
% \end{macrocode}
%\end{macro}
% \subsubsection{Internal commands\label{sec:NInternal}}
-% \begin{macro}{\parse at opt}
-% Parses options supplied to the main Nyquist and Nichols macros. A |for| loop over tuples of the form |\obj/\opt|, processed using nested if-else statements does the job. The input |\obj| is either |plot| or |axes|, and the corresponding |\opt| are passed to the |\addplot| macro and the |axis| environment, respectively. If the input tuples contain macros, they are to be passed to respective |pgf| macros unexpanded.
+% \begin{macro}{\parse at N@opt}
+% Parses options supplied to the main Nyquist and Nichols macros. A |for| loop over tuples of the form |\obj/\opt|, processed using nested if-else statements does the job. If the input |\obj| is |plot|, |axes|, or |tikz| then the corresponding |\opt| are passed, unexpanded, to the |\addplot| macro, the |axis| environment, and the |tikzpicture| environment, respectively. \changes{v1.0.3}{2021/11/03}{Added commands and tikz options}
% \begin{macrocode}
\newcommand{\parse at N@opt}[1]{%
\gdef\opt at axes{}%
\gdef\opt at plot{}%
+ \gdef\opt at commands{}%
+ \gdef\opt at tikz{}
\foreach \obj/\opt in {#1} {%
\ifnum\pdfstrcmp{\obj}{axes}=0
\xdef\opt at axes{\unexpanded\expandafter{\opt}}%
@@ -1274,7 +1330,15 @@
\ifnum\pdfstrcmp{\obj}{plot}=0
\xdef\opt at plot{\unexpanded\expandafter{\opt}}%
\else
- \xdef\opt at plot{\unexpanded\expandafter{\obj}}%
+ \ifnum\pdfstrcmp{\obj}{commands}=0
+ \xdef\opt at commands{\unexpanded\expandafter{\opt}}%
+ \else
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\opt at plot{\opt at plot,\unexpanded\expandafter{\obj}}%
+ \fi
+ \fi
\fi
\fi
}%
@@ -1283,8 +1347,11 @@
% \end{macro}
% \subsection{Nichols charts}
% \begin{macro}{\NicholsZPK}
+% \changes{v1.0.3}{2021/11/03}{Added commands and tikz options}
% \begin{macro}{\NicholsTF}
+% \changes{v1.0.3}{2021/11/03}{Added commands and tikz options}
% \begin{macro}{NicholsChart}
+% \changes{v1.0.3}{2021/11/03}{Added tikz option to environments}
% \begin{macro}{\addNicholsZPKChart}
% \begin{macro}{\addNicholsTFChart}
% These macros and the |NicholsChart| environment generate Nichols charts, and they are implemented similar to their Nyquist counterparts.
@@ -1294,22 +1361,27 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={Phase (degrees)},
- ylabel={Gain (dB)},
- samples=500,
- \opt at axes]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={Phase (degrees)},
+ ylabel={Gain (dB)},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\edef\temp at cmd{\noexpand\addplot[thick,\opt at plot]}%
\if at pgfarg
\temp at cmd ( {\func at ph} , {\func at mag} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric, gnuplot degrees, gnuplot def]
{ \func at ph , \func at mag };
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -1319,29 +1391,34 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={Phase (degrees)},
- ylabel={Gain (dB)},
- samples=500,
- \opt at axes]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={Phase (degrees)},
+ ylabel={Gain (dB)},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\edef\temp at cmd{\noexpand\addplot[thick,\opt at plot]}%
\if at pgfarg
\temp at cmd ( {\func at ph} , {\func at mag} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric, gnuplot degrees, gnuplot def]
{ \func at ph , \func at mag };
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
}
\newenvironment{NicholsChart}[3][]{%
- \begin{tikzpicture}
- \begin{axis}[%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
bodeStyle,
domain=#2:#3,
height=5cm,
@@ -1349,7 +1426,10 @@
xtick distance=15,
xlabel={Phase (degrees)},
ylabel={Gain (dB)},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
}{
\end{axis}
\end{tikzpicture}
Modified: trunk/Master/texmf-dist/tex/latex/bodeplot/bodeplot.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/bodeplot/bodeplot.sty 2021-11-05 02:03:52 UTC (rev 60957)
+++ trunk/Master/texmf-dist/tex/latex/bodeplot/bodeplot.sty 2021-11-05 22:01:30 UTC (rev 60958)
@@ -43,7 +43,7 @@
\tikzset{%
gnuplot def/.style={%
id=\arabic{idGnuplot},
- prefix=gnuplot/
+ prefix=gnuplot/\jobname
}%
}
\pgfplotsset{%
@@ -172,42 +172,46 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{\opt at approx}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{groupplot}[%
- bodeStyle,
- xmin={#3},
- xmax={#4},
- domain=#3:#4,
- height=2.5cm,
- xmode=log,
- group style = {group size = 1 by 2,vertical sep=0.25cm,},
- \opt at group,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{groupplot}[%
+ bodeStyle,
+ xmin={#3},
+ xmax={#4},
+ domain=#3:#4,
+ height=2.5cm,
+ xmode=log,
+ group style = {group size = 1 by 2,vertical sep=0.25cm},
+ \opt at group
+ ]%
+ }%
\temp at cmd
- \if at pgfarg
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd {\func at mag};
- \optmag at commands;
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd {\func at ph};
- \optph at commands;
- \else
- \stepcounter{idGnuplot}
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
- \optmag at commands;
- \stepcounter{idGnuplot}
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
- \optph at commands;
- \fi
- \end{groupplot}\end{tikzpicture}
+ \if at pgfarg
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd {\func at mag};
+ \optmag at commands;
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd {\func at ph};
+ \optph at commands;
+ \else
+ \stepcounter{idGnuplot}
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
+ \optmag at commands;
+ \stepcounter{idGnuplot}
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
+ \optph at commands;
+ \fi
+ \end{groupplot}
+ \end{tikzpicture}
}
\newcommand{\BodeTF}[4][]{%
\parse at opt{#1}%
@@ -214,42 +218,46 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{groupplot}[%
- bodeStyle,
- xmin={#3},
- xmax={#4},
- domain=#3:#4,
- height=2.5cm,
- xmode=log,
- group style = {group size = 1 by 2,vertical sep=0.25cm,},
- \opt at group,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{groupplot}[%
+ bodeStyle,
+ xmin={#3},
+ xmax={#4},
+ domain=#3:#4,
+ height=2.5cm,
+ xmode=log,
+ group style = {group size = 1 by 2,vertical sep=0.25cm},
+ \opt at group
+ ]%
+ }%
\temp at cmd
- \if at pgfarg
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd {\func at mag};
- \optmag at commands;%
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd {\func at ph};
- \optph at commands;%
- \else
- \stepcounter{idGnuplot}%
- \expandafter\nextgroupplot\expandafter[ytick distance=20,
- ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
- \optmag at commands;%
- \stepcounter{idGnuplot}%
- \expandafter\nextgroupplot\expandafter[ytick distance=45,
- ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
- \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
- \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
- \optph at commands;%
- \fi
- \end{groupplot}\end{tikzpicture}
+ \if at pgfarg
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd {\func at mag};
+ \optmag at commands;
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd {\func at ph};
+ \optph at commands;
+ \else
+ \stepcounter{idGnuplot}%
+ \expandafter\nextgroupplot\expandafter[ytick distance=20,
+ ylabel={Gain (dB)},xmajorticks=false,\optmag at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optmag at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at mag};
+ \optmag at commands;
+ \stepcounter{idGnuplot}%
+ \expandafter\nextgroupplot\expandafter[ytick distance=45,
+ ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph at axes]
+ \edef\temp at cmd{\noexpand\addplot[thick,\optph at plot]}%
+ \temp at cmd gnuplot[gnuplot degrees,gnuplot def] {\func at ph};
+ \optph at commands;
+ \fi
+ \end{groupplot}
+ \end{tikzpicture}
}
\newcommand{\addBodeZPKPlots}[3][true/{}]{%
\foreach \approx/\opt in {#1} {%
@@ -294,8 +302,9 @@
\fi
}
\newenvironment{BodePlot}[3][]{%
- \begin{tikzpicture}
- \begin{semilogxaxis}[%
+ \parse at env@opt{#1}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]
+ \noexpand\begin{semilogxaxis}[%
bodeStyle,
xmin={#2},
xmax={#3},
@@ -302,9 +311,12 @@
domain=#2:#3,
height=2.5cm,
xlabel={Frequency (rad/s)},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
}{
- \end{semilogxaxis}
+ \end{semilogxaxis}
\end{tikzpicture}
}
\newcommand*{\add at feature}[3]{%
@@ -449,38 +461,39 @@
\gdef\optmag at plot{}%
\gdef\opt at group{}%
\gdef\opt at approx{}%
- \xdef\optph at commands{}%
- \xdef\optmag at commands{}%
+ \gdef\optph at commands{}%
+ \gdef\optmag at commands{}%
+ \gdef\opt at tikz{}%
\foreach \obj/\typ/\opt in {#1} {%
\ifnum\pdfstrcmp{\obj}{plot}=0
\ifnum\pdfstrcmp{\typ}{mag}=0
- \xdef\optmag at plot{\optmag at plot,\opt}%
+ \xdef\optmag at plot{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\typ}{ph}=0
- \xdef\optph at plot{\optph at plot,\opt}%
+ \xdef\optph at plot{\unexpanded\expandafter{\opt}}%
\else
- \xdef\optmag at plot{\optmag at plot,\opt}%
- \xdef\optph at plot{\optph at plot,\opt}%
+ \xdef\optmag at plot{\unexpanded\expandafter{\opt}}%
+ \xdef\optph at plot{\unexpanded\expandafter{\opt}}%
\fi
\fi
\else
\ifnum\pdfstrcmp{\obj}{axes}=0
\ifnum\pdfstrcmp{\typ}{mag}=0
- \xdef\optmag at axes{\optmag at axes,\opt}%
+ \xdef\optmag at axes{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\typ}{ph}=0
- \xdef\optph at axes{\optph at axes,\opt}%
+ \xdef\optph at axes{\unexpanded\expandafter{\opt}}%
\else
- \xdef\optmag at axes{\optmag at axes,\opt}%
- \xdef\optph at axes{\optph at axes,\opt}%
+ \xdef\optmag at axes{\unexpanded\expandafter{\opt}}%
+ \xdef\optph at axes{\unexpanded\expandafter{\opt}}%
\fi
\fi
\else
\ifnum\pdfstrcmp{\obj}{group}=0
- \xdef\opt at group{\opt at group,\opt}%
+ \xdef\opt at group{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\obj}{approx}=0
- \xdef\opt at approx{\opt}%
+ \xdef\opt at approx{\unexpanded\expandafter{\opt}}%
\else
\ifnum\pdfstrcmp{\obj}{commands}=0
\ifnum\pdfstrcmp{\typ}{phase}=0
@@ -489,8 +502,12 @@
\xdef\optmag at commands{\unexpanded\expandafter{\opt}}%
\fi
\else
- \xdef\optmag at plot{\optmag at plot,\obj}%
- \xdef\optph at plot{\optph at plot,\obj}%
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\optmag at plot{\optmag at plot,\unexpanded\expandafter{\obj}}%
+ \xdef\optph at plot{\optph at plot,\unexpanded\expandafter{\obj}}%
+ \fi
\fi
\fi
\fi
@@ -498,19 +515,37 @@
\fi
}%
}
+\newcommand{\parse at env@opt}[1]{%
+ \gdef\opt at axes{}%
+ \gdef\opt at tikz{}%
+ \foreach \obj/\opt in {#1} {%
+ \ifnum\pdfstrcmp{\obj}{axes}=0
+ \xdef\opt at axes{\unexpanded\expandafter{\opt}}%
+ \else
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\opt at axes{\opt at axes,\unexpanded\expandafter{\obj}}%
+ \fi
+ \fi
+ }%
+}
\newcommand{\NyquistZPK}[4][]{%
\parse at N@opt{#1}%
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={$\Re$},
- ylabel={$\Im$},
- samples=500,
- \opt at axes,]}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={$\Re$},
+ ylabel={$\Im$},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
\edef\temp at cmd{\noexpand\addplot[thick,\unexpanded\expandafter{\opt at plot}]}%
@@ -517,11 +552,13 @@
\if at pgfarg
\temp at cmd ( {\n at pow{10}{((\func at mag)/20)}*cos(\func at ph)},
{\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric,gnuplot degrees,gnuplot def] {%
\n at pow{10}{((\func at mag)/20)}*cos(\func at ph),
\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)};
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -531,14 +568,17 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={$\Re$},
- ylabel={$\Im$},
- samples=500,
- \opt at axes,]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={$\Re$},
+ ylabel={$\Im$},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
\edef\temp at cmd{\noexpand\addplot[thick,\unexpanded\expandafter{\opt at plot}]}%
@@ -545,11 +585,13 @@
\if at pgfarg
\temp at cmd ( {\n at pow{10}{((\func at mag)/20)}*cos(\func at ph)},
{\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric,gnuplot degrees,gnuplot def]{%
\n at pow{10}{((\func at mag)/20)}*cos(\func at ph),
\n at pow{10}{((\func at mag)/20)}*sin(\func at ph)};
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -583,14 +625,18 @@
\fi
}
\newenvironment{NyquistPlot}[3][]{%
- \begin{tikzpicture}
- \begin{axis}[%
+\parse at env@opt{#1}%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
bodeStyle,
height=5cm,
domain=#2:#3,
xlabel={$\Re$},
ylabel={$\Im$},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
\addplot [only marks,mark=+,thick,red] (-1 , 0);
}{%
\end{axis}
@@ -599,6 +645,8 @@
\newcommand{\parse at N@opt}[1]{%
\gdef\opt at axes{}%
\gdef\opt at plot{}%
+ \gdef\opt at commands{}%
+ \gdef\opt at tikz{}
\foreach \obj/\opt in {#1} {%
\ifnum\pdfstrcmp{\obj}{axes}=0
\xdef\opt at axes{\unexpanded\expandafter{\opt}}%
@@ -606,7 +654,15 @@
\ifnum\pdfstrcmp{\obj}{plot}=0
\xdef\opt at plot{\unexpanded\expandafter{\opt}}%
\else
- \xdef\opt at plot{\unexpanded\expandafter{\obj}}%
+ \ifnum\pdfstrcmp{\obj}{commands}=0
+ \xdef\opt at commands{\unexpanded\expandafter{\opt}}%
+ \else
+ \ifnum\pdfstrcmp{\obj}{tikz}=0
+ \xdef\opt at tikz{\unexpanded\expandafter{\opt}}%
+ \else
+ \xdef\opt at plot{\opt at plot,\unexpanded\expandafter{\obj}}%
+ \fi
+ \fi
\fi
\fi
}%
@@ -616,22 +672,27 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at ZPK@plot{\func at mag}{\func at ph}{}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={Phase (degrees)},
- ylabel={Gain (dB)},
- samples=500,
- \opt at axes]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={Phase (degrees)},
+ ylabel={Gain (dB)},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\edef\temp at cmd{\noexpand\addplot[thick,\opt at plot]}%
\if at pgfarg
\temp at cmd ( {\func at ph} , {\func at mag} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric, gnuplot degrees, gnuplot def]
{ \func at ph , \func at mag };
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
@@ -641,29 +702,34 @@
\gdef\func at mag{}%
\gdef\func at ph{}%
\build at TF@plot{\func at mag}{\func at ph}{#2}%
- \edef\temp at cmd{\noexpand\begin{tikzpicture}\noexpand\begin{axis}[%
- bodeStyle,
- domain=#3:#4,
- height=5cm,
- xlabel={Phase (degrees)},
- ylabel={Gain (dB)},
- samples=500,
- \opt at axes]}
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
+ bodeStyle,
+ domain=#3:#4,
+ height=5cm,
+ xlabel={Phase (degrees)},
+ ylabel={Gain (dB)},
+ samples=500,
+ \opt at axes
+ ]%
+ }%
\temp at cmd
\edef\temp at cmd{\noexpand\addplot[thick,\opt at plot]}%
\if at pgfarg
\temp at cmd ( {\func at ph} , {\func at mag} );
+ \opt at commands;
\else
\stepcounter{idGnuplot}%
\temp at cmd gnuplot[parametric, gnuplot degrees, gnuplot def]
{ \func at ph , \func at mag };
+ \opt at commands;
\fi
\end{axis}
\end{tikzpicture}
}
\newenvironment{NicholsChart}[3][]{%
- \begin{tikzpicture}
- \begin{axis}[%
+ \edef\temp at cmd{\noexpand\begin{tikzpicture}[\opt at tikz]%
+ \noexpand\begin{axis}[%
bodeStyle,
domain=#2:#3,
height=5cm,
@@ -671,7 +737,10 @@
xtick distance=15,
xlabel={Phase (degrees)},
ylabel={Gain (dB)},
- #1]
+ \opt at axes
+ ]%
+ }%
+ \temp at cmd
}{
\end{axis}
\end{tikzpicture}
More information about the tex-live-commits
mailing list.