4

Consider this MWE:

\documentclass{article}
% \documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.5.1}
\usetikzlibrary{pgfplots.groupplots}
\usepackage{pgfplotstable}

\pagecolor{yellow!15}

\begin{document}

\pgfplotstableset{
% %define how the '0', '1' column shall be filled:
create on use/0/.style={create col/set list={0,1,...,200}},%
create on use/1/.style={create col/expr={1+0.005*\pgfplotstablerow+1*sin(40*\pgfplotstablerow)}},
}
% %create a new table with 11 rows and column ’0’:
\pgfplotstablenew[header=false,columns={0,1}]{201}\mytable

%%show it (debug):
%%I do not know the key '/pgfplots/table/create col/output empty row'
%\pgfplotstabletypeset[%header=false, %
%  empty cells with={---}, %
%  /pgfplots/table/every head row/.style={}, %
%]\mytable

\begin{tikzpicture}
\begin{groupplot}[
  group style={
    group name=my fancy plots,
    group size=2 by 1, % cols by rows
    yticklabels at=edge left,
    %xticklabels at=edge bottom,
    %vertical sep=0pt,
    horizontal sep=0pt,
  },
  height=6cm,
  ymin=0, ymax=3.5,
  domain=0:150, % x domain
  axis y line=middle,
  axis x line=middle,
  ylabel style={anchor=west},
]

\nextgroupplot[
  xmin=0, xmax=50,
  axis y line=left,
  axis x line=bottom,
  x axis line style=-,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
  skip rows between index={11}{200}, % passes, but no effect?
]\mytable;

\nextgroupplot[xmin=140, xmax=190,
  axis y line=none, % none here, because:
  axis x discontinuity=parallel,
  axis x line=bottom,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
  skip rows between index={11}{200}, % passes, but no effect?
]\mytable;

\end{groupplot}
\end{tikzpicture}

\end{document}

If you compile this with group size=1 by 1,, the code will compile as expected (minus a warning), in either article or standalone class (that is, there will be a single, centered plot).

But if you compile the MWE as is (group size=2 by 1,), in article class you get something like:

test04a

In my original work case where I noticed this, the plot was so much displaced to the right - that all I got when I opened the PDF was a blank page! Yet I found it suspicious that the PDF page was 80+ KB, so I tried standalone, and in this MWE, it confirms that, indeed, the whole plot is rendered as it should - just displaced:

test04b

