2

So I am attempting to create some simple sudo random data and plot the results with a trend line. Best fit linear approximation. I am trying to create something that looks like the graph below

enter image description here

Here is what I have so far

enter image description here

Problems

  • I do not not know I can use axis y discontinuity=parallel in both directions to obtain the blue discontinuties.
  • My randomization of variables and plotting feels very convoluted

Short explanation

I got the following function

f(\T) = 1.08 * 10^10 * exp(-12667/\T)

From which I am trying to create some fictional experimental data that fits this equation (Arrhenius equation). Then I am trying to plot the data in a log plot with a linear regression. I do this as follows

\pgfmathsetmacro{\arrenhiusOneX}{int(2*random(300,305))}

\pgfkeys{/pgf/fpu}
  \pgfmathparse{f(\arrenhiusOneX)+2*rand}
  \edef\arrenhiusOneY{\pgfmathresult}
  \pgfmathparse{ln(\arrenhiusOneX)}
  \edef\arrenhiusOneYi{\pgfmathresult}
\pgfkeys{/pgf/fpu=false}

I manually add some noise on purpose. Because the values are too big, I have to use the fpu library. Then I put these points into a table

\pgfplotstableread{
X Y
{\arrenhiusZeroXi} {\arrenhiusZeroYi}
.
. 
.
}\datatable

From which I can create the linear fit line with.

\addplot [thick, red] table[
    y={create col/linear regression={y=Y}}
] % compute a linear regression from the input table
{\datatable};

However, as mentioned previously this feels convoluted.

Code

\documentclass[margin=5mm]{standalone}
\usepackage{mathtools}
\usepackage{xcolor}
\usepackage[version=4]{mhchem}
\usepackage{siunitx}
\usepackage{pgfplots, pgfplotstable}
    \pgfplotsset{
        compat=1.16,
        % declare your function here ...
        /pgf/declare function={
            f(\T) = 1.08 * 10^10 * exp(-12667/\T);
        },
    }
\pgfmathsetmacro{\arrenhiusZeroX}{592}
\pgfmathsetmacro{\arrenhiusOneX}{int(2*random(300,305))}
\pgfmathsetmacro{\arrenhiusTwoX}{int(2*random(310,315))}
\pgfmathsetmacro{\arrenhiusThreeX}{int(2*random(325,327))}
\pgfmathsetmacro{\arrenhiusFourX}{558}

\pgfmathsetmacro{\arrenhiusZeroXi}{1/\arrenhiusZeroX}
\pgfmathsetmacro{\arrenhiusOneXi}{1/\arrenhiusOneX}
\pgfmathsetmacro{\arrenhiusTwoXi}{1/\arrenhiusTwoX}
\pgfmathsetmacro{\arrenhiusThreeXi}{1/\arrenhiusThreeX}
\pgfmathsetmacro{\arrenhiusFourXi}{1/\arrenhiusFourX}

\pgfkeys{/pgf/fpu}
\pgfmathparse{f(\arrenhiusOneX)+2*rand}
\edef\arrenhiusOneY{\pgfmathresult}
\pgfmathparse{f(\arrenhiusTwoX)+2*rand}
\edef\arrenhiusTwoY{\pgfmathresult}
\pgfmathparse{f(\arrenhiusThreeX)+2*rand}
\edef\arrenhiusThreeY{\pgfmathresult}

\pgfmathparse{ln(\arrenhiusZeroX)}
\edef\arrenhiusZeroYi{\pgfmathresult}
\pgfmathparse{ln(\arrenhiusOneX)}
\edef\arrenhiusOneYi{\pgfmathresult}
\pgfmathparse{ln(\arrenhiusTwoX)}
\edef\arrenhiusTwoYi{\pgfmathresult}
\pgfmathparse{ln(\arrenhiusThreeX)}
\edef\arrenhiusThreeYi{\pgfmathresult}
\pgfmathparse{ln(\arrenhiusFourX)}
\edef\arrenhiusFourYi{\pgfmathresult}

\pgfkeys{/pgf/fpu=false}

