Setting variables to random numbers for pgfplots

In the declare function scope, I am trying to set randomized numbers to variables, as shown in the code:

\documentclass[12pt]{article}
\usepackage{pgfplots}
\usepackage{float}
\pgfplotsset{compat=1.17}
\usepackage{tikz}
\usetikzlibrary{shapes, arrows.meta, automata, positioning, matrix, calc}
\usepackage[margin=1in]{geometry}
\usepackage{caption}
\usepackage{siunitx}
\begin{document}
\begin{figure}[H]
\centering
\captionsetup{skip = 5pt} %default is 10pt; I am doing this to make use of pages more efficient; if I didn't do this, then some figures would go onto the next page, and leave a lot of space at the end of the current page
\pgfplotsset{grid style={dashed,gray}} %Both grids for this figure ONLY
\definecolor{mycolor1}{rgb}{0.00000,0.44700,0.74100}%
\definecolor{mycolor2}{rgb}{0.85000,0.32500,0.09800}%
\definecolor{mycolor3}{rgb}{0.92900,0.69400,0.12500}%
\begin{tikzpicture}[trim axis left, trim axis right,
declare function = {
R1Nom = 20566;
R2Nom = R1Nom;
R3Nom = 8227;
LNom = 1;
CNom = 0.1*10^{-6};
\pgfmathsetseed{2}%Setting the seed
\pgfmathparse{0.8 + 0.4*rnd}
R1Rand1 = R1Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R2Rand1 = R2Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R3Rand1 = R3Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
LRand1 = LNom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
CRand1 = CNom*\pgfmathresult;
RthRand1 = R1Rand1*R2Rand1/(R1Rand1 + R2Rand1);
KRand1 = R3Rand1*R2Rand1/((R1Rand1 + R2Rand1)*(R3Rand1 + RthRand1));
\pgfmathparse{0.8 + 0.4*rnd}
R1Rand2 = R1Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R2Rand2 = R2Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R3Rand2 = R3Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
LRand2 = LNom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
CRand2 = CNom*\pgfmathresult;
RthRand2 = R1Rand2*R2Rand2/(R1Rand2 + R2Rand2);
KRand2 = R3Rand2*R2Rand2/((R1Rand2 + R2Rand2)*(R3Rand2 + RthRand2));
\pgfmathparse{0.8 + 0.4*rnd}
R1Rand3 = R1Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R2Rand3 = R2Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
R3Rand3 = R3Nom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
LRand3 = LNom*\pgfmathresult;
\pgfmathparse{0.8 + 0.4*rnd}
CRand3 = CNom*\pgfmathresult;
RthRand3 = R1Rand3*R2Rand3/(R1Rand3 + R2Rand3);
KRand3 = R3Rand3*R2Rand3/((R1Rand3 + R2Rand3)*(R3Rand3 + RthRand3));
}
]
\begin{semilogxaxis}[
width=12cm,
height=12cm,
%scale only axis, this command allows dimension of the axes to match up with the specified dimensions i.e. width and height; if not placed there, then the bounding box (which include tick marks, labels, etc) will be set to those dimensions
xlabel={$\omega$ ($\SI[per-mode = symbol]{}{\radian\per\second}$)},
ylabel={Ampltitude ($\SI{}{\decibel}$)},
grid=both,
xmin = 10^0, xmax=10^6,
ymin = -110, ymax=-10,
samples=1000]
\addplot [mycolor1, thick, domain = 1:10^6] {20*log10(KRand1/sqrt((1 - x^2*(LRand1*CRand1*R3Rand1/(R3Rand1 + RthRand1)))^2 + x^2*(LRand1 + CRand1*R3Rand1*RthRand1)^2/(R3Rand1 + RthRand1)^2))};
\addplot [mycolor2, thick, domain = 1:10^6] {20*log10(KRand2/sqrt((1 - x^2*(LRand2*CRand2*R3Rand2/(R3Rand2 + RthRand2)))^2 + x^2*(LRand2 + CRand2*R3Rand2*RthRand2)^2/(R3Rand2 + RthRand2)^2))};
\addplot [mycolor3, thick, domain = 1:10^6] {20*log10(KRand3/sqrt((1 - x^2*(LRand3*CRand3*R3Rand3/(R3Rand3 + RthRand3)))^2 + x^2*(LRand3 + CRand3*R3Rand3*RthRand3)^2/(R3Rand3 + RthRand3)^2))};
\end{semilogxaxis}
\end{tikzpicture}
\caption{This plot.}
\end{figure}
\end{document}