(In my original work case, the standalone PDF measures 15821.4 x 175.365 pts; 5581 × 62 mm - that's like 5+ meters width!! compared to regular, expected, less than US Letter (216 × 279 mm)..) In this case, the standalone output PDF for this MWE (for me) measures 593.274 x 140.828 pts (or 209 × 50 mm).

Apparently, this is a problem to do with the size of the bounding box of the plot, not so much the size of the plot (contents) it(them)self(ves). It is also related to the discontinuity in the ranges: if you use (xmin=0,xmax=50 & xmin=50,xmax=100), then there is less of displacement, than if you use (xmin=0,xmax=50 & xmin=140,xmax=190).

So, what is the reason for this - and how can I get a correctly sized and placed pgfplot, when using a 2x1 groupplots with table data?

6

Remove the axis x discontinuity=parallel which causes the problem. Instead you can draw the discontinuity in a gap between the two plots. The gap can be set by the group style option horizontal sep.

enter image description here

\begin{tikzpicture}
\begin{groupplot}[
  group style={
    group name=my fancy plots,
    group size=2 by 1, % cols by rows
    yticklabels at=edge left,
    horizontal sep=3mm,% setting the gap for the discontinuity
  },
  height=6cm,
  ymin=0, ymax=3.5,
  domain=0:150, % x domain
  axis y line=middle,
  axis x line=middle,
  ylabel style={anchor=west},
]

\nextgroupplot[
  xmin=0, xmax=50,
  xtick={0,10,...,40},
  extra x ticks=50,
  extra x tick label=\llap{50},% shifts 50 left
  axis y line=left,
  axis x line=bottom,
  x axis line style=-,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
]\mytable;
\coordinate(dl)at(rel axis cs:1,0);% left point for discontinuity

\nextgroupplot[xmin=140, xmax=190,
  xtick={150,160,...,190},
  extra x ticks=140,
  extra x tick label=\rlap{140},% shifts 140 right
  axis y line=none,
  axis x line=bottom,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
]\mytable;
\coordinate(dr)at(rel axis cs:0,0);% right point for discontinuity
\end{groupplot}

% drawing the discontinuity:
\draw(dl)--++(0.1,0)--+(0,0.25)--+(0,-0.25);
\draw(dr)--++(-0.1,0)--+(0,0.25)--+(0,-0.25);
\end{tikzpicture}

Or

enter image description here

\begin{tikzpicture}
\begin{groupplot}[
  group style={
    group name=my fancy plots,
    group size=2 by 1, % cols by rows
    yticklabels at=edge left,
    horizontal sep=4mm,% setting the gap for the discontinuity
  },
  height=6cm,
  ymin=0, ymax=3.5,
  domain=0:150, % x domain
  axis y line=middle,
  axis x line=middle,
  ylabel style={anchor=west},
]

\nextgroupplot[
  xmin=0, xmax=50,
  axis y line=left,
  axis x line=bottom,
  x axis line style=-,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
]\mytable;
\coordinate(dl)at(rel axis cs:1,0);% left point for discontinuity

\nextgroupplot[xmin=140, xmax=190,
  xtickmin=145,% avoid printing a tick at 140
  axis y line=none,
  axis x line=bottom,
]
\addplot[mark=*,mark options={blue}] table[ %
  x index=0,
  y index=1,
]\mytable;
\coordinate(dr)at(rel axis cs:0,0);% right point for discontinuity
\end{groupplot}

% drawing the discontinuity:
\draw(dl)--++(0.2,0)--+(0,0.25)--+(0,-0.25);
\draw(dr)--++(-0.1,0)--+(0,0.25)--+(0,-0.25);
\end{tikzpicture}
  • Fantastic - many thanks for that, @esdd; just bumped into even more problems with discontinuity, so having this answer is great. Cheers! – sdaau Jun 6 '14 at 15:04
2

Boy, this was nasty. First I tried debugging with lua-visual-debug (Discovering which (La)Tex element is shown by lua-visual-debug (print to stdout)?), but what ultimately helped was brute-force (commenting options and recompiling, also in '2 by 1' mode).

It turns out that the problem is with axis x discontinuity=parallel, - comment that out, and the weird displacement goes away. Something similar is reported in Plot not plotted with pgfplots' \nextgroupplot and discontinuities?, where the problem turned out to be with the domain. Here it is something similar; consider this as the code for the second \nextgroupplot:

% the second \nextgroupplot
\nextgroupplot[xmin=181, xmax=190, %
  axis y line=left, %
  axis x discontinuity=parallel, % this is the buggy! but works if xmin<=first coordinate in addplot (up to xmin=180); already xmin=182 visible breakage!
  axis x line=bottom, %
] %
\addplot coordinates {(180,0) (190,1)};

As the comment says - with xmin<=180, there is no weird displacement, as the smallest x position of coordinates is 180; set xmin=182, and displacement would start occuring (this is more visible in 2 by 1 mode).

The problem is - when we do \addplot table, xmin doesn't even matter so much, because the entirety of the table will be processed for plotting, and so when discontinuity is active, it (apparently) will be plotted in the background (invisibly), starting from 0; and then simply it will be shown/cropped in the xmin:xmax range!

One would think skip rows between index={0}{139} would work here, but it doesn't: it works only for \pgfplotstabletypeset!! The corresponding invocation for \addplot table is skip coords between index={0}{139}, and with that (and the lua-visual-debug output of lualatex), I finally get this (for standalone):

test05a.png

... or for the solution MWE below (with pdflatex), which is slightly "cleaned up":

test05b.png

... which is what I was hoping to achieve.

Here is the solution:

% \documentclass{article}
\documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.5.1}
\usetikzlibrary{pgfplots.groupplots}
\usepackage{pgfplotstable}

