[Tex/LaTex] Symlog as axis scaling in PGFPlots

axispgfplotstikz-pgf

I'm new to TikZ plotting. :)

I want to plot data from a CSV with pgfplots in an axis environment.
The data has a quite large range, for which a linear y-axis isn't very appropriate. In Python's matplotlib is a scaling called symlog (for symmetric log: A mirrored log scale around the x-axis), which also allows negative values (e.g., a range from -(10^5) to 10^5)
Since ymode=symlog doesn't work, is there any other way to create symlog-like plots?

My code is equivalent to (works only for the positive values):

\begin{tikzpicture}
\begin{axis}[
    xmode=linear,
    ymode=log,
    xlabel=$f$ (Hz),
    ylabel=$T$ (-),
    title={Measured transfer function of analogue filter},
    grid=both,
    minor grid style={gray!25},
    major grid style={gray!25},
    width=0.75\linewidth,
    no marks]
\addplot[line width=1pt,solid,color=blue] %
    coordinates {(0,-1000) (1,-100) (2,-10) (3,-1) (4,0) (5,1) (6,10) (7,100) (8,1000)};
\addlegendentry{Transfer function};
\end{axis}
\end{tikzpicture}

Source: https://olivierpieters.be/blog/2015/10/23/latex-plotting-from-file.html

Edit:

The result is:

enter image description here

But for coordinates {(0,-1000) (1,-100) (2,-10) (3,-1) (4,0) (5,1) (6,10) (7,100) (8,1000)}; the plot should look like (the scaling between -1 and +1 is linear):

enter image description here

Best Answer

Here we go, using the y coord trafo key from pgfplots.

The symlog function is defined using the tikzmath.

It is the function enter image description here

For some reason, I can't seem to be able to plot a tikzmath function including if conditionals with pgfplots, hence the clumsiness of the symlog internals.

We also define the inverse transform symexp and feed it to the y coord inv trafo key, to be able to use the axis coordinate system.

It is the function enter image description here

The code

producing the following output :

enter image description here

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{math}
\tikzmath
{
  function symlog(\x,\a){
    \yLarge = ((\x>\a) - (\x<-\a)) * (ln(max(abs(\x/\a),1)) + 1);
    \ySmall = (\x >= -\a) * (\x <= \a) * \x / \a ;
    return \yLarge + \ySmall ;
  };
  function symexp(\y,\a){
    \xLarge = ((\y>1) - (\y<-1)) * \a * exp(abs(\y) - 1) ;
    \xSmall = (\y>=-1) * (\y<=1) * \a * \y ;
    return \xLarge + \xSmall ;
  };
}
\begin{document}
\begin{tikzpicture}
  \def\basis{1}
  \pgfplotsset
  {
    y coord trafo/.code={\pgfmathparse{symlog(#1,\basis)}\pgfmathresult},
    y coord inv trafo/.code={\pgfmathparse{symexp(#1,\basis)}\pgfmathresult},
    yticklabel style={/pgf/number format/.cd,int detect,precision=2},
}
  \begin{axis}
    [
      height=12cm,
      legend pos=north west,
      scaled ticks = base 10:0,
      domain = -5:5.5,
      ytick = {-100,-10, -1,0,1,10,100},
      minor ytick = {-90,-80,...,-20,-9,-8,...,-2,-.9,-.8,...,.9,2,3,...,9,20,30,...,90},
      tick label style = {fill=white, fill opacity=.7},
      yminorgrids = true,
      ymajorgrids = true,
      xmajorgrids = true,
      samples=200,
      axis lines=center,
    ]
    \addplot+ [mark=none] {x} ;
    \addplot+ [mark=none] {exp(x)} ;
    \addplot+ [mark=none] {-exp(-x)} ;
    \legend {$x$,$e^x$,$-e^{-x}$}
  \end{axis}
\end{tikzpicture}
\end{document}

Cheers,

Related Question