However, I am getting an error relating to pgfmath saying: Package PGF Math Error: Unknown operator =' or =@' (in '='). ]

What is the proper way of using a random number generator in declare function?

You cannot put \pgfmathparse into declare function. Moreover, CNom = 0.1*10^{-6}; is incorrect, but e.g.  CNom = 0.1*10^(-6); works. You probably want to use one constant random per variable, so the perhaps easiest way is to store those in macros.

\documentclass[12pt]{article}
\usepackage{pgfplots}
\usepackage{float}
\pgfplotsset{compat=1.17}
\usepackage[margin=1in]{geometry}
\usepackage{caption}
\usepackage{siunitx}
\begin{document}
\begin{figure}[H]
\centering
\captionsetup{skip = 5pt} %default is 10pt; I am doing this to make use of pages more efficient; if I didn't do this, then some figures would go onto the next page, and leave a lot of space at the end of the current page
\pgfplotsset{grid style={dashed,gray}} %Both grids for this figure ONLY
\definecolor{mycolor1}{rgb}{0.00000,0.44700,0.74100}%
\definecolor{mycolor2}{rgb}{0.85000,0.32500,0.09800}%
\definecolor{mycolor3}{rgb}{0.92900,0.69400,0.12500}%
\begin{tikzpicture}[trim axis left, trim axis right,
declare function={myrnd=0.8 + 0.4*rnd;}]
\pgfmathsetseed{2}%Setting the seed
\pgfmathsetmacro{\rndA}{myrnd}
\pgfmathsetmacro{\rndB}{myrnd}
\pgfmathsetmacro{\rndC}{myrnd}
\pgfmathsetmacro{\rndD}{myrnd}
\pgfmathsetmacro{\rndE}{myrnd}
\pgfmathsetmacro{\rndF}{myrnd}
\pgfmathsetmacro{\rndG}{myrnd}
\pgfmathsetmacro{\rndH}{myrnd}
\pgfmathsetmacro{\rndI}{myrnd}
\pgfmathsetmacro{\rndJ}{myrnd}
\pgfmathsetmacro{\rndK}{myrnd}
\pgfmathsetmacro{\rndL}{myrnd}
\pgfmathsetmacro{\rndM}{myrnd}
\pgfmathsetmacro{\rndN}{myrnd}
\begin{semilogxaxis}[ declare function = {
R1Nom = 20566;
R2Nom = R1Nom;
R3Nom = 8227;
LNom = 1;
CNom = 0.1*10^(-6);
R1Rand1 = R1Nom*\rndA;
R2Rand1 = R2Nom*\rndB;
R3Rand1 = R3Nom*\rndC;
LRand1 = LNom*\rndD;
CRand1 = CNom*\rndE;
RthRand1 = R1Rand1*R2Rand1/(R1Rand1 + R2Rand1);
KRand1 = R3Rand1*R2Rand1/((R1Rand1 + R2Rand1)*(R3Rand1 + RthRand1));
R1Rand2 = R1Nom*\rndF;
R2Rand2 = R2Nom*\rndF;
R3Rand2 = R3Nom*\rndG;
LRand2 = LNom*\rndH;
CRand2 = CNom*\rndI;
RthRand2 = R1Rand2*R2Rand2/(R1Rand2 + R2Rand2);
KRand2 = R3Rand2*R2Rand2/((R1Rand2 + R2Rand2)*(R3Rand2 + RthRand2));
R1Rand3 = R1Nom*\rndJ;
R2Rand3 = R2Nom*\rndK;
R3Rand3 = R3Nom*\rndL;
LRand3 = LNom*\rndM;
CRand3 = CNom*\rndN;
RthRand3 = R1Rand3*R2Rand3/(R1Rand3 + R2Rand3);
KRand3 = R3Rand3*R2Rand3/((R1Rand3 + R2Rand3)*(R3Rand3 + RthRand3));
},
width=12cm,
height=12cm,
%scale only axis, this command allows dimension of the axes to match up with the specified dimensions i.e. width and height; if not placed there, then the bounding box (which include tick marks, labels, etc) will be set to those dimensions
xlabel={$\omega$ ($\SI[per-mode = symbol]{}{\radian\per\second}$)},
ylabel={Ampltitude ($\SI{}{\decibel}$)},
grid=both,
xmin = 10^0, xmax=10^6,
ymin = -110, ymax=-10,
samples=101]
\addplot [mycolor1, thick, domain = 1:10^6] {20*log10(KRand1/sqrt((1 - x^2*(LRand1*CRand1*R3Rand1/(R3Rand1 + RthRand1)))^2 + x^2*(LRand1 + CRand1*R3Rand1*RthRand1)^2/(R3Rand1 + RthRand1)^2))};
\addplot [mycolor2, thick, domain = 1:10^6] {20*log10(KRand2/sqrt((1 - x^2*(LRand2*CRand2*R3Rand2/(R3Rand2 + RthRand2)))^2 + x^2*(LRand2 + CRand2*R3Rand2*RthRand2)^2/(R3Rand2 + RthRand2)^2))};
\addplot [mycolor3, thick, domain = 1:10^6] {20*log10(KRand3/sqrt((1 - x^2*(LRand3*CRand3*R3Rand3/(R3Rand3 + RthRand3)))^2 + x^2*(LRand3 + CRand3*R3Rand3*RthRand3)^2/(R3Rand3 + RthRand3)^2))};
\end{semilogxaxis}
\end{tikzpicture}
\caption{This plot.}
\end{figure}
\end{document}