% \usepackage{lua-visual-debug}
\pagecolor{yellow!15}

\begin{document}

\pgfplotstableset{ %
% %define how the '0', '1' column shall be filled:
create on use/0/.style={create col/set list={0,1,...,200}},%
create on use/1/.style={create col/expr={1+0.005*\pgfplotstablerow+1*sin(40*\pgfplotstablerow)}}, %
} %
% %create a new table with 11 rows and column ’0’:
\pgfplotstablenew[header=false,columns={0,1}]{201}\mytable %
%

\begin{tikzpicture}
\node[fill] (origin) at (0,0) {};

\begin{groupplot}[ %
  group style={ %
    group name=my fancy plots, %
    group size=2 by 1, % cols by rows
    yticklabels at=edge left, %
    %xticklabels at=edge bottom,
    %vertical sep=0pt,
    horizontal sep=0pt, %
  }, %
  height=6cm, %
  ymin=0, ymax=3.5, %
  %domain=0:10, % x domain
  axis y line=middle, %
  axis x line=middle, %
  ylabel style={anchor=west}, %
  xmin=0,ymin=0, %
  enlargelimits=false, %enlarge x limits={abs=5},
  /tikz/xshift=0cm,
] %


\nextgroupplot[ %
  xmin=0, xmax=50, %
  axis y line=left, %
  axis x line=bottom, %
  x axis line style=-, %
] %
\addplot[mark=*,mark options={blue}] table[ %
  x index=0, %
  y index=1, %
]\mytable; %


\nextgroupplot[xmin=140, xmax=190, %
  axis y line=none, % none here, because:
  axis x discontinuity=parallel, % 
  axis x line=middle, %
  % must manually specify xticklabels here, to
  % avoid/skip printing the first one, which overlaps with previous plot
  xtick={150,160,...,190},
  domain=145:190, % x domain ; no influence, neither here nor in \addplot
] %
\addplot[mark=*,mark options={blue},] table[ %
  x index=0, %
  y index=1, %
%   skip rows between index={0}{139}, % passes, but no effect? only pgfplotstabletypeset!
  skip coords between index={0}{143}, % this works for {0}{139}, make it more so that discontinuity is clearly seen
  filter discard warning=false, % else getting "... NOTE: coordinate (138,2.5560002e0) has been dropped because of a coordinate filter."; https://tex.stackexchange.com/questions/38255
]\mytable; %
%
\end{groupplot}
\end{tikzpicture}

\end{document}

EDIT: Note that if you use a table column to provide for xticklabels, using skip coords between index will make the xticklabels shift! The xmin/xmax indexes will still be correct, but if you, say, skip coords {0}{20}, and show xmin/xmax=40/50, then xmin=40 will read the table at index 60 (since the first 20 are skipped, so xmin=0 refers to row 21), and all other labels will be correspondingly shifted!

Here is code that shows how to fix the labels there (using \tick in xticklabel) - but at the cost of introducing again the problem with sizing :( ...

... actually, it turns out, that is due to the "create data table" part being between {document} and {tikzpicture}: it seems that if pgfplotstableset/new are between \begin{document} and \begin{tikzpicture}, then extra space is inserted; but if they are either before \begin{document} or inside \begin{tikzpicture}, then there is none of this extraneous space ?! So, in the MWE below, that "create data table" section is moved inside the \begin{tikzpicture} - and it seems ok, finally:

% \documentclass{article}
\documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.5.1}
\usetikzlibrary{pgfplots.groupplots}
\usepackage{pgfplotstable}

\usepackage{lua-visual-debug}
\pagecolor{yellow!15}

\begin{document}

% create data table was here - extra space!
% don't include it between {document} and {tikzpicture}!

\begin{tikzpicture}

\node[fill] (origin) at (0,0) {};

% create data table is ok here now
\pgfplotstableset{ %
create on use/0/.style={create col/set list={0,1,...,199}},%
create on use/1/.style={create col/expr={1+0.005*\pgfplotstablerow+1*sin(40*\pgfplotstablerow)}}, %
} %
\pgfplotstablenew[columns={0,1}]{200}\mytable %

