2

I use "hybrid" coordinates made out of \ymin and raw x- and y-values. It's pretty comfortable to use, thanks to Gonzalo:

\newcommand{\getpgfkey}[1]{\pgfkeysvalueof{/pgfplots/#1}}
\newcommand{\xmin}[0]{\getpgfkey{xmin}}
\newcommand{\xmax}[0]{\getpgfkey{xmax}}
\newcommand{\ymin}[0]{\getpgfkey{ymin}}
\newcommand{\ymax}[0]{\getpgfkey{ymax}}

So now... say you have large data values and you would like to have your data scaled and the tick labels' content adjusted acoordingly. (This is directly based on my personal experience: I was told that the default position of the y tick labels aren't that pretty. Personally, I agree. Their default style puts them at (0,1), above right, roughly put.)

Of course one could always manually adjust their position and further alignment and so on but that is very time-consuming. So Jake delivered the solution by using an additional scaling style.

But that kind of "breaks" several other things, see my comments here. Most notable is the lack of sound meaning when using the aforementiond \xmin, \xmax... commands. After the transformations, these values are out of bounds and thus not visible anymore.

So I'd like to define a new value or variable \xminSCALED (and \xmaxSCALED, \yminSCALED and \ymaxSCALED) which gets defined/renewed after the coordinates have been transformed/scaled. These new values should then give access to new minimum and maximum values for the transformed x and y.

MWE

\documentclass{standalone}

\usepackage{pgfplots}

\newcommand{\getpgfkey}[1]{\pgfkeysvalueof{/pgfplots/#1}}
\newcommand{\xmin}[0]{\getpgfkey{xmin}}
\newcommand{\xmax}[0]{\getpgfkey{xmax}}
\newcommand{\ymin}[0]{\getpgfkey{ymin}}
\newcommand{\ymax}[0]{\getpgfkey{ymax}}

\usepgfplotslibrary{groupplots}
\pgfplotsset{
YScaling/.style={
y coord trafo/.code=\pgfmathparse{##1/(1e#1)},
%the following 4 lines break the MWE, also not working are variants with \newcommand or \renewcommand
%\let{\pgfkeysvalueof{/pgfplots/xmin}}={\xminSCALED},
%\let{\pgfkeysvalueof{/pgfplots/xmax}}={\xmaxSCALED},
%\let{\pgfkeysvalueof{/pgfplots/ymin}}={\yminSCALED},
%\let{\pgfkeysvalueof{/pgfplots/ymax}}={\ymaxSCALED},
ylabel style={
append after command={
node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
}
}
},
}

\begin{document}
\begin{tikzpicture}
\begin{groupplot}[
group style={
horizontal sep=0.2cm,
group size=2 by 1,
ylabels at=edge left,
yticklabels at=edge left,
},
ymin=300, ymax=1300,
xlabel={The label for the x-axis},
ylabel={Some y-values},
scale ticks above exponent={2},
]
\nextgroupplot[YScaling=3]
\addplot[only marks] coordinates{(2000,1200) (3000,500)};
\draw[ultra thick, dashed, blue] (axis cs:2000,\pgfkeysvalueof{/pgfplots/ymin}) rectangle (axis cs:3060,\pgfkeysvalueof{/pgfplots/ymax}); %<--- not working
\draw[ultra thick, dashed, red] (axis cs:2000,600) rectangle (axis cs:3050,1150); %<--- works but does not look equally good
%
\nextgroupplot[scaled y ticks=false]
\addplot[only marks] coordinates{(2000,1200) (4000,400)};
\addlegendentry{Text}
\end{groupplot}
\end{tikzpicture}
\end{document}

Picture for additional MWE below

enter image description here

additional MWE

\documentclass{standalone}

\usepackage{pgfplots}

\newcommand{\getpgfkey}[1]{\pgfkeysvalueof{/pgfplots/#1}}
\newcommand{\xmin}[0]{\getpgfkey{xmin}}
\newcommand{\xmax}[0]{\getpgfkey{xmax}}
\newcommand{\ymin}[0]{\getpgfkey{ymin}}
\newcommand{\ymax}[0]{\getpgfkey{ymax}}

\usepgfplotslibrary{groupplots}
\pgfplotsset{
xscalingdown/.style={ %XXX SCALE DOWN
    x coord trafo/.code=\pgfmathparse{##1/(1e#1)},
    xlabel style={
        append after command={
            node [anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
        }
    },
    every axis/.append code={%
        \pgfmathresult{\xmax/(1e#1)}\global\let\xmaxSCALED=\pgfmathresult
        \pgfmathresult{\xmin/(1e#1)}\global\let\xminSCALED=\pgfmathresult
%       \pgfmathresult{\ymax}\global\let\ymaxSCALED=\pgfmathresult
%       \pgfmathresult{\ymin}\global\let\yminSCALED=\pgfmathresult
    },
},
xscalingup/.style={ %XXX SCALE UP
    x coord trafo/.code=\pgfmathparse{##1*(1e#1)},
    xlabel style={
        append after command={
            node [anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{{-1}#1}}$}
        }
    },
    every axis/.append code={%
        \pgfmathresult{\xmax*(1e#1)}\global\let\xmaxSCALED=\pgfmathresult
        \pgfmathresult{\xmin*(1e#1)}\global\let\xminSCALED=\pgfmathresult
        %\pgfmathresult{\ymax}\global\let\ymaxSCALED=\pgfmathresult
        %\pgfmathresult{\ymin}\global\let\yminSCALED=\pgfmathresult
    },
},
yscalingdown/.style={ %YYY SCALE DOWN
    y coord trafo/.code=\pgfmathparse{##1/(1e#1)},
    ylabel style={
        append after command={
            node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
        }
    },
    every axis/.append code={%
        \pgfmathparse{\ymax/(1e#1)}\global\let\ymaxSCALED=\pgfmathresult
        \pgfmathparse{\ymin/(1e#1)}\global\let\yminSCALED=\pgfmathresult
        %\pgfmathresult{\xmax}\global\let\xmaxSCALED=\pgfmathresult
        %\pgfmathresult{\xmin}\global\let\xminSCALED=\pgfmathresult
    },
},
yscalingup/.style={ %YYY SCALE UP
    y coord trafo/.code=\pgfmathparse{##1*(1e#1)},
    ylabel style={
        append after command={
            node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{{-1}#1}}$}
        }
    },
    every axis/.append code={%
        \pgfmathparse{\ymax*(1e#1)}\global\let\ymaxSCALED=\pgfmathresult
        \pgfmathparse{\ymin*(1e#1)}\global\let\yminSCALED=\pgfmathresult
        %\pgfmathresult{\xmax}\global\let\xmaxSCALED=\pgfmathresult
        %\pgfmathresult{\xmin}\global\let\xminSCALED=\pgfmathresult
    },
},
}

\begin{document}
\begin{tikzpicture}
\begin{groupplot}[
group style={
    horizontal sep=0.2cm,
    group size=2 by 1,
    ylabels at=edge left,
    yticklabels at=edge left,
},
ymin=-100, ymax=1300,
xlabel={The label for the x-axis},
ylabel={Some y-values},
xscalingdown=3,
yscalingdown=3,
]
\nextgroupplot
\addplot coordinates{(2000,1200) (3000,\yminSCALED)};
\filldraw[ultra thick, dashed, blue] (\xminSCALED,\yminSCALED) rectangle (\xmaxSCALED,\ymaxSCALED);
\nextgroupplot
\addplot+ coordinates{(2100,1000) (2800,1200)};
\filldraw[ultra thick, dashed, red] (axis cs:2100,1000) rectangle (axis cs:\xmaxSCALED,1000) node[below, fill=orange] {bla};
%%NOTABLE DIFFERENT OUTPUT when omitting 'axis cs'
\filldraw[ultra thick, dashed, red] (2100,1000) rectangle (axis cs:\xmaxSCALED,1000) node[below, fill=orange] {bla};
\end{groupplot}
\end{tikzpicture}
\end{document}
henry
  • 6,594
  • Why not using (axis description cs:0.1,0.1) rectangle (axis description cs:0.9,0.9)? Or something like that? – percusse Sep 26 '14 at 07:27
  • Well that would work for substitutes for the \xmin macros and so forth but I need the hybrid coordinates. Ok I do not need them but I want them as they made T&E runs obsolete and are a real time-saver. – henry Sep 26 '14 at 07:53
  • 1
    Ok but if they are out of bounds then what should be the new xmin? You are practically using new set of numbers so you can also compute the xmin with the same trafo. I can't say I understand the purpose but seems like you can do it. – percusse Sep 26 '14 at 08:02
  • @percusse Yeah, exactly, new set of numbers. The new xmin (I think "xminSCALED" is better) should equal the value of xmin/1e10^{#1} then. But how can I define that? ... this is what the thread is about. Hope that clears it up? :) – henry Sep 27 '14 at 12:27

1 Answers1

2

This is actually too much for a comment, but not enough for an answer... but perhaps you can find something of interest or pose more directed questions to help me understand the use-case.

From what I understand, you would like to use \yminSCALED in order to accept the value inside of axis cs, right? In other words, you want "yminSCALED := inverse y transformation (\ymin)" ?

This would probably do it:

\documentclass{standalone}

\usepackage{pgfplots}

\newcommand{\getpgfkey}[1]{\pgfkeysvalueof{/pgfplots/#1}}
\newcommand{\xmin}[0]{\getpgfkey{xmin}}
\newcommand{\xmax}[0]{\getpgfkey{xmax}}
\newcommand{\ymin}[0]{\getpgfkey{ymin}}
\newcommand{\ymax}[0]{\getpgfkey{ymax}}

\usepgfplotslibrary{groupplots}
\pgfplotsset{
    YScaling/.style={
        y coord trafo/.code=\pgfmathparse{##1/(1e#1)},
        %the following 4 lines break the MWE, also not working are variants with \newcommand or \renewcommand
            %\let{\pgfkeysvalueof{/pgfplots/xmin}}={\xminSCALED},
        %\let{\pgfkeysvalueof{/pgfplots/xmax}}={\xmaxSCALED},
        %\let{\pgfkeysvalueof{/pgfplots/ymin}}={\yminSCALED},
        %\let{\pgfkeysvalueof{/pgfplots/ymax}}={\ymaxSCALED},
        ylabel style={
            append after command={
                node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
            }
        },
        %
        every axis/.append code={%
            \pgfmathparse{\ymax*(1e#1)}\global\let\ymaxSCALED=\pgfmathresult
            \pgfmathparse{\ymin*(1e#1)}\global\let\yminSCALED=\pgfmathresult
            \edef\pgfmathresult{\xmax}\global\let\xmaxSCALED=\pgfmathresult
            \edef\pgfmathresult{\xmin}\global\let\xminSCALED=\pgfmathresult
        },
    },
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    group style={
        horizontal sep=0.2cm,
        group size=2 by 1,
        ylabels at=edge left,
        yticklabels at=edge left,
    },
    ymin=300, ymax=1300,
    xlabel={The label for the x-axis},
    ylabel={Some y-values},
    scale ticks above exponent={2},
    YScaling=3,
    ]
\addplot[only marks] coordinates{(2000,1200) (3000,500)};
\draw[ultra thick, dashed, blue] (axis cs:\xminSCALED,\yminSCALED) rectangle (axis cs:\xmaxSCALED,\ymaxSCALED); %<--- not working
%
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Clearly "min" and "max" is not really what you wanted here (I must have missed something). But perhaps this is the correct direction?

EDIT

Regarding your questions:

  1. \edef\pgfmathresult{...} means "expanded definition": it defines \pgfmathresult to contain whatever is in the curly braces. In your example, you meant \pgfmathparse{...}. Please substitute \edef\pgfmathresult by \pgfmathparse; it is easier to work with and has the same effect.

  2. I experienced compilation problems with the example. It seems my approach with every axis/.style is incompatible with groupplot (sorry for not testing it properly). A workaround appears to be to add thexscalingdown` etc to each groupplot (I suppose there are smarter ways, but I have no time to find them right now).

  3. Your *SCALED versions should resemble the inverse transformation: if your transformation is "*10", the SCALED version should use "/10".

  4. I repaired the xlabel alignment.

Code:

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.11}
\newcommand{\getpgfkey}[1]{\pgfkeysvalueof{/pgfplots/#1}}
\newcommand{\xmin}[0]{\getpgfkey{xmin}}
\newcommand{\xmax}[0]{\getpgfkey{xmax}}
\newcommand{\ymin}[0]{\getpgfkey{ymin}}
\newcommand{\ymax}[0]{\getpgfkey{ymax}}

\usepgfplotslibrary{groupplots}
\pgfplotsset{
    xscalingdown/.style={
        x coord trafo/.code=\pgfmathparse{##1/(1e#1)},
        every axis/.append code={%
            \pgfmathparse{\xmax*(1e#1)}\global\let\xmaxSCALED=\pgfmathresult
            \pgfmathparse{\xmin*(1e#1)}\global\let\xminSCALED=\pgfmathresult
        },
        xlabel style={
            append after command={
                node [ anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
            }
        }
    },
        xscalingup/.style={
            x coord trafo/.code=\pgfmathparse{##1*(1e#1)},
            every axis/.append code={%
                \pgfmathparse{\xmax/(1e#1)}\global\let\xmaxSCALED=\pgfmathresult
                \pgfmathparse{\xmin/(1e#1)}\global\let\xminSCALED=\pgfmathresult
            },
            xlabel style={
                append after command={
                    node [anchor=base west] at (\tikzlastnode.base west) {$\cdot{10^{{-1}#1}}$}
                }
            }
        },
        yscalingdown/.style={
            y coord trafo/.code=\pgfmathparse{##1/(1e#1)},
            every axis/.append code={%
                \pgfmathparse{\ymax*(1e#1)}\global\let\ymaxSCALED=\pgfmathresult
                \pgfmathparse{\ymin*(1e#1)}\global\let\yminSCALED=\pgfmathresult
            },
            ylabel style={
                append after command={
                    node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{#1}}$}
                }
            }
        },
        yscalingup/.style={
            y coord trafo/.code=\pgfmathparse{##1*(1e#1)},
            every axis/.append code={%
                \pgfmathparse{\ymax/(1e#1)}\global\let\ymaxSCALED=\pgfmathresult
                \pgfmathparse{\ymin/(1e#1)}\global\let\yminSCALED=\pgfmathresult
            },
            ylabel style={
                append after command={
                    node [rotate=90, anchor=base west] at (\tikzlastnode.base east) {$\cdot{10^{{-1}#1}}$}
                }
            }
        },
}

\begin{document}
\begin{tikzpicture}
\begin{groupplot}[
group style={
    horizontal sep=0.2cm,
    group size=2 by 1,
    ylabels at=edge left,
    yticklabels at=edge left,
},
ymin=-100, ymax=1300,
xlabel={The label for the x-axis},
ylabel={Some y-values},
]
\nextgroupplot[
xscalingdown=3,
yscalingdown=3,
]
\addplot[only marks] coordinates{(2000,1200) (3000,500)};
\draw[ultra thick, dashed, blue] (axis cs:\xminSCALED,\yminSCALED) rectangle (axis cs:\xmaxSCALED,\ymaxSCALED);
\nextgroupplot[
xscalingdown=3,
yscalingdown=3,
]
\addplot[only marks] coordinates{(2100,1000) (2800,1200)};
\draw[ultra thick, dashed, blue] (axis cs:\xminSCALED,\yminSCALED) rectangle (axis cs:\xmaxSCALED,\ymaxSCALED);
\end{groupplot}
\end{tikzpicture}
\end{document}

enter image description here

henry
  • 6,594
  • Hm, I think I should adapt the MWE in the op to my status quo. But you already provided the solution as far as I can tell. What Jake's code does: it scales the coordinates down to provide some make-shift method for a better placement of tick labels (original thread on that here). Anyways, I'll update the op with an additional MWE. So... I don't know, I can mark you post then. – henry Sep 29 '14 at 19:08
  • Edited the op. But I do not fully understand it. If I enter measurements for shifts and so forth without a unit, they should get scaled according to y coord trafo... but they do not. Shift value with units remain untouched. (see the result for \ymax in the right plot). Also, why do you use \edef for those 2 lines? – henry Sep 29 '14 at 20:15
  • I played around with your code and came up with this. But I do not understand why it won't work. :/ – henry Sep 29 '14 at 20:16
  • One more, this is the best explanation of the scaling operations so far imho: http://pastebin.com/MkD4bgBZ – henry Sep 30 '14 at 07:02
  • 1
    I addressed (some of?) the questions in my edit – Christian Feuersänger Oct 01 '14 at 19:03
  • Thank you for your edit and explanations. About adding the scaling options to every groupplot, that is not remarkably ... "bad" or anything. About point 4, you wrote I repaired the xlabel alignment.. Maybe I misunderstand, but I do not see that. Or did you mean that you used the code by Jake? :) – henry Oct 03 '14 at 14:20