2

I know the title can be misleading, but I don't know how to put it better. I will correct it when I get better proposals.

I try drawing plots from external tables with pgfplots. Alas, the template I have to use is pretty narrow, thus I have to place multiple steps tightly together. This means, I define a style for my plots, such that the axis borders are in line with my document \linewidth. Unfortunately, I want to use one style for many plots, thus I do not set tick count manually (and don't want to). In the attached example, the ticks are all fine (I do not really care about them, it's for qualitative purposes only) but the outmost ticks stretch my bounding box outside, overlapping in case of two plots placed next to each other.

See the attached image for my problem, problematic parts encircled in red. Blck boxes around are fboxes displaying the image border. pgflpots with overlay tick labels

Packages used are

\usepackage{pgfplots}
\pgfplotsset{compat=1.10}

My style is defined as follows and applied to the axis environment: (neglecting colour, thickness and other irrelevant parts)

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

So what I want to do is: command the ticks to be only inside the axis. I do not want to set them manually nor move the labels nor delete the labels entirely. This means, I am fine with +-8 being the most outside ticks in this case, I would also be fine with +-9 being the most outside ticks, but I do not want the +-10 ticks in there. Does anyone have any ideas?

  • Does a workaround work for you? Add this to your graphs as a key to the axis environment (so \begin{axis}[xtick=...]): xtick={-8,-6,...,8}, for the above graph and xtick={-5,0,...,5} for the one below. – 1010011010 Jun 19 '14 at 17:05
  • As I have stated above, I do not want to "set [labels and ticks] manually". Of course this would do in a single case, but has do be done per plot. This is not what I have in mind, since I have a lot of plots in my article. – marc Jun 19 '14 at 19:17
  • Since you didn't upvote my answer, am I correct in assuming you're not entirely happy with it? – Jake Jun 22 '14 at 14:24
  • 1
    I am sorry, I am perfectly happy with your answer. I thought accepting it was enough, but I corrected that. – marc Jun 22 '14 at 15:34
2

You could achieve this by patching the internal macro that is responsible for typesetting the labels to only typeset the label if it fits completely inside the bounding box:

\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}
  • On further use, I just noticed some remaining flaws. Unfortunately I am not too well versed in understanding the internal latex syntax, thus I cannot remedy them myself. Can you please add support for the vertical axe as well and support for not rendering the ticks if the label is not rendered? – marc Jun 22 '14 at 17:21

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.