# Janky pgfplot behaviour with arcsinh function

I'm trying to draw a titration curve using pgfplot. Based off this paper, there is an equation for the titration curve:

I've attempted to implement this within pgfplots, and I get a very strange result:

I have no idea why this would occur; even attempting to recreate the exact formula I used within desmos did not work.

For reference, here is the code, and also a link to an overleaf project.

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

\pgfkeys{
/pgf/declare function={
arcsinh(\x) = ln(\x + sqrt(\x^2+1));
},
/pgf/declare function={
Va = 0.025;
Ma = 0.1;
Mb = 0.1;
V(\x) = \x / 1000;
Kw = 1*10^(-14);
p(\o) = -ln(\o)/ln(10);
}
}

\begin{center}
\begin{tikzpicture}
\begin{axis}[
ylabel = {pH},
ymin=0,
ymax=14,
ytick distance=7,
xtick distance=10,
]
samples=100,
color=red,
domain=0:50,
]{%
7 + 1/ln(10) * arcsinh( 1/(2*sqrt(Kw))  *  (Mb*V(x) - Ma*Va) / (Va + V(x)) )
};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}


endnote: if there's a way I can have variables e.g. V_a within the pgfplot function, that'd be much nicer than having constants throughout. thanks Torjorn

• Welcome! Why are you using base 10 logarithms? Commented Sep 2, 2020 at 13:51
• You can use declare function for the variables as well. Commented Sep 2, 2020 at 14:08
• @egreg If you're referring to the division by ln(10) int the definition of arcsinh, it's just been shifted from outside to inside (if you look at the reference function it's outside). I don't think it makes any difference, and I've tried having it both ways. It just makes it easier to read imo, even if it's not strictly an arcsinh function anymore. Commented Sep 2, 2020 at 14:33
• @Modelmat That's what I wanted to underline: you know, a mathematician's hyperbolic sine uses e. ;-) Commented Sep 2, 2020 at 14:58
• BTW, are you getting a Dimension too large error? Commented Sep 3, 2020 at 3:29

One gets this strange result because TeXs limits are reached -- as can also be seen by the dropped coordinates -- and thus the "zigzag" results from precision limits (red line). If you use either gnuplot (green dots) or Lua (blue line) as calculation engine, it works as expected. Of course for the Lua solution you have to use LuaLaTeX as TeX engine.

Sidenote:
If you want to avoid to use such a high number of samples, consider reformulating the eqution to make use of non-linear spacing. For that see e.g.

% used PGFPlots v1.17
\documentclass[border={5pt}]{standalone}
\usepackage{pgfplots}
% use this compat level or higher to use LUA backend for calculation (if possible)
\pgfplotsset{compat=1.12}
\begin{document}
% for gnuplot solution
\newcommand*{\Kw}{1e-14}
\newcommand*{\Ma}{0.1}
\newcommand*{\Mb}{0.1}
\newcommand*{\Va}{0.025}
\begin{tikzpicture}[
% from https://tex.stackexchange.com/q/144778
/pgf/declare function={
% for LUA solution
arcsinh(\x) = ln(\x + sqrt(\x^2+1));
Kw = 1e-14;
Ma = 0.1;
Mb = 0.1;
Va = 0.025;
V(\x) = \x / 1000;
p(\o) = -0.5*ln(\o)/ln(10);
},
]
\begin{axis}[
ylabel={pH},
domain=0:50,
samples=201,
]
% gnuplot
\addplot+ [ultra thick,green,mark size=1pt,only marks,opacity=0.5] gnuplot
{-0.5*log10(\Kw) + asinh(1/(2*sqrt(\Kw)) * (\Ma*\Va - \Mb*x/1000)/(\Va + x/1000) )/log(10)};
% Lua(TeX)

• Thanks heaps! I'm unsure how replacing -0.5log10(K_w) with 7 would make the curve "incorrect"? K_w will always be what it is, and thus 0.5*pK_w will always be 7. Commented Sep 3, 2020 at 20:11
• You are right. I got distracted from just not using your definition of p ... I removed that comment. Commented Sep 4, 2020 at 9:15