[Tex/LaTex] Preserving styles while changing axis y line in pgfplots

pgfplotstikz-pgf

The code for the MWE generating this image is given below (click for full-size):

test-sbs.png

Basically, I had some graphs like on the left, until I realized I need to shift the x axis – this also forces me to move axis y line=middle (left-hand plot) to axis y line=left (right-hand plot). My questions are:

  • How do I get the xlabel ("t [ms]") and the ylabel ("D"), to be in the same position on the right-hand plot, as they are on the left-hand plot? (hopefully, with a single command to be used both places; that is, without having to use rotate in one, and not use rotate in the other)
  • How do I get the zero to disappear as first y axis tick label on the right-hand plot, without entering labels manually?
  • How do I get the zero to appear as first x axis tick label on the left-hand plot?
  • I like the organization of one tikzpicture with two scopes inside; however the xshift of the right-hand plot is trial&error. What would be the recommended "automatic" way to get the two plots side by side, each taking up half of the page width, with this structure (that is, without introducing extra minipage)?

And a side question: how do I get the axes tick label font to be the same as the rest of the document style (here IEEEtran)?

Here is the code:

\documentclass[%
  12pt,
  journal,
  twoside,
  draftcls,
  letterpaper,
]{IEEEtran}

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{tikz}


\begin{document}

\begin{tikzpicture}

\pgfplotstableread[col sep=&,row sep=\\]{
  0.0159779999812599 & 0.00398599999607541 \\
  0.0240009999834001 & 0.00802300000214018 \\
  0.0240489999996498 & 4.80000162497163e-05 \\
  0.0280280000006314 & 0.00397900000098161 \\
}\mytable

\begin{scope}
\begin{axis}[
  title={\small my data},
  title style={at={(0.5,0.9)},anchor=center},
  clip=true,
  axis x line=middle,
  axis y line=middle,
  xmin = 0,
  xmax = 0.03,
  ymin = 0,
  ymax = 0.009,
  xlabel={$t$\,[ms]},
  xlabel style={at={(axis description cs:1.01,+0.0)},anchor=west},
  ylabel={$D$},
  ylabel style={at={(axis description cs:-0.02,1.01)},anchor=south},
  %xtick=data,
  scaled x ticks=base 10:3,
  xtick scale label code/.code={},
  x tick label style={
    rotate=-45,
    anchor=west,
    /pgf/number format/fixed,
    /pgf/number format/fixed zerofill,
    /pgf/number format/precision=3,
  },
  ymajorticks=true,
  yminorticks=false,
  tick label style={font=\small,},
  legend cell align=left,
  legend pos=outer north east,
]

\addplot table \mytable;

\end{axis}
\end{scope}

\begin{scope}[xshift=240]
\begin{axis}[
  title={\small my data},
  title style={at={(0.5,0.9)},anchor=center},
  clip=true,
  axis x line=bottom,
  axis y line=left,
  xmin = -0.005,
  xmax = 0.025,
  ymin = 0,
  ymax = 0.009,
  xlabel={$t$\,[ms]},
  xlabel style={at={(axis description cs:1.01,+0.0)},anchor=west},
  ylabel={$D$},
  ylabel style={at={(axis description cs:-0.02,1.01)},anchor=south},
  %xtick=data,
  scaled x ticks=base 10:3,
  xtick scale label code/.code={},
  x tick label style={
    rotate=-45,
    anchor=west,
    /pgf/number format/fixed,
    /pgf/number format/fixed zerofill,
    /pgf/number format/precision=3,
  },
  ymajorticks=true,
  yminorticks=false,
  tick label style={font=\small,},
  legend cell align=left,
  legend pos=outer north east,
]

\addplot table \mytable;

\end{axis}
\end{scope}

\end{tikzpicture}
\end{document}

\end{document}

Best Answer

OK, I got somewhere - except the I cannot get the plots' combined width to fit within the margins (hope someone will offer a solution for that):

test-sbs-fix

Otherwise:

  • Aligning the xlabel, ylabel: is a bit of a pain; note the manual states:

    The starred versions . . . line* only affect the axis lines, without correcting the positions of axis labels, tick lines or other keys which are (possibly) affected by a changed axis line.

