6

I have a particular question on how to properly modify the style of tick labels, to get them in exponential style. What I actually want to have is them to be of the style 10^n at the ticks corresponding to values to be multiples of 10.

standard logarithmic axes

At the standard setting of logarithmic style axes, tikz just starts to begin to use the exponential style numbers at the labels from 10^5 upwards. smaller numbers are printed as simple numbers.

using the number format option sci 10e of pgf

When I do this (i.e. uncomment the first line within the y-axis options), tikz will print all tick labels in the format 1*10^n, which already comes close to what I want to have. But I want to get rid of the leading factor '1*' for a more compact representation.

using the number format option sci generic of pgf

Actually according to the manual of pgfplotstable this should be the option of choice, to get where I want to reach. But when I do so (i.e. uncomment the second line within the y-axis options) I get some weird result of the tick label format.

I was able to get to the point, where I wanted to reach (i.e. uncomment line three) by messing around a bit with some pgfmathparse, but I find this not to be a very good solution.

Has somebody an idea, how to solve this problem a little bit smarter?

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{datavisualization,datavisualization.formats.functions}

\begin{document}
\makeatletter
\begin{tikzpicture}
\datavisualization [
scientific axes,
all axes={length=6cm},
x axis={
            ticks and grid={
                            step=2,
                            minor steps between steps=1
                            },
            include value={0,20},
            },
%               
y axis={
            logarithmic,
            ticks and grid={
                            step=1,
                            minor steps between steps=8,
                            %tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci 10e}\pgfmathprintnumber{##1}},
                            %tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci generic={exponent={10^{##1}}}}\pgfmathprintnumber{##1}}
                            %tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci generic={exponent={0^{\pgfmathparse{int(round(log10(##1)))}\pgfmathresult}}}}\pgfmathprintnumber{##1}}
                            },
            },
visualize as line
]
data[separator=\space] {
x y
0 1E1
5 1E2
10 1E3
15 1E4
20 1E5
}
;
\end{tikzpicture}
\end{document}

All lines commented out

enter image description here

Uncommented 1nd line

tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci 10e}\pgfmathprintnumber{##1}},

enter image description here

Uncommented 2nd line

tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci generic={exponent={10^{##1}}}}\pgfmathprintnumber{##1}}

enter image description here

Uncommented 3nd line

tick typesetter/.code={\pgfkeys{/pgf/number format/.cd, sci, sci generic={exponent={0^{\pgfmathparse{int(round(log10(##1)))}\pgfmathresult}}}}\pgfmathprintnumber{##1}}

enter image description here

  • Why do you have \makeatletter in your document? I can't see any reason for it but, if you do need it, you should issue \makeatother when you are done needing it. – cfr Dec 27 '15 at 1:43
  • I get an error if I uncomment the third option. – cfr Dec 27 '15 at 1:49
  • @cfr The \makeatletter was probably a remainder of testing something. – JMP Feb 1 '16 at 11:33
2

This is not correct. It is, rather, a cleaner hack which does not fail with an error on compilation, as the code in the question does.

Following the example on page 805 of the manual, we define \mytypesetter as follows:

\def\mytypesetter#1{% page 805
  \tikzset{%
    /pgf/number format/.cd,
    sci,
    sci generic={mantissa sep=,exponent={0^{##1}}}%
  }%
  \pgfmathprintnumber{#1}%
}

Since in this case the mantissa is always equal to 1, setting mantissa sep to an empty value and typesetting to exponent as 0^{<value>} rather than 10^{<value>} should give the result we want.

This is obviously not a good solution, but only a hack, because this is far from semantic mark-up. Indeed, it mixes format and content in an especially horrible way.

We can, however, then say

      tick typesetter/.code=\mytypesetter{##1},

to produce the required output, if I've understood the desiderata correctly.

hacked tick format for y-axis

If you prefer to configure this all in the one place, you can do so but you must distinguish between the first argument being passed to tick typesetter and the first argument being passed to /pgf/number format/sci generic. You do not want to pass the former to the latter else you will end up with the entire number formatted in the exponent, in addition to the mantissa part and the separator preceding it.

  y axis={
    logarithmic,
    ticks and grid={
      step=1,
      minor steps between steps=8,
      tick typesetter/.code={%
        \tikzset{%
          /pgf/number format/.cd,
          sci,
          sci generic={mantissa sep=,exponent={0^{####1}}}%
        }%
        \pgfmathprintnumber{##1}
      }
    },
  },

I would tend not to do this as I find this much harder to read than the first version which splits out the code formatting the number from the processing of the number in the axis definition. But the second version produces the same output if you prefer it for some reason.

Complete code:

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{datavisualization,datavisualization.formats.functions}
\def\mytypesetter#1{% page 805
  \tikzset{%
    /pgf/number format/.cd,
    sci,
    sci generic={mantissa sep=,exponent={0^{##1}}}%
  }%
  \pgfmathprintnumber{#1}%
}

\begin{document}
\begin{tikzpicture}
  \datavisualization [
  scientific axes,
  all axes={length=6cm},
  x axis={
    ticks and grid={
      step=2,
      minor steps between steps=1
    },
    include value={0,20},
  },
  y axis={
    logarithmic,
    ticks and grid={
      step=1,
      minor steps between steps=8,
      tick typesetter/.code=\mytypesetter{##1},
    },
  },
  visualize as line
  ]
  data[separator=\space] {
    x y
    0 1E1
    5 1E2
    10 1E3
    15 1E4
    20 1E5
  }
  ;
\end{tikzpicture}
\end{document}
  • Thanks for giving a better workaround. Still curious, if there is a 'correct' way. So I'm not sure if I should accept your answer, when you're saying by yourself, that this is not correct. – JMP Mar 29 '16 at 9:39
  • I can't advise. But this definitely isn't a good solution in my opinion. Just a more convenient hack. – cfr Mar 29 '16 at 13:09
1

Got finally a 'correct' version. To produce the tick labels in the way I want them, you have to work on a lower level of pgf. Basically you need to define your own typesetter, as already mentioned by cfr in his answer. Basically it is quite easy. You're passing the numbers to be printed to your code by \pgfmathfloatparsenumber{#1}. The number is then separated into flag, mantissa and exponent by \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E} and passed to predefined macros. The actual number printing then is done by \pgfutilensuremath{10^\E}.

One note:

This type of number printing is just correct, when using the logarithmic axis scaling and just for major ticks! Its incorrect for anything else, since the mantissa of the numbers is ommited at all!

EDIT

Added some percent signs in the declaration of the typesetter to prevent creation of unwanted whitespace, which becomes disturbing, when using the typesetter for setting labels at the right vertical axis.

Edit2

Added some curly braces at \pgfutilensuremath{10^{\E}} to prevent problems with printing negative exponents

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{datavisualization,datavisualization.formats.functions}
\def\mytypesetter#1{%
  \newcommand{\F}{0}%
  \newcommand{\M}{1}%
  \newcommand{\E}{0}%
  \pgfmathfloatparsenumber{#1}%
  \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E}%
  \pgfutilensuremath{10^{\E}}%
}

\begin{document}
\begin{tikzpicture}
  \datavisualization [
  scientific axes,
  all axes={length=6cm},
  x axis={
    ticks and grid={
      step=2,
      minor steps between steps=1
    },
    include value={0,20},
  },
  y axis={
    logarithmic,
    ticks and grid={
      step=1,
      minor steps between steps=8,
      tick typesetter/.code=\mytypesetter{##1},
    },
  },
  visualize as line
  ]
  data[separator=\space] {
    x y
    0 1E1
    5 1E2
    10 1E3
    15 1E4
    20 1E5
  }
  ;
\end{tikzpicture}
\end{document}

enter image description here

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.