You can shorten this using a \loop.

\documentclass[12pt]{article}
\usepackage{pgfplots}
\usepackage{float}
\pgfplotsset{compat=1.17}
\usepackage[margin=1in]{geometry}
\usepackage{caption}
\usepackage{siunitx}
\newcounter{iloop}
\begin{document}
\begin{figure}[H]
\centering
\captionsetup{skip = 5pt} %default is 10pt; I am doing this to make use of pages more efficient; if I didn't do this, then some figures would go onto the next page, and leave a lot of space at the end of the current page
\pgfplotsset{grid style={dashed,gray}} %Both grids for this figure ONLY
\definecolor{mycolor1}{rgb}{0.00000,0.44700,0.74100}%
\definecolor{mycolor2}{rgb}{0.85000,0.32500,0.09800}%
\definecolor{mycolor3}{rgb}{0.92900,0.69400,0.12500}%
\begin{tikzpicture}[trim axis left, trim axis right,
declare function={myrnd=0.8 + 0.4*rnd;}]
\pgfmathsetseed{2}%Setting the seed
\setcounter{iloop}{0}
\loop
\stepcounter{iloop}
\pgfmathparse{myrnd}
\expandafter\edef\csname rnd\Alph{iloop}\endcsname{\pgfmathresult}
\ifnum\value{iloop}<14
\repeat
\begin{semilogxaxis}[ declare function = {
R1Nom = 20566;
R2Nom = R1Nom;
R3Nom = 8227;
LNom = 1;
CNom = 0.1*10^(-6);
R1Rand1 = R1Nom*\rndA;
R2Rand1 = R2Nom*\rndB;
R3Rand1 = R3Nom*\rndC;
LRand1 = LNom*\rndD;
CRand1 = CNom*\rndE;
RthRand1 = R1Rand1*R2Rand1/(R1Rand1 + R2Rand1);
KRand1 = R3Rand1*R2Rand1/((R1Rand1 + R2Rand1)*(R3Rand1 + RthRand1));
R1Rand2 = R1Nom*\rndF;
R2Rand2 = R2Nom*\rndF;
R3Rand2 = R3Nom*\rndG;
LRand2 = LNom*\rndH;
CRand2 = CNom*\rndI;
RthRand2 = R1Rand2*R2Rand2/(R1Rand2 + R2Rand2);
KRand2 = R3Rand2*R2Rand2/((R1Rand2 + R2Rand2)*(R3Rand2 + RthRand2));
R1Rand3 = R1Nom*\rndJ;
R2Rand3 = R2Nom*\rndK;
R3Rand3 = R3Nom*\rndL;
LRand3 = LNom*\rndM;
CRand3 = CNom*\rndN;
RthRand3 = R1Rand3*R2Rand3/(R1Rand3 + R2Rand3);
KRand3 = R3Rand3*R2Rand3/((R1Rand3 + R2Rand3)*(R3Rand3 + RthRand3));
},
width=12cm,
height=12cm,
%scale only axis, this command allows dimension of the axes to match up with the specified dimensions i.e. width and height; if not placed there, then the bounding box (which include tick marks, labels, etc) will be set to those dimensions
xlabel={$\omega$ ($\SI[per-mode = symbol]{}{\radian\per\second}$)},
ylabel={Ampltitude ($\SI{}{\decibel}$)},
grid=both,
xmin = 10^0, xmax=10^6,
ymin = -110, ymax=-10,
samples=101]
\addplot [mycolor1, thick, domain = 1:10^6] {20*log10(KRand1/sqrt((1 - x^2*(LRand1*CRand1*R3Rand1/(R3Rand1 + RthRand1)))^2 + x^2*(LRand1 + CRand1*R3Rand1*RthRand1)^2/(R3Rand1 + RthRand1)^2))};
\addplot [mycolor2, thick, domain = 1:10^6] {20*log10(KRand2/sqrt((1 - x^2*(LRand2*CRand2*R3Rand2/(R3Rand2 + RthRand2)))^2 + x^2*(LRand2 + CRand2*R3Rand2*RthRand2)^2/(R3Rand2 + RthRand2)^2))};
\addplot [mycolor3, thick, domain = 1:10^6] {20*log10(KRand3/sqrt((1 - x^2*(LRand3*CRand3*R3Rand3/(R3Rand3 + RthRand3)))^2 + x^2*(LRand3 + CRand3*R3Rand3*RthRand3)^2/(R3Rand3 + RthRand3)^2))};
\end{semilogxaxis}
\end{tikzpicture}
\caption{This plot.}
\end{figure}
\end{document}

• Hmmm interesting, I didn’t know about not using pgfmathparse in the declare function scope, and I must have been silly in the exponent part. Thank you so much! Jun 18 '20 at 4:49
• On a side note, as I see, calling myrnd generates a different random number each time. So far, I have used declare function for calling constants. Are there other examples of using declare function and getting different things besides rnd e.g. passing in parameters like x and returning exp(x)? Jun 18 '20 at 4:53
• @Superman Yes, you can do declare function={f(\x)=exp(\x);} and then plot f(x) (or f(x)). The function can have up to nine variables. (More variables are possible but one has to do that differently.)
– user194703
Jun 18 '20 at 4:56
• @Superman This creates macros \rndA, \rndB and so on. We need first to "bake" the macro and then to use \edef, hence \expandafter.
– user194703
Jun 18 '20 at 5:03
• @Superman Yes, "bake" means create. I think this is a nice resource for that.
– user194703
Jun 18 '20 at 5:09