which in this case means that I should first set axis y line=middle to set the label position as I want it, then re-set with axis y line*=left afterwards, so only the axis position changes (this also adds the 0 as ytick label)

  • the zero to appear as first x axis tick label on the left-hand plot - similarly, by "overloading" with axis x line*=bottom

  • the zero to disappear as first y axis tick label on the right-hand plot - somewhat tricky, but seems that only thing that works, is "overloading" yticklabel and setting a conditional command via \ifnum in there, that uses \ticknum (which apparently starts from 1).

  • the axes tick label font - the problem is that by default, pgfplots typesets axes tick labels in math mode; as example - I've left the yticklabel overload so it typesets the number directly, and it can be seen it is in Times. Otherwise, Change font also on axes in pgfplots explains that an additional package has to be loaded to use Times as math font, and for me \usepackage{txfonts} works (though I bumped in the problem described in Local font installation problems, and the solution there worked for me).

  • auto xshift of scope: a similar problem is noted in pgfplots - Positioning a tikz scope relative to another tikz scope. This is not quite auto, but I use half of \textwidth minus half of intended separation to set the width of a plot; as it can be seen from the image, it's almost there but not quite right with the margins; will probably have to test the suggestion of @JohnKormylo, too

And here is the code:

\documentclass[%
  12pt,
  journal,
  twoside,
  draftcls,
  letterpaper,
]{IEEEtran}


% \usepackage{txfonts} % Times font in math; 
% tlmgr install txfonts ; texhash ; updmap-sys --enable Map=txfonts.map ; texhash
% [rm ~/.texlive2011/texmf-var/fonts/map/pdftex/updmap/pdftex.map]

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning} % of

% https://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz
\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother

\begin{document}

\newlength{\pw}
\setlength{\pw}{0.5\textwidth}
\addtolength{\pw}{-0.5cm}

\begin{tikzpicture}

\pgfplotstableread[col sep=&,row sep=\\]{
  0.0159779999812599 & 0.00398599999607541 \\
  0.0240009999834001 & 0.00802300000214018 \\
  0.0240489999996498 & 4.80000162497163e-05 \\
  0.0280280000006314 & 0.00397900000098161 \\
}\mytable

\begin{scope}[local bounding box=scope1]
\begin{axis}[
  title={\small my data},
  title style={at={(0.5,0.9)},anchor=center},
  clip=true,
  width=\pw,
  axis x line=middle,
  axis y line=middle,
  axis x line*=bottom,
  xmin = 0,
  xmax = 0.03,
  ymin = 0,
  ymax = 0.009,
  xlabel={$t$\,[ms]},
  xlabel style={at={(axis description cs:1.01,+0.0)},anchor=west},
  ylabel={$D$},
  ylabel style={at={(axis description cs:-0.02,1.01)},anchor=south},
  scaled x ticks=base 10:3,
  xtick scale label code/.code={},
  x tick label style={
    rotate=-45,
    anchor=west,
    /pgf/number format/fixed,
    /pgf/number format/fixed zerofill,
    /pgf/number format/precision=3,
  },
  ymajorticks=true,
  yminorticks=false,
  tick label style={font=\small,},
  legend cell align=left,
  legend pos=outer north east,
]

\addplot table \mytable;

\end{axis}
\end{scope}

\gettikzxy{($(scope1.east)+(1cm,0)$)}{\ax}{\ay}

% none of this works:
% \begin{scope}[remember picture,at={($(scope1.east)+(1cm,0)$)}]%right=of scope1.east]%[at={($(scope1.east)+(1cm,0)$)}] 
% ... only xshift:
\begin{scope}[xshift=\ax]
\begin{axis}[
  title={\small my data},
  title style={at={(0.5,0.9)},anchor=center},
  clip=true,
  width=\pw,
  axis x line=middle,
  axis y line=middle,
  axis x line*=bottom,
  axis y line*=left,
  xmin = -0.005,
  xmax = 0.025,
  ymin = 0,
  ymax = 0.009,
  xlabel={$t$\,[ms]},
  xlabel style={at={(axis description cs:1.01,+0.0)},anchor=west},
  ylabel={$D$},
  ylabel style={at={(axis description cs:-0.02,1.01)},anchor=south},
  scaled x ticks=base 10:3,
  xtick scale label code/.code={},
  x tick label style={
    rotate=-45,
    anchor=west,
    /pgf/number format/fixed,
    /pgf/number format/fixed zerofill,
    /pgf/number format/precision=3,
  },
  %yticklabel={\ifnum\ticknum=1{}\else\axisdefaultticklabel\fi},
  yticklabel={\ifnum\ticknum=1{}\else\tick\fi},
  ymajorticks=true,
  yminorticks=false,
  tick label style={font=\small,},
  legend cell align=left,
  legend pos=outer north east,
]

\addplot table \mytable;

\end{axis}
\end{scope}

\end{tikzpicture}
\end{document}
Related Question