我知道标题可能会引起误解,但我不知道该如何表达得更好。当我收到更好的建议时,我会改正它。
我尝试使用 pgfplots 从外部表绘制图表。唉,我必须使用的模板非常窄,因此我必须将多个步骤紧密放在一起。这意味着,我为我的图表定义一种样式,使得轴边框与我的文档一致\linewidth
。不幸的是,我想对许多图表使用一种样式,因此我不会手动设置刻度数(并且不想这样做)。在所附的示例中,刻度都很好(我并不真正关心它们,这仅用于定性目的)但最外面的刻度将我的边界框延伸到外面,如果两个图表彼此相邻,则会重叠。
请参阅所附图片以了解我的问题,有问题的部分用红色圈出。周围的黑色框是显示图像边框的 fbox。
使用的软件包是
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
我的风格定义如下,并应用于轴环境:(忽略颜色,厚度和其他不相关的部分)
gek1d/.style={
enlargelimits=false,
scale only axis,
xlabel={$x$},
ylabel={$f(x)$},
axis lines=middle,
xtick align=center,
enlarge x limits=false,
x axis line style={-stealth},
width=\linewidth ,
height=0.618\linewidth,
yticklabel style={overlay},
xticklabel style={overlay},
}
所以我想要做的是:命令刻度只在轴内。我不想手动设置它们,也不想移动标签,也不想完全删除标签。这意味着,在这种情况下,我可以接受 +-8 作为最外面的刻度,我也可以接受 +-9 作为最外面的刻度,但我不希望 +-10 刻度在那里。有人有什么想法吗?
答案1
您可以通过修补负责排版标签的内部宏来实现这一点,以便仅当标签完全适合边界框时才排版标签:
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\usepackage{calc}
\makeatletter
% #1: the axis (x,y or z)
% #2: the location where to place it.
\def\pgfplots@show@ticklabel@@#1#2{%
\pgf@process{#2}%
% define a leniency factor here, so we can remove all labels, which are
% \leniency* labeldim from the border.
\def\leniency{0.5}%
\setlength{\pgf@xa}{\widthof{\csname pgfplots@#1ticklabel\endcsname}}%
\setlength{\pgf@ya}{\heightof{\csname pgfplots@#1ticklabel\endcsname}}%
\pgfmathtruncatemacro\labelfits{
and(
and(
(\pgf@x-\leniency*\pgf@xa)>0,
(\pgf@picmaxx-\pgf@x-\leniency*\pgf@xa)>0
),
and(
(\pgf@y-\leniency*\pgf@ya)>0,
(\pgf@picmaxy-\pgf@y-\leniency*\pgf@ya)>0
))}%
\ifnum\labelfits=1%
% Typeset the label!
\pgfinterruptboundingbox
% What makes this complicated is the 'ticklabel cs' feature.
% What we need is to compute the MAXIMUM LENGTH over each tick
% label IN DIRECTION OF THE OUTER NORMAL.
%
% This needs to
% 1. enable bounding box computation even in case of
% 'overlay',
% 2. projection of the bounding box in direction of the outer
% normal,
% 3. update of the bounding box if 'overlay' is not active.
\begingroup
%
% prepare step (1.):
\pgfkeysalso{%
/tikz/every node/.append code={%
\ifpgf@relevantforpicturesize
\gdef\pgfplots@show@ticklabel@@update@BB{1}%
\else
\gdef\pgfplots@show@ticklabel@@update@BB{0}%
\fi
\pgf@relevantforpicturesizetrue
}%
}%
%
% Compute and remember the position '#2':
\pgf@process{#2}%
\edef\pgfplots@ticklabel@at@x{\the\pgf@x}%
\edef\pgfplots@ticklabel@at@y{\the\pgf@y}%
%
% ok, generate the label!
\node at (\pgfplots@ticklabel@at@x,\pgfplots@ticklabel@at@y) {\csname pgfplots@#1ticklabel\endcsname};%
%
% compute the label's dimensions, step (2.):
\pgfplots@ticklabel@maxtickdimen@updateforcurrentpath
{#1}
{\pgf@x=\pgfplots@ticklabel@at@x\space\pgf@y=\pgfplots@ticklabel@at@y\space}%%
%
% prepare step (3.): update of bounding box:
\if\pgfplots@show@ticklabel@@update@BB1%
\xdef\pgfplots@glob@TMPa{%
\pgf@xa=\the\pgf@picminx\space
\pgf@xb=\the\pgf@picminy\space
\pgf@ya=\the\pgf@picmaxx\space
\pgf@yb=\the\pgf@picmaxy\space
\noexpand\pgf@protocolsizes{\pgf@xa}{\pgf@xb}%
\noexpand\pgf@protocolsizes{\pgf@ya}{\pgf@yb}%
\noexpand\pgf@resetpathsizes
}%
\else
\global\let\pgfplots@glob@TMPa=\relax
\fi
\endgroup
\endpgfinterruptboundingbox
\begingroup
\pgfplots@glob@TMPa
\endgroup
\fi
}%
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{axis}[
domain=-10:10,
axis lines=middle,
]
\addplot {sin(deg(x/5))};
\end{axis}
\end{tikzpicture}
\end{document}