[Tex/LaTex] Non-slanted (siunitx style) unit prefixes with pgfplots

pgfplotssiunitx

I've taken the example from the pgfplots manual on Preset SI prefixes and modified it slightly, changing a prefix from milli to micro.

The result is that the units of the yaxis are stated as micro-Newton, a \mu and a capital N. The \mu is slanted here, which is what disturbs and surprises me. The siunitx package (which I use everywhere else) would set the unit with an upright \mu. That's what I'd like to happen here as well.

Here's a rendering of this sample document:

\documentclass[preview]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{units}
\pgfplotsset{width=7cm,compat=1.11}
\usepackage{siunitx}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[change x base,
    x SI prefix=kilo,x unit=m,
    y SI prefix=micro,y unit=N,
    xlabel=Distance,ylabel=Force (\si{\micro\newton})]
    \addplot coordinates {
    (1000,1)
    (2000,1.1)
    (3000,1.2)
    (4000,1.3)
    };
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

I thought I had found a solution for this when I came across the line

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

in the pgfplots manual, but this does not help because the micro is passed to siunitx as \mu rather than \micro.

Best Answer

I believe this is a bug in tikzlibrarypgfplots.units.code.tex. Take a look at lines 109-180, where the prefixes are defined. You'll find (for micro only):

/pgfplots/x SI prefix/micro/.style={/pgfplots/axis base prefix={axis x base 6 prefix \mu}},%
/pgfplots/y SI prefix/micro/.style={/pgfplots/axis base prefix={axis y base 6 prefix \mu}},%
/pgfplots/z SI prefix/micro/.style={/pgfplots/axis base prefix={axis z base 6 prefix \mu}},%

This is what causes \mu to be passed even when using

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

as you mentioned. I'm not sure the best way to solve this in the general case (where the user is not guaranteed to be using siunitx), but here is a workaround for your case:

\documentclass[preview]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{units}
\pgfplotsset{width=7cm,compat=1.11}
\pgfplotsset{
  x SI prefix/micro/.style={/pgfplots/axis base prefix={axis x base 6 prefix \micro}},
  y SI prefix/micro/.style={/pgfplots/axis base prefix={axis y base 6 prefix \micro}},
  z SI prefix/micro/.style={/pgfplots/axis base prefix={axis z base 6 prefix \micro}},
  unit code/.code 2 args={\si{#1#2}},
}
\usepackage{siunitx}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[change x base,
    x SI prefix=kilo,x unit=\metre,
    y SI prefix=micro,y unit=\newton,
    xlabel=Distance,ylabel=Force (\si{\micro\newton})]
    \addplot coordinates {
    (1000,1)
    (2000,1.1)
    (3000,1.2)
    (4000,1.3)
    };
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

More detailed discussion

The rest of the prefix lines also leave something to be desired when siunitx is being used. Here's a typical example:

/pgfplots/x SI prefix/yocto/.style={/pgfplots/axis base prefix={axis x base 24 prefix y}},%

This does not follow the siunitx convention of using the literal prefix as a csname. If we were to do that, the typical line would look like:

/pgfplots/x SI prefix/yocto/.style={/pgfplots/axis base prefix={axis x base 24 prefix \yocto}},%

but, of course, this would only work with

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

just as my workaround above. The ideal solution would involve significant modifications to the code, but perhaps an siunitx option could be considered (a la circuitikz), which resets all prefixes to the literal prefix as a csname, and automatically sets up unit code for usage with siunitx.

To fix this when siunitx is not being used requires yet more modifications because of the default setup of unit code, which is entirely in math mode. Even if upright greeks were available, using them as part of the axis base prefix key is not allowed because we're not in text mode at that point.