2

I was asked to try and put the scale labels for the yticks not right above the north west corner of the plot as it is rather unusual. Personally, I tend to agree. It works easily but above left might be a bit better. But actually, putting it right above the label for the y-axis, then rotated 90 degrees, is preferable.

Based on Jake's post here, I got the idea to position the scale right above the ylabel by anchoring it to the ylabel node for each groupplot. But this does not work for a groupplot for reasons I have not yet figured out.

But all in all, I intended to use a reliable method to anchor the scale labels to xlabel and ylabel because fine-tuning the positions is an immensely time-consuming task. :(

Is this possible, to anchor the tick scale labels at the north end of the ylabel in a groupplot?

Really cool mockup of what I would like to have (the blue, funny looking scale labels are the ones I want, please imagine the red one right next to the xlabel as well)

enter image description here

MWE (does not work)

\documentclass[
a4paper
]{scrartcl}

\usepackage{
lmodern,
tikz,
pgfplots,
}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepgfplotslibrary{groupplots}

%\pgfplotsset{
%x label style={at={(rel axis cs:0.5,-0.15)}, name=xlabel},
%y label style={at={(rel axis cs:-0.2,0.5)}, name=ylabel},
%}

\begin{document}
\begin{center}
\begin{tikzpicture}[font=\small]
\begin{groupplot}[
group style={
group size=2 by 1,
horizontal sep=0.2cm,
vertical sep=1.5cm,
ylabels at=edge left,
yticklabels at=edge left,
},
%
ymin=300,
ymax=1300,
%
xlabel={The label for the x-axis},
ylabel={Some y-values},
%
xlabel style={at={(rel axis cs:0.5,-0.15)}, name={xlabel} },
ylabel style={at={(rel axis cs:-0.2,0.5)}, name={ylabel}},
legend style={at={(xlabel.south)}, anchor=north, yshift=-1ex},
%
every x tick scale label/.append style={
    at={(xlabel.east)}, anchor=west, inner sep=0pt
},
every y tick scale label/.append style={
    at={(ylabel.north)}, rotate=90, anchor=south, inner sep=0pt
},
%
scale ticks above exponent={2},
]
\nextgroupplot
\addplot[only marks] coordinates{(2000,1200) (3000,500)};
\addlegendentry{Word}
\nextgroupplot
\addplot[only marks] coordinates{(2000,1200) (4000,400)};
\addlegendentry{Text}
\end{groupplot}
\end{tikzpicture}
\end{center}
\end{document}
henry
  • 6,594
  • A simple solution would be to define macros and use the macros in each plot. \def\ymin{300) ... ymin=\ymin – John Kormylo Sep 18 '14 at 14:56
  • Come to think of it, you could set the value using \pgfkeys, but you would need to know its full name. – John Kormylo Sep 18 '14 at 14:58
  • @JohnKormylo I think there was a misunderstanding. Or I am not smart enough to apply the bits in your comments to the problem. – henry Sep 18 '14 at 15:52
  • @henry: I'm not sure I understand exactly where you want the scale label to go. Could you maybe add a mock-up of what you want the output to look like? – Jake Sep 18 '14 at 16:34
  • Sorry, I thought you were just trying to get several plots to have the same scale. – John Kormylo Sep 18 '14 at 16:43
  • @Jake Edited the op. :) – henry Sep 18 '14 at 18:35
  • 1
    @henry: Ugh, this would requires some serious changes to a lot of internal macros. I don't suppose you'd be happy with a manual solution? If you define a new key \pgfplotsset{ henry's scale label/.style={ y coord trafo/.code=\pgfmathparse{##1/(1e#1)}, ylabel/.append={$\ \cdot{10^{#1}}$} } } you can call henry's scale label=3 in your axis options to get the desired output. – Jake Sep 18 '14 at 19:57
  • @Jake Hm, that is a good idea. But I'll rather use the vanilla code then, i.e. to put it above the y-values then, via at={(0,1)}, above left, yshift=SOMEVALUE. "Less code is better", kind of... sort of. :) Thank you for looking into it, I appreciate it. – henry Sep 18 '14 at 20:26
  • You could pre-compute the scale factor (power of 10) yourself and apply it to the data. I've already got code to do that somewhere. – John Kormylo Sep 18 '14 at 22:11
  • 1
    @Jake In hindsight, your code might prove to be ideal after all. :) Will try it out asap. – henry Sep 21 '14 at 17:49
  • @Jake It works like a charm... for the y-values, that is. Hm, but I can't really pinpoint why the values which are used are transformed ... what gets displayed, say when a value of 1500 is taken out of the respective data file? 1.5 or 1500? Btw I suppose it's simply in analog form for the x-values? – henry Sep 21 '14 at 20:44
  • @Jake Hm, also the actual label content (=text) gets shifted due to the extra content. All in all, what will I choose, the devil or the deep blue sea. :P I think it's worth saying that once one has figured out the 1. font, 2. font size and 3. the shift, the vanilla method is equally, um, pleasant to work with. ;) – henry Sep 21 '14 at 20:47
  • @Jake Can I add an xshift command exactly the length of whatever length henry's scale label might add to the original xlabel? – henry Sep 23 '14 at 20:41
  • @henry: To avoid shifting the xlabel, you can simply attach the scale label to the side of the xlabel. I've added an answer. – Jake Sep 24 '14 at 05:07

