3

I'd like to make a plot where data is arranged in bars, but each bar has a custom label if it is greater than a thousand. For instance, instead of 18,000 the label would read "18k" and for 50 million the label would read "50M" instead of "5*10^7". For billions it would read "2.2G" instead of "2.2*10^9". I've tried without success to find some way to do this and have checked the Tikz manual and all of the number format options, but can't figure it out.

\begin{tikzpicture}
\begin{semilogyaxis}[
width=11.5cm,
height=7.5cm,
ybar,
ymin=0.1,ymax=1e10,
legend style={at={(0.5,-0.2)},
anchor=north,legend columns=-1},
symbolic x coords={
candybar,
CD,
car,
house,
mansion,
spaceshuttle
},
xtick=data,
nodes near coords,
point meta=rawy, 
nodes near coords align={vertical},
x tick label style={rotate=45,anchor=east},
ymajorgrids=true,
grid style = very thin
]
\addplot coordinates {
(candybar,0.50) 
(CD,15) 
(car,18e3) 
(house,250e3) 
(mansion,50e6)
(spaceshuttle,2.2e9)
};
\end{semilogyaxis}
\end{tikzpicture}
3

You can customize your nodes near coords key for your own needs. For example, if you use

nodes near coords={%
  \pgfmathfloatparsenumber{\pgfplotspointmeta}%
  \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E}%
  \pgfmathsetmacro\mypostfix{\E<=2?0:(\E<=5?"k":(\E<=8?"M":"G"))}%
  \pgfkeys{/pgf/fpu}%
  \pgfmathparse{(\pgfplotspointmeta< 1Y1.0e3] ?1:%False
  (\pgfplotspointmeta < 1Y1.0e6]? 1Y1.0e3]:%False
    (\pgfplotspointmeta<1Y1.0e9] ? 1Y1.0e6]:1Y1.0e9])))}%
  \pgfmathparse{\pgfplotspointmeta/\pgfmathresult}%
  \pgfmathprintnumber[fixed,1000 sep=]\pgfmathresult\mypostfix%
},

You would get

enter image description here

I've also noticed that the rounding is problematic (as usual) so there might some need to use rounding if you are using values like 999999.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.