% create table with xlabels column for the data table
\pgfplotstableset{ %
create on use/xlbcol/.style={create col/assign/.code={%
  \pgfplotstablegetelem{\pgfplotstablerow}{[index]0}\of{\mytable}
  \edef\entry{\pgfplotsretval}
  \edef\entry{label-\entry}%
  \pgfkeyslet{/pgfplots/table/create col/next content}\entry
}},
}
% must be **exactly** 200 as mytable is; else error for 201!
\pgfplotstablenew[columns={xlbcol}]{200}\myxlabtable %


% global
\gdef\firstRowA{44} \gdef\lastRowA{54}
\gdef\firstRowB{64} \gdef\lastRowB{74}
\pgfmathtruncatemacro{\RowBthreshold}{\firstRowB-1}
\xdef\RowBthreshold{\RowBthreshold}

\begin{groupplot}[ %
  group style={ %
    group name=my fancy plots, %
    group size=2 by 1, % cols by rows
    yticklabels at=edge left, %
    %xticklabels at=edge bottom,
    %vertical sep=0pt,
    horizontal sep=0pt, %
  }, %
  height=6cm, %
  xmin=0, %
  ymin=0,ymax=3.5, %
  domain=0:199, % x domain
  axis x line=middle, %
  axis y line=middle, %
  xticklabels from table={\myxlabtable}{xlbcol}, %{0},%{[index]0},
  xtick=data, %
  x tick label style={rotate=-20, anchor=west, align=center, font=\small}, %
  ylabel style={anchor=west}, %
%   enlargelimits=false, %enlarge x limits={abs=5},
%   /tikz/xshift=0cm,
] %
%

\nextgroupplot[ %
  xmin=\firstRowA, xmax=\lastRowA, %
  axis y line=left, %
  axis x line=bottom, %
  x axis line style=-, %
] %
\addplot[mark=*,mark options={blue}] table[ %
  x index=0, %
  y index=1, %
]\mytable;


\nextgroupplot[xmin=\firstRowB, xmax=\lastRowB, %
  axis y line=none, % none here, because:
  axis x discontinuity=parallel, % this is the buggy! but works if xmin<first coordinate in addplot!
  axis x line=middle, %
  domain=\firstRowB:\lastRowB, % x domain ; no influence, neither here nor in \addplot
  % note: without xticklabel below, the labels are
  % completely wrong (they'll start from 0)!
  % \pgfplotstablerow,\coordindex undefined here; only \tick
  xticklabel={%
    \pgfmathtruncatemacro{\tickint}{\tick} % get tick as integer in tickint
    \pgfplotstablegetelem{\tickint}{xlbcol}\of{\myxlabtable} % get the label text from the corresponding row
    \pgfplotsretval % output that value for the current tick label
  },
] %
\addplot[mark=*,mark options={blue},] table[ %
  %x index=0, %
  % here, \coordindex is same as x index=0,
  % but don't modify coordindex - else bad data!
  x expr=\coordindex,%-\firstRowB,
  y index=1, %
  skip coords between index={0}{\firstRowB}, %
%   filter discard warning=false, %
]\mytable;

\end{groupplot}

% for debug (visual comparison of range):
% \begin{axis}[xmin=\firstRowB, xmax=\lastRowB, ymin=0,ymax=3.5, height=6cm]
% \addplot[mark=*,mark options={red},] table[ %
%   x index=0, %
%   y index=1, %
% ]\mytable;
% \end{axis}

\end{tikzpicture}

\end{document}
  • Thanks for the detailed analysis. This is a bug in pgfplots and I will link your elaboration with the bug report. – Christian Feuersänger Oct 23 '14 at 20:58
1

I had a similar Problem using

\begin{document}

\pgfplotstableset{create on use ...
    }
\pgfplotstablenew[create on use ...]{}

\begin{tikzpicture}

A blank space was created before the picture was drawn. I put the commands behind the \begin{tikzpicture}, which solved the problem.

\begin{document}
\begin{tikzpicture}

\pgfplotstableset{create on use ...
    }
\pgfplotstablenew[create on use ...]{}

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.