图片/绘图与表格组图的位置(和/或大小)错误(......和不连续性)?

图片/绘图与表格组图的位置(和/或大小)错误(......和不连续性)?

考虑一下这个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}

如果使用 编译它group size=1 by 1,,代码将按预期进行编译(减去警告),在或article类中standalone(也就是说,将有一个居中的图)。

但是如果你按原样编译 MWE ( group size=2 by 1,),在article课堂上你会得到类似这样的内容:

测试04a

在我最初注意到这一点的工作案例中,情节向右偏移了很多——当我打开 PDF 时,我得到的只是一个空白页!然而,我发现 PDF 页面有 80+ KB 很可疑,所以我尝试了,standalone在这个 MWE 中,它证实了,确实,整个情节都是按应有的方式呈现的——只是偏移了:

测试04b

(在我原来的工作案例中,standalonePDF 尺寸为 15821.4 x 175.365 pts;5581 × 62 毫米 - 相当于 5 米以上的宽度!!与常规、预期的美国信纸(216 × 279 毫米)相比...)在这种情况下,standalone此 MWE 的输出 PDF(对我而言)尺寸为 593.274 x 140.828 pts(或 209 × 50 毫米)。

显然,这是一个与绘图边界框大小有关的问题,而不是绘图(内容)本身的大小。它还与范围的不连续性有关:如果使用 (xmin=0,xmax=50 & xmin=50,xmax=100),则位移会比使用 (xmin=0,xmax=50 & xmin=140,xmax=190) 时小。

那么,这是什么原因造成的?当使用带有表格数据的 2x1 组图时,如何获得正确大小和位置的 pgfplot?

答案1

删除axis x discontinuity=parallel导致问题的 。相反,您可以在两个图之间的间隙中绘制不连续性。间隙可以通过选项 来group style设置horizontal sep

在此处输入图片描述

\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}

或者

在此处输入图片描述

\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}

答案2

天哪,这太糟糕了。首先我尝试使用lua-visual-debug(发现 lua-visual-debug 显示哪个 (La)Tex 元素(打印到标准输出)?),但最终有帮助的还是蛮力(注释选项并重新编译,也采用“2 by 1”模式)。

事实证明,问题出在axis x discontinuity=parallel,- 注释掉它,奇怪的位移就消失了。在图未使用 pgfplots 的 \nextgroupplot 和不连续性绘制?,问题出在域上。这里有一些类似的东西;将其视为第二个的代码\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)};

正如注释所说 - 当 xmin<=180 时,不会出现奇怪的位移,因为坐标的最小 x 位置是 180;设置 xmin=182,位移就会开始发生(这在 2 x 1 模式下更加明显)。

问题是 - 当我们这样做时\addplot table,xmin 甚至不那么重要,因为整个表都将被处理以进行绘图,因此当discontinuity处于活动状态时,它(显然)将要从 0 开始在背景中绘制(不可见);然后它会在 xmin:xmax 范围内显示/裁剪!

有人认为skip rows between index={0}{139}这可以在这里工作,但事实并非如此:它有效仅有的对于\pgfplotstabletypeset!! 对应的调用\addplot tableskip coords between index={0}{139},有了它(以及lua-visual-debug的输出lualatex),我最终得到了这个(对于standalone):

测试05a.png

... 或者对于下面的 MWE 解决方案(带有pdflatex),它稍微“清理”了一下:

测试05b.png

...这正是我希望实现的。

解决方案如下:

% \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}

编辑:笔记如果您使用表格列来提供 xticklabels,则使用skip coords between index将使 xticklabels 发生偏移!xmin/xmax 索引仍然正确,但如果您跳过坐标 {0}{20},并显示 xmin/xmax=40/50,则 xmin=40 将读取索引 60 处的表格(因为跳过了前 20 个,所以 xmin=0 指的是第 21 行),并且所有其他标签将相应地发生偏移!

以下代码显示了如何修复那里的标签(使用\tickin xticklabel)——但代价是引入再次尺寸问题:(...

...实际上,事实证明,这是由于“创建数据表”部分位于{document}和之间{tikzpicture}:似乎如果 pgfplotstableset/new 位于\begin{document}和之间\begin{tikzpicture},则会插入额外的空间;但如果它们在之前\begin{document}或之内\begin{tikzpicture},那么就没有这些多余的空间了?!因此,在下面的 MWE 中,“创建数据表”部分被移到了里面\begin{tikzpicture}- 看起来还不错,最后:

% \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}

答案3

我遇到了类似的问题

\begin{document}

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

\begin{tikzpicture}

在绘制图片之前出现了空白区域。我将命令放在 后面\begin{tikzpicture},问题就解决了。

\begin{document}
\begin{tikzpicture}

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

相关内容