1 Answers1

1

Doing this in a fully automatic fashion is quite hard and would require serious changes to several internal macros. If you can live with a semi-automatic solution where you provide the scaling exponent manually, you could define a new style

\pgfplotsset{
    henry's scale label/.style={
        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}}$}
            }
        }
    }
}

which in your example you would call using henry's scale label=3:

\documentclass{standalone}

\usepackage{pgfplots}

\usepgfplotslibrary{groupplots}
\pgfplotsset{
    henry's scale label/.style={
        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}}$}
            }
        }
    }
}

\begin{document}
\begin{tikzpicture}
\begin{groupplot}[
group style={
    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},
henry's scale label=3
]
\nextgroupplot
\addplot[only marks] coordinates{(2000,1200) (3000,500)};
\addlegendentry{Word}
\nextgroupplot
\addplot[only marks] coordinates{(2000,1200) (4000,400)};
\addlegendentry{Text}
\end{groupplot}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • This workaround breaks the solution found here to draw zero lines for every plot. The plots who get assigned the option to use this custom scale label, do not get the respective zero line drawn anymore. – henry Sep 25 '14 at 13:34
  • But unfortunately, using execute at begin plot={\draw[thin] (current axis.left of origin) -- (current axis.right of origin);\draw[thin] (current axis.above origin) -- (current axis.below origin);}, does not lead to satisfactory results (read: really ugly and factually wrong) => click here for picture. Could you please give some advice for this? :) Also, random note: one can not use the restrict VARIABLE to domain key with this, it does not produce useful results then. – henry Sep 25 '14 at 13:35
  • Another note: this "breaks" (for the lack of a better word) the method to define coordinate based upon another, by using syntax like: \draw (0,1) coordinate (x1) ($(x1)+(1.5cm,0.33cm)$) coordinate (x2) ;. It's back to [yshift=...] then. Neither does shift={(1.2cm,0.25cm)} work. – henry Sep 28 '14 at 10:57
  • @henry: I'm not sure what you mean by "breaks" in this last case. The calc syntax shouldn't be influenced by this code. Could you maybe ask a new question about this_ – Jake Sep 28 '14 at 11:00
  • I figured out the restrict VARIABLE to domain method in the meantime. One has to multiply/divide these border values with/by the scale factor on defines. So in that regards, I take that back. It's fine. – henry Sep 29 '14 at 19:51
  • About that last case: damnit, I can't reproduce it. :( :( It works as expected in an MWE but not in my big document. :( – henry Sep 29 '14 at 19:57