[Tex/LaTex] pgfplots – x unit with siunitx

pgfplotssiunitx

I want to use x unit=something to draw the units to an axis. In the manual I find this to use siunitx to do so:

\pgfplotsset{
  unit code/.code 2 args={\si{#1#2}}
}  

Now I make a plot:

\begin{axis}[
    xlabel = \(E\),
    x unit={\mega\electronvolt.m}
  ]  

The dot is written, which should not be. Manually, this works:

\begin{axis}[
    xlabel = \(E\),
    x unit=\si{\mega\electronvolt.m}
]  

What am I doing wrong?

Best Answer

The issue is that pgfplots passes the unit 'wrapped up' inside some code. To get it out correctly here we have to take steps to expand it.

\documentclass{standalone}
\usepackage{pgfplots,siunitx}
\usepgfplotslibrary{units}
\makeatletter
\pgfplotsset{
  unit code/.code 2 args=
    \begingroup
    \protected@edef\x{\endgroup\si{#2}}\x
} 
\makeatother 
\begin{document}
\begin{tikzpicture}

\begin{axis}[
  xlabel = \(E\),
  x unit=\mega\electronvolt.m]
\addplot {x^2};
\end{axis}

\end{tikzpicture}
\end{document}

You can do the same with \expandafter but you need a lot of them!

\documentclass{standalone}
\usepackage{pgfplots,siunitx}
\usepgfplotslibrary{units}
\pgfplotsset{
  unit code/.code 2 args=
    \expandafter\expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter\si
        \expandafter\expandafter\expandafter\expandafter
          \expandafter\expandafter\expandafter{#2}%
} 

\begin{document}
\begin{tikzpicture}

\begin{axis}[
  xlabel = \(E\),
  x unit=\mega\electronvolt.m]
\addplot {x^2};
\end{axis}

\end{tikzpicture}
\end{document}

The reason you have to force expansion is that unlike numbers, siunitx does not try to expand units: it expects them to be given 'as is'. As such, the search-and-replace for . fails as it's 'hidden' inside a pgfplots macro.

Related Question