It seems that pgfplots
passes some additional information through, rather than just the units themselves. This confuses siunitx
, which is looking for a unit only (otherwise it bails out of processing the units). So we need to strip out the additional information. As mentioned in pgfplots - x unit with siunitx, we also need to expand the information passed through as it is 'stored' by pgfplots
:
\documentclass{article}
\usepackage{siunitx}
\usepackage{pgfplots}
\usepgfplotslibrary{units}
\makeatletter
\pgfplotsset{
unit code/.code 2 args=
\begingroup
\protected@edef\x{\endgroup\si{#2}}\x
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{axis}[
x unit=\metre\per\second, %This doesn't do what I want
y unit=\si{\metre\per\second}] %This does, but I don't want to type "\si{...}"
\end{axis}
\end{tikzpicture}
\end{document}
(The .code 2 args
here is used to throw away the first piece of information in #1
, which is where the main issue is.)
For those who would know everything, the full story. If you take a peek at what #1
in the above actually is, you get {}{\pgfkeysvalueof {/pgfplots/x\space unit}}
. Now, the problem is the braces. The first stage of siunitx
processing is to \edef
everything, which leads to {}{\metre\per\second}
(\pgfkeysvalueof
is expandable and the unit macros are protected). The second step siunitx
does is to look for anything that is not a unit macro, which I call 'literal' input. That leads to {}{}
, which is not empty and so looks like literal input. So the first 'argument' in the solution throws away the first set of braces, and unbraces the second argument. That means that the value then contains no 'literal' items, and is processed by siunitx
using the unit processor as desired.
Life gets a bit more complicated if there is a literal part to the unit, as in some circumstances the expansion process might take place at the 'wrong' time. That happens for example if there is a need to search-and-replace .
in a literal unit. Forcing the expansion 'up front' deals with that too.
One possibility to keep being flexible would be to redefine \ang
with an xparse argument signature like the following {omo}
to add the optional unit in the third argument. This macro then could easily be redefined.
Unfortunately this would either include a call to \SI
and thus loosing the possibilities of anglular minutes and angular seconds of the original \ang
macro or include a call to the old \ang
macro. The latter is to my knowledge not possible without code duplication, as neither the \let
nor the \LetLtxMacro
commands can cope with macros defined by xparse (which is the case for \ang
defined in siunitx).
As a workaround it is possible to use the following definition until there is a better solution:
\NewDocumentCommand{\angsi}{omom}{%
\ang[#1]{#2}\si[#3]{#4}%
}
Then it is possible to write
\angsi{42}{\per\second}
or
\angsi{1;2;3}{\per\second}
and add spacing as \,
to the macro definition later, if that should be needed.
Update:
I contacted Joseph Wright (siunitx package author) and he proposes
<num>°\,s^{-1}
according to the NIST standard:
There is a space between the numerical value and unit symbol, even
when the value is used in an adjectival sense, except in the case
of superscript units for plane angle.
So that's the way to go, which can be achieved by
\NewDocumentCommand{\angsi}{omom}{%
\ang[#1]{#2}\,\si[#3]{#4}%
}
Best Answer
You are using an old type of option to
siunitx
. If I fix the option everything is shown as expected. It also warns you to use the version 2 type inputs.