\pgfplotstableread{
X Y
{\arrenhiusZeroXi} {\arrenhiusZeroYi}
{\arrenhiusOneXi} {\arrenhiusOneYi}
{\arrenhiusTwoXi} {\arrenhiusTwoYi}
{\arrenhiusThreeXi} {\arrenhiusThreeYi}
{\arrenhiusFourXi} {\arrenhiusFourYi}
}\datatable

\begin{document}

\begin{tikzpicture}
    \begin{axis}[
        title = {\ce{2NO2 -> 2NO + O2}},
        xlabel={1/T [\si{\per\kelvin}]},
        ylabel={ln(k [\SI{e-4}{\cm\cubed\per\mol\per\s}]})],
        minor x tick num=4,
        title = {\ce{2NO2 -> 2NO + O2}},
        xmin=0.0015, xmax=0.0017,
        ymin=0,ymax=4.5,
        ytick={0,0.5,...,4},
        minor grid style={black!25},
        major grid style={black},
        grid=both,
        minor y tick num=4,
        ylabel=Error]
\addplot [only marks,
    every mark/.append style={solid, fill=black},
    mark = square*] table {\datatable};
\addplot [thick, red] table[
    y={create col/linear regression={y=Y}}
] % compute a linear regression from the input table
{\datatable};
    \end{axis}
\end{tikzpicture}
\end{document}
N3buchadnezzar
  • 11,348
  • 7
  • 55
  • 114

1 Answers1

2

This is a partial answer, dealing only with the creation of the random numbers.

pgfplotstable lets you generate columns of N values based on mathematical expressions, including random numbers, so it's not necessary to define N * 4 macros. random(a,b) is not available though, but int(a + rnd * (b - a)) does the same (?). Note I've used a single random number expression for the X-values, instead of five different ones as you had in your example though, you'll have to decide yourself if that is a problem.

As I said this doesn't address the discontinuities. However, if the purpose of it is to show where the line intersects the y-axis, one option might be to just add a node containing that information. The value is available in \pgfplotstableregressionb. I added an example of that in the code, which is commented out.

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{mathtools}
\usepackage[version=4]{mhchem}
\usepackage{siunitx}
\usepackage{pgfplotstable}
    \pgfplotsset{
        compat=1.16,
        % declare your function here ...
        /pgf/declare function={
            f(\T) = 1.08 * 10^10 * exp(-12667/\T);
        },
    }

% random(a,b) is not available in this context, so use
% int(a + rnd * (b - a)) instead
\pgfplotstablenew[
  % create X-column
  create on use/X/.style={create col/expr={int(550+rnd*100)}},
  columns={X}
  ]{5} % number of rows
   {\datatable}

% then add the rest
\pgfplotstablecreatecol[create col/expr={1/\thisrow{X}}]{Xi}{\datatable}
\pgfplotstablecreatecol[create col/expr={f(\thisrow{X})+2*rand}]{Y}{\datatable}
\pgfplotstablecreatecol[create col/expr={ln(\thisrow{X})}]{Yi}{\datatable}
\pgfkeys{/pgf/fpu=false}
\begin{document}
%\pgfplotstabletypeset\datatable

\begin{tikzpicture}
    \begin{axis}[
        title = {\ce{2NO2 -> 2NO + O2}},
        xlabel={1/T [\si{\per\kelvin}]},
        ylabel={ln(k [\SI{e-4}{\cm\cubed\per\mol\per\s}])},
        ]

\addplot [only marks,
    every mark/.append style={solid, fill=black},
    mark = square*] table [x=Xi, y=Yi] {\datatable};
\addplot [thick, red] table[x=Xi,
    y={create col/linear regression={y=Yi}}
] % compute a linear regression from the input table
{\datatable};

   %\node [above right=2mm] at (current axis.south west) {Intersect: \num[round-mode=places,round-precision=2]{\pgfplotstableregressionb}};
   \end{axis}
\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688
  • Is it possible to shift each point according to the 2*rand? If all are shifted in the same direction, it moves the regression line – N3buchadnezzar May 11 '20 at 09:56
  • 1
    @N3buchadnezzar Not entirely sure I follow, but I guess just add +rand*2 in the expression for the Yi-column. I did add that in expression for the Y-column (which is not used), because I tried to do the same as your macros. – Torbjørn T. May 11 '20 at 10:06