5

I would like to change the behavior of pgfplots for the placement of tick scale labels and units.

My desired placement would be or between the last two ticks or in place of the second last tick. For units, this function isn't existing yet, but at least it is possible to define the units separately as part of the \usepgfplotslibrary{units}. Maybe in future this will be possible to define their placement.

For the tick scale labels, placement is possible with every tick scale label/.style={} (s. page 277 in the manual).

For that, I am having two questions.

  • Is there a possibility to find the coordinates between the last two ticks (e.g. in style of (xticklabel cs:...))?
  • How can I prevent overlapping? If to narrow, the tick scale label shall be positioned in place of the second last tick label. For that, this tick label has to be disabled.

The placement of units is also discussed here without solution.


Edit

Here is an MWE for workaround. \cdot 10^{-2} should be between 1.3 and 1.2. I would like it more with \times in stead of \cdot.

\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[sticky-per]{siunitx}

\usepackage{tikz}
\usepackage{pgfplots}
\SendSettingsToPgf %follow localization
\usepgfplotslibrary{units}
\pgfplotsset{
            compat=1.8, 
            unit marking pre={\!\!/}, 
            unit marking post={},
            y label style={rotate=-90},
            %scale ticks above exponent = 1, %choose between scaling to one number before comma or to multiples of 3
            %scaled ticks=engineering, https://tex.stackexchange.com/a/124268/32245
            }

\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}
  \begin{axis}[
    yticklabel=$\pgfmathprintnumber{\tick}$,%follow localization
    xticklabel=$\pgfmathprintnumber{\tick}$,%follow localization
        %Problem here: for `scaled ticks=false` and big numbers, the numbers overlap
        xlabel=$\vartheta$, ylabel=$P$,
        x unit= \si{\kelvin}, y unit= \si{\watt},
        %scaled x ticks=false, %or {base 10:-3}, local manipulation of scaling
        %scaled y ticks={base 10:-2}, %or false, local manipulation of scaling
                ]
    \addplot coordinates {
        (1000,.01)
        (2000,.011)
        (3000,.012)
        (4000,.013)
    };
  \end{axis}
\end{tikzpicture}
\caption{Loss $P$ over temperature $\vartheta$}
\end{figure}
\end{document}

Some extras coming up when seeing my result:

  • Why isn't there a 10^3 on the x axis?
  • This x tick scale label would be a candidate to be positioned on the 3,500 tick
  • Possibility to move units to the coordinates I am searching in this post. E.g. \si{\kelvin} in place of the 3,500 tick
  • Parsing all numbers in ticks in respect to the siunitx localization
  • Could you add a MWE for the lazy? Technically the labels are nodes so giving them names for later reference should be easily doable. – Qrrbrbirlbel Aug 6 '13 at 11:45
  • Hi, did you find a solution to this? The answer below contains some nice things but not the answer to the real question. – LaRiFaRi Aug 11 '13 at 13:42
4
+100

You can find the position between the last two tick labels by naming the ticklabel nodes using a counter.

Placing the scale label in the position of the penultimate tick label in case there's not enough space automatically would be pretty tedious. An easier approach is to simply place the scale label on top of the tick label, using a white background to overwrite the tick label.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[sticky-per]{siunitx}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\SendSettingsToPgf %follow localization
\usepgfplotslibrary{units}
\pgfplotsset{
            compat=1.8, 
            unit marking pre={\!\!/}, 
            unit marking post={},
            y label style={rotate=-90},
            %scale ticks above exponent = 1, %choose between scaling to one number before comma or to multiples of 3
            %scaled ticks=engineering, http://tex.stackexchange.com/a/124268/32245
            }

\newcounter{yticklabel}
\newcounter{xticklabel}
\pgfplotsset{
    larifaris yticklabel/.style={
         yticklabel style={
            name=yticklabel-\theyticklabel,
            execute at end node={\stepcounter{yticklabel}}
         },
        every y tick scale label/.style={
            at={
                ($(yticklabel-\the\numexpr\theyticklabel-2\relax.east)!0.5!(yticklabel-\the\numexpr\theyticklabel-1\relax.east)$)
            },
            anchor=east
        },      
    },
    larifaris xticklabel/.style={
         xticklabel style={
            name=xticklabel-\thexticklabel,
            execute at end node={\stepcounter{xticklabel}}
         },
        every x tick scale label/.style={
            at={(xticklabel-\the\numexpr\thexticklabel-2\relax)},
            anchor=center,
            fill=white, inner ysep=1pt
        },      
    }
}

\begin{document}
\begin{figure}
\centering

\begin{tikzpicture}
  \begin{axis}[
        larifaris yticklabel,
        scale ticks above exponent=2,
        larifaris xticklabel,
        xlabel=$\vartheta$, ylabel=$P$,
        x unit= \si{\kelvin}, y unit= \si{\watt}
                ]
    \addplot coordinates {
        (1000,.01)
        (2000,.011)
        (3000,.012)
        (4000,.013)
    };
  \end{axis}

\end{tikzpicture}

\caption{Loss $P$ over temperature $\vartheta$}
\end{figure}
\end{document}
1

Remarks

I didn't find solutions to all of your problems, especially placing the order of magnitude with respect to any chosen ticks (this would need several let ... in ... operations, which are not possible inside of coordinate specifications).

Also replacing ticklabels by other labels in dependency to the paper size doesn't seem possible.

I hope my implementation is a good start point.

Implementation

\documentclass[tikz,border=3pt]{standalone}
\usepackage[sticky-per]{siunitx}
\usepackage{pgfplots}
\usepgfplotslibrary{units}
\pgfplotsset{
    compat=1.8, 
    unit marking pre={\!\!/}, 
    unit marking post={},
    y label style={rotate=-90},
    every x tick scale label/.style={
        at={(xticklabel cs:0.8,5pt)},
        anchor=near xticklabel,
        inner sep=0pt
    }, % change position of order of magnitude on x axis
    tick scale binop=\times, % Use \times instead of \cdot for order of magnitude
    ticklabel style={/pgf/number format/use comma}, % use comma as decimal separator in ticklabels
}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        xlabel=$\vartheta$,
        ylabel=$P$,
        x unit=\si{\kelvin},
        y unit=\si{\watt},
        scaled x ticks={base 10:-3}, % scale x axis to 10^3
    ]
        \addplot coordinates {
            (1000,.01)
            (2000,.011)
            (3000,.012)
            (4000,.013)
        };
    \end{axis}
\end{tikzpicture}
\end{document}

Output

enter image description here

  • Thanks for the start. Two comments to that: 1. The "use comma" is a good workaround but does not follow the localization. I added an idea to my MWE. 2. Why does scaling start automatically at 10^4? Is it possible to set scaling as default (every tick in the document has just one number in front of the comma)? – LaRiFaRi Aug 6 '13 at 13:53
  • 1
    @LaRiFaRi scaled ticks=true by default, but it only scales numbers with negative exponent. I'm pretty sure /pgf/number format doesn't have specific localizations predefined. – Henri Menke Aug 6 '13 at 13:54
  • And greater than 10^3. For what I tested. Try adding an zero to all x Points. Would be cool to manipulate this behavior in the preamble. – LaRiFaRi Aug 6 '13 at 13:57
  • 1
    You can specify the limits when scaling should be used with the keys scale ticks below exponent (default -1) and scale ticks above exponent (default 3). There was also a question about only using scaling exponents that are multiples of three (so-called engineering notation): tex.stackexchange.com/questions/124180/… – Jake Aug 6 '13 at 13:59
  • works great, thanks to you two. I'll add general scaling from Jake to the preamble and local manipulation from Henri to the axis options – LaRiFaRi Aug 6 '13 at 14:06

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.