summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex829
1 files changed, 544 insertions, 285 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex
index facc28cbe67..76abf78a92d 100644
--- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex
+++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotsticks.code.tex
@@ -301,6 +301,8 @@
% #5: ticknumber
\def\pgfplots@show@ticklabel#1#2(#3,#4+#5)#6{%
\begingroup%
+ \edef\pgfmathresult{#2}%
+ \pgfkeyslet{/pgfplots/sloped/at position}\pgfmathresult%
\csname ifpgfplots@#1ticklabel@interval\endcsname
% Special case for the INTERVAL feature:
% we have to do additional work here.
@@ -639,6 +641,11 @@
% Check if a label does not cross the x-axis
\def\pgfplots@ytick@check@tickshow{%
\pgfplots@tickshowtrue
+ %
+ \pgfplots@if@has@axis@shift x{%
+ \pgfplots@hide@obscured@ytickfalse
+ }{}%
+ %
\ifpgfplots@hide@obscured@ytick
\if\pgfplots@yaxislinesnum2% center
\ifcase\pgfplots@xaxislinesnum\relax
@@ -682,6 +689,13 @@
}
\def\pgfplots@ztick@check@tickshow{%
\pgfplots@tickshowtrue
+ %
+ \pgfplots@if@has@axis@shift x{%
+ \pgfplots@if@has@axis@shift y{%
+ \pgfplots@hide@obscured@ztickfalse
+ }{}%
+ }{}%
+ %
\ifpgfplots@hide@obscured@ztick
\if\pgfplots@zaxislinesnum2% center
\pgfplotsmath@ifapproxequal@dim
@@ -755,15 +769,13 @@
%
% Assemble the \pgfplots@drawticklines@for@placecomputedtick
% command.
- \def\pgfplots@drawticklines@for@placecomputedtick{%
- \if\pgfplots@drawticklines@for@placecomputedtick@LOWEROK1%
- \pgfpathmoveto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@LOWER@b}{\pgfplots@tick@LOWER@shiftbeg pt}}%
- \pgfpathlineto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@LOWER@b}{\pgfplots@tick@LOWER@shiftend pt}}%
- \fi
- \if\pgfplots@drawticklines@for@placecomputedtick@UPPEROK1%
- \pgfpathmoveto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@UPPER@b}{\pgfplots@tick@UPPER@shiftbeg pt}}%
- \pgfpathlineto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@UPPER@b}{\pgfplots@tick@UPPER@shiftend pt}}%
- \fi
+ \def\pgfplots@drawticklines@for@placecomputedtick@LOWER{%
+ \pgfpathmoveto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@LOWER@b}{\pgfplots@tick@LOWER@shiftbeg pt}}%
+ \pgfpathlineto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@LOWER@b}{\pgfplots@tick@LOWER@shiftend pt}}%
+ }%
+ \def\pgfplots@drawticklines@for@placecomputedtick@UPPER{%
+ \pgfpathmoveto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@UPPER@b}{\pgfplots@tick@UPPER@shiftbeg pt}}%
+ \pgfpathlineto{\pgfplotspointonorientedsurfaceabwithbshift{\pgfplots@curtickpos}{\pgfplots@tick@UPPER@b}{\pgfplots@tick@UPPER@shiftend pt}}%
}%
%\message{place computed tick: LOWEROK=\pgfplots@drawticklines@for@placecomputedtick@LOWEROK; UPPEROK=\pgfplots@drawticklines@for@placecomputedtick@UPPEROK.}%
}%
@@ -827,6 +839,11 @@
% This is just a special case for centered axis lines.
\def\pgfplots@xtick@check@tickshow{%
\pgfplots@tickshowtrue
+ %
+ \pgfplots@if@has@axis@shift y{%
+ \pgfplots@hide@obscured@xtickfalse
+ }{}%
+ %
\ifpgfplots@hide@obscured@xtick
\if\pgfplots@xaxislinesnum2% center
\ifcase\pgfplots@yaxislinesnum\relax
@@ -1217,6 +1234,64 @@
\pgfpathlineto{\pgfplotspointonorientedsurfaceab{#1}{\csname pgfplots@\pgfplotspointonorientedsurfaceB max\endcsname}}%
}%
+% Implements 'axis x line shift' and its friends.
+%
+% It is called by grid line drawing instructions, tick lines, and tick
+% labels and installs a common shift. The purpose is to shift the
+% _entire_ axis along the outer normal.
+%
+% The operation is supposed to be used when an oriented surf is
+% installed.
+%
+% #1 used to determine the axis for which the outer normal is to be
+% determined. #1 is the 'a' value of the current oriented surf, i.e.
+% one of 0, 1, 2, or v.
+%
+% #2 same as '#1', but this here determines the 'b' value of the
+% current oriented surf.
+%
+% exactly one of '#1' or '#2' must be 'v' such that a unique line can
+% be identified.
+\def\pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf#1#2{%
+ \if v#1%
+ \let\pgfplots@loc@TMPa=\pgfplotspointonorientedsurfaceA%
+ \if v#2%
+ \pgfplots@error{Exactly one of '#1' or '#2' must be 'v', not both}%
+ \fi
+ \else
+ \if v#2%
+ \let\pgfplots@loc@TMPa=\pgfplotspointonorientedsurfaceB%
+ \else
+ \pgfplots@error{One of '#1' or '#2' must be 'v'}%
+ \fi
+ \fi
+ %
+ \pgfkeysgetvalue{/pgfplots/axis \pgfplots@loc@TMPa\space line shift}\pgfplots@loc@TMPb
+ \ifx\pgfplots@loc@TMPb\pgfutil@empty
+ \else
+ % in this case, we KNOW that is is
+ % (a) parsed and
+ % (b) nonzero and
+ % (c) a dimension WITHOUT unit
+ % See \pgfplots@init@axis@shift
+ \ifpgfplots@separate@axis@lines
+ \else
+ \pgfplots@error{Internal error encountered: separate axis lines=false but axis shift found}%
+ \fi
+ \pgftransformshift{%
+ \expandafter\pgfqpointscale\expandafter{\pgfplots@loc@TMPb}{%
+ \begingroup
+ \pgf@process{%
+ \pgfplotspointonorientedsurfaceabtolinespec{#1}{#2}%
+ \expandafter\pgfplotspointouternormalvectorofaxis\expandafter{\pgfplotsretval}%
+ }%
+ \endgroup
+ }%
+ }%
+ \fi
+}%
+\let\pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf@orig=\pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf
+
% Draws ticks on the currently active "oriented surface".
%
% The oriented surface is two dimensional and has been initialised
@@ -1384,12 +1459,29 @@
\let\pgfplots@subtickwidth@=\pgfmathresult
\let\pgfplots@subtickwidth=\pgfmathresult
\pgfplots@prepare@tick@offsets@for@{#1}{\pgfplots@subtickwidth@}%
- \pgfplotslistforeach\pgfplots@prepared@tick@positions@minor@\as\pgfplots@curtickpos{%
- \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
- \let\pgfplots@curtickpos=\pgfplots@tick
- \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
- \pgfplots@drawticklines@for@placecomputedtick
- }%
+ \if\pgfplots@drawticklines@for@placecomputedtick@LOWEROK1%
+ \begingroup
+ \pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf v0%
+ \pgfplotslistforeach\pgfplots@prepared@tick@positions@minor@\as\pgfplots@curtickpos{%
+ \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
+ \let\pgfplots@curtickpos=\pgfplots@tick
+ \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
+ \pgfplots@drawticklines@for@placecomputedtick@LOWER
+ }%
+ \endgroup
+ \fi
+ %
+ \if\pgfplots@drawticklines@for@placecomputedtick@UPPEROK1%
+ \begingroup
+ \pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf v1%
+ \pgfplotslistforeach\pgfplots@prepared@tick@positions@minor@\as\pgfplots@curtickpos{%
+ \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
+ \let\pgfplots@curtickpos=\pgfplots@tick
+ \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
+ \pgfplots@drawticklines@for@placecomputedtick@UPPER
+ }%
+ \endgroup
+ \fi
\endpgfextra;
}{}%
%
@@ -1405,12 +1497,29 @@
\let\pgfplots@tickwidth@=\pgfmathresult
\let\pgfplots@tickwidth=\pgfmathresult
\pgfplots@prepare@tick@offsets@for@{#1}{\pgfplots@tickwidth@}%
- \pgfplotslistforeach\pgfplots@prepared@tick@positions@major@\as\pgfplots@curtickpos{%
- \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
- \let\pgfplots@curtickpos=\pgfplots@tick
- \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
- \pgfplots@drawticklines@for@placecomputedtick
- }%
+ \if\pgfplots@drawticklines@for@placecomputedtick@LOWEROK1%
+ \begingroup
+ \pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf v0%
+ \pgfplotslistforeach\pgfplots@prepared@tick@positions@major@\as\pgfplots@curtickpos{%
+ \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
+ \let\pgfplots@curtickpos=\pgfplots@tick
+ \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
+ \pgfplots@drawticklines@for@placecomputedtick@LOWER
+ }%
+ \endgroup
+ \fi
+ %
+ \if\pgfplots@drawticklines@for@placecomputedtick@UPPEROK1%
+ \begingroup
+ \pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf v1%
+ \pgfplotslistforeach\pgfplots@prepared@tick@positions@major@\as\pgfplots@curtickpos{%
+ \expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
+ \let\pgfplots@curtickpos=\pgfplots@tick
+ \pgfplotspointouternormalvectorofaxissetv{}{\pgfplots@curtickpos}%
+ \pgfplots@drawticklines@for@placecomputedtick@UPPER
+ }%
+ \endgroup
+ \fi
\endpgfextra;
}{}%
%
@@ -1551,6 +1660,7 @@
\def\pgfmathlogtologten@{\pgfplotscoordmath{#1}{log to log 10}}%
%
\xdef\pgfplots@show@ticklabel@LASTTICK{}%
+ \pgfplots@transformshift@along@outer@normal@on@line@of@oriented@surf{v}{\pgfplots@ticklabelside}%
\pgfplotslistforeachungrouped\pgfplots@prepared@tick@positions@major@\as\pgfplots@curtickpos{%
\expandafter\pgfplots@prepared@tick@pos@unpack\pgfplots@curtickpos
\let\pgfplots@curtickpos=\pgfplots@tick
@@ -1684,9 +1794,18 @@
\fi
\fi
\fi
+ %
+ %
+ %
+ % suppress this warning. We cannot avoid it currently.
+ \pgfkeysgetvalue{/pgfplots/warning/missing near ticklabel at/.@cmd}\pgfplots@loc@neartickllabel@at
+ \pgfkeysdef{/pgfplots/warning/missing near ticklabel at}{}%
+ %
\pgfplots@ticklabel@maxtickdimen@prepare@for@normalvec
{#1}%
{\pgfplotspointouternormalvectorofticklabelaxis{#1}}%
+ %
+ \pgfkeyslet{/pgfplots/warning/missing near ticklabel at/.@cmd}\pgfplots@loc@neartickllabel@at%
}%
\newif\ifpgfplots@checkuniform@isfirst
@@ -1792,6 +1911,400 @@
}%
}
+% This is part of \pgfplots@assign@default@tick@foraxis and relies on
+% its temporary variables.
+%
+% INPUT:
+% \MIN : the lower axis limit of #1 (a TeX register, in transformed range)
+% \MAX : same with upper axis limit of #1
+% OUTPUT:
+% \H : will contain the (transformed) distance between adjacent ticks
+% \aftergroup\pgfplots@isuniformticktrue set if it applies
+%
+%
+\def\pgfplots@ticks@compute@tick@distance#1{%
+ % compute step size 'H':
+ \H=\MAX
+ \advance\H by-\MIN
+ \ifdim\H<0pt \H=-1\H \fi
+%\message{Axis limit #1: [\the\MIN:\the\MAX], diff = \the\H.^^J}%
+ \c@pgf@counta=\desirednumticks
+ \advance\c@pgf@counta by-1 %
+ \divide\H by\c@pgf@counta
+%\message{determining ticks for #1-axis: Wr := (width/max space between ticks) = \the\Wr, desirednumticks=max(\axisdefaulttryminticks, trunc(Wr)) = \the\desirednumticks, H#1=(axis range/(desirednumticks-1)) = \the\H^^J}%
+ %
+ % SEARCH for the NEXT FEASABLE H.
+ \edef\Hmacro{\pgf@sys@tonumber\H}%
+ \ifpgfplots@cur@is@linear
+ % CASE LINEAR AXIS
+ \ifpgfplots@is@datascaled
+ % This here works if the scaling trafo is linear.
+ \pgfplotscoordmath{#1}{datascaletrafo noshift inverse}{\Hmacro}%
+ \let\Hmacro=\pgfmathresult
+ \else
+ \pgfmathfloatparsenumber{\Hmacro}%
+ \let\Hmacro=\pgfmathresult
+ \fi
+%\message{Got T^{-1}(H#1) = \Hmacro^^J}%
+ %
+ \pgfplots@assign@default@tick@foraxis@normalizetickdist#1\Hmacro
+ \let\Hmacro=\pgfmathresult
+ %
+ % Ok, we are ready.
+ % Now, convert everything into the fixed point data
+ % range:
+ \ifpgfplots@is@datascaled
+ \pgfplotscoordmath{#1}{datascaletrafo noshift}{\Hmacro}%
+ \H=\pgfmathresult pt
+ \else
+ \pgfmathfloattofixed\Hmacro
+ \H=\pgfmathresult pt
+ \fi
+ %
+%\message{snapped-to-nicest = \Hmacro^^J}%
+ \aftergroup\pgfplots@isuniformticktrue
+ \else
+ % CASE LOG AXIS
+ %
+ % search for the "best" H= j* log(10), j an integer.
+ %
+ % And prefer j=1 if that is possible (otherwise minor
+ % ticks are not useful).
+ \pgfmath@basic@multiply@{\Hmacro}{\pgfplots@loc@log@from@display@log@scale}%
+ \let\Hmacrobaseten=\pgfmathresult
+ \expandafter\H\pgfmathresult pt
+%\message{ [ H / log(10) = \pgfmathresult ]}%
+ \ifdim\H<2pt
+ \H=1pt
+ \else
+ \ifnum\H<1pt
+ \H=1pt
+ \else
+ \expandafter\pgfmathfloor\expandafter{\pgfmathresult}%
+ \expandafter\H\pgfmathresult pt
+ \fi
+ \fi
+ \ifdim\H=1pt
+ \aftergroup\pgfplots@isuniformticktrue
+ \pgfplots@isuniformticktrue
+ \else
+ \aftergroup\pgfplots@isuniformtickfalse
+ \pgfplots@isuniformtickfalse
+ \fi
+%\message{final H=\pgf@sys@tonumber{\H} * log(10)}%
+ \H=\pgfplots@loc@log@to@display@log@scale\H
+ \fi
+ %
+}
+
+% This is part of \pgfplots@assign@default@tick@foraxis
+%
+% It overwrites the internal macros of
+% \pgfplots@assign@default@tick@foraxis
+\def\pgfplots@assign@default@tick@foraxis@autoadjust@result#1{%
+ \pgfplots@if{pgfplots@#1islinear}{%
+ \begingroup
+ \def\pgfplots@tick@returnval@ready{1}%
+ \pgfutil@ifundefined{pgfplots@assign@default@tick@foraxis@recurselevel}{%
+ \def\pgfplots@assign@default@tick@foraxis@recurselevel{1}%
+ }{%
+ \pgfplotsutil@advancestringcounter\pgfplots@assign@default@tick@foraxis@recurselevel
+ }%
+ \ifnum\pgfplots@assign@default@tick@foraxis@recurselevel<15
+ \c@pgf@counta=\axisdefaulttryminticks\relax
+ \advance\c@pgf@counta by1
+ \edef\axisdefaulttryminticks{\the\c@pgf@counta}%
+%\message{**TOO FEW TICK LABELS FOR #1. RECURSION with try min ticks=\axisdefaulttryminticks.**^^J}%
+ % recurse.
+ \pgfplots@assign@default@tick@foraxis{#1}%
+ \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPa\csname pgfplots@#1tick\endcsname
+ \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPb\csname pgfplots@tick@distance@#1\endcsname
+ \else
+ \pgfplotswarning{tick computation failed}{#1}{\axisdefaulttryminticks}\pgfeov%
+ \def\pgfplots@tick@returnval@ready{0}%
+ \fi
+ \pgfmath@smuggleone\pgfplots@tick@returnval@ready
+ \endgroup
+ }{%
+ % Case logarithmic axes and too few ticks.
+ \aftergroup\pgfplots@isuniformtickfalse
+ % ok, do something special.
+ %
+ % The idea is now to place ticks at
+ % 10^{i*h} with properly choosen 'h'.
+ %
+ % So: apply basically the SAME code as above for linear
+ % axis, just everything log 10! And keep in mind that all
+ % coordinates are actually given as natural logarithms.
+ \MIN\csname pgfplots@#1min\endcsname pt
+ \H=\MAX
+ \advance\H by-\MIN
+ \ifdim\H<0pt \H=-1\H \fi
+ \H=\pgfplots@loc@log@from@display@log@scale \H
+%\message{Axis limit #1: [\the\MIN:\the\MAX], diff/log(10) = \the\H.}%
+ \c@pgf@counta=\desirednumticks\relax
+ \advance\c@pgf@counta by-1
+ \ifnum\c@pgf@counta>2
+ % subtract one more. This algorithm here produces more
+ % ticks than the normal one which is designed for 10^i
+ \advance\c@pgf@counta by-1
+ \fi
+ \divide\H by\c@pgf@counta\relax
+%\message{determining ticks for #1-axis: Wr := (width/max space between ticks) = \the\Wr, desirednumticks=max(\axisdefaulttryminticks, trunc(Wr)) = \the\desirednumticks, H#1=(axis range/(desirednumticks-1)) = \the\H}%
+ %
+ % SEARCH for the NEXT FEASABLE H.
+ \edef\Hmacro{\pgf@sys@tonumber\H}%
+ \pgfmathfloatparsenumber{\Hmacro}%
+ \pgfplots@assign@default@tick@foraxis@normalizetickdist#1\pgfmathresult
+ %
+ \expandafter\pgfmathfloattofixed\expandafter{\pgfmathresult}%
+ \let\Hmacro=\pgfmathresult
+ \H=\Hmacro pt %
+ % Ok, our step size h for 10^{i*h} is ready!
+%\message{determined step size 10^{\Hmacro}}%
+ % Now, we want to activate the Tick set {10^{i*H}, i in \Z}
+ % compute I such that
+ % 10^{min} = 10^{I * H + rest}; |rest| < H
+ % -> I = round(xmin/H)
+ % -> MIN = I * H
+ % BUT EVERYTHING to log(10) basis!
+ \MIN=\pgfplots@loc@log@from@display@log@scale \MIN
+ \pgfmathlog@invoke@expanded\pgfmathdivide@{%
+ {\pgf@sys@tonumber\MIN}%
+ {\Hmacro}%
+ }%
+ \pgfmathsetcount{\c@pgf@counta}{\pgfmathresult}%
+ \ifdim\MIN<0pt
+ % the truncation rounds TOWARDS 0 which is not what I want.
+ \advance\c@pgf@counta by-1
+ \fi
+ \MIN=\H\relax
+ \multiply\MIN by\c@pgf@counta\relax
+ %
+ % convert back to basis 'e':
+ \MIN=\pgfplots@loc@log@to@display@log@scale\MIN\relax
+ \H=\pgfplots@loc@log@to@display@log@scale\H\relax
+ \MINH=\MIN\relax
+ \advance\MINH by\H\relax
+ }%
+}%
+
+% The key 'xtick distance' can have any value. This routine avoids
+% 'dimension too large' programmatically
+\def\pgfplots@assign@default@tick@foraxis@cap#1#2{%
+ \ifpgfplots@is@datascaled
+ \pgfplotscoordmath{#1}{datascaletrafo noshift inverse}{16000}%
+ \let\pgfplots@loc@TMPb=\pgfmathresult
+ \pgfplotscoordmath{#1}{min}{\pgfplots@loc@TMPb}{#2}%
+ \edef\pgfplots@loc@TMPc{#2}%
+ \ifx\pgfplots@loc@TMPc\pgfmathresult
+ \def\pgfplotsretval{0}%
+ \else
+ \def\pgfplotsretval{1}%
+ \fi
+ \else
+ \pgfplotscoordmath{#1}{parsenumber}{16000}%
+ \let\pgfplots@loc@TMPb=\pgfmathresult
+ \pgfplotscoordmath{#1}{parsenumber}{#2}%
+ \let\pgfplots@loc@TMPc=\pgfmathresult
+ \pgfplotscoordmath{#1}{min}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}%
+ %
+ \ifx\pgfplots@loc@TMPc\pgfmathresult
+ \def\pgfplotsretval{0}%
+ \else
+ \def\pgfplotsretval{1}%
+ \fi
+ \fi
+ %
+ \ifx1\pgfplotsretval
+ \pgfplotswarning{dimension too large in ticks}{#1}{#2}{\pgfmathresult}\pgfeov%
+ \fi
+}
+
+% This macro is NECESSARILY part of
+% \pgfplots@assign@default@tick@foraxis:
+%
+% OUTPUT:
+% \csname pgfplots@#1tick\endcsname
+% \csname pgfplots@tick@distance@#1\endcsname
+% FIXME : some \aftergroup trickery...
+\def\pgfplots@assign@default@tick@foraxis@compute#1{%
+ % Ok, we have either log or linear axis and need default
+ % ticks MIN,MIN+H,...,MAX.
+ \let\MINH=\pgf@xa
+ \let\H=\pgf@xb
+ \let\MAX=\pgf@ya
+ \let\MIN=\pgf@yb
+ %
+ \MAX=\csname pgfplots@#1max\endcsname pt %
+ \advance\MAX by0.001pt % avoid round errors
+ %\expandafter\MIN\the\c@pgf@counta pt
+ \MIN=\csname pgfplots@#1min\endcsname pt %
+ %
+ \pgfkeysgetvalue{/pgfplots/#1tick distance}\Hmacro
+ \ifx\Hmacro\pgfutil@empty
+ \pgfplots@ticks@compute@tick@distance#1%
+ \def\b@pgfplots@ticks@computed@tick@distance@is@final{0}%
+ \else
+ % ah - a user argument. OK, prefer that one over the default:
+ \pgfplotscoordmath{default}{parse}{abs(\Hmacro)}%
+ \let\Hmacro=\pgfmathresult
+ \pgfplots@assign@default@tick@foraxis@cap{#1}{\Hmacro}%
+ \let\Hmacro=\pgfmathresult
+ \ifpgfplots@cur@is@linear
+ \ifpgfplots@is@datascaled
+ \pgfplotscoordmath{#1}{datascaletrafo noshift}{\pgfmathresult}%
+ \else
+ \pgfplotscoordmath{#1}{tofixed}{\pgfmathresult}%
+ \fi
+ \H=\pgfmathresult pt
+ \pgfplots@isuniformticktrue
+ \aftergroup\pgfplots@isuniformticktrue
+ \else
+ \pgfplotscoordmath{#1}{log}{\pgfmathresult}%
+ \let\Hmacro=\pgfmathresult
+ \H=\pgfmathresult pt
+ %
+ % we don't know it. check it.
+ \pgfplots@isuniformtickfalse
+ \aftergroup\pgfplots@isuniformtickfalse
+ \fi
+ \def\b@pgfplots@ticks@computed@tick@distance@is@final{1}%
+ \fi
+%\message{Got H=\the\H\space(\Hmacro)^^J}%
+ %
+ % OK, now compute MIN/MAX :
+ \ifpgfplots@cur@is@linear
+ % The following code is carried out in floating point
+ % arithmetics because it requires large data ranges.
+ %
+ % I want to compute MIN@new := I*H where I is chosen
+ % such that MIN = I*H + rest with rest < H.
+ % The problem is the possibly large range of MIN. I
+ % can't work completely in the transformed datarange,
+ % so numbers get too large.
+ %
+ % So, compute I := int( MIN / H ) (integer truncation)
+ % in float arithmetics and then MIN@new := I*H
+ \pgfmathfloatdivide@{\csname pgfplots@#1min@unscaled@as@float\endcsname}{\Hmacro}%
+ \pgfmathfloatint@{\pgfmathresult}%
+ \pgfmathfloatmultiply@{\pgfmathresult}{\Hmacro}%
+ \let\MIN@new=\pgfmathresult
+ %
+ % Now, convert everything into the fixed point data
+ % range:
+ \ifpgfplots@is@datascaled
+ \pgfplotscoordmath{#1}{datascaletrafo}{\MIN@new}%
+ \MIN=\pgfmathresult pt
+ \else
+ \pgfmathfloattofixed\MIN@new
+ \MIN=\pgfmathresult pt
+ \fi
+ %
+ % And, since we have used finite precision, I is most
+ % likely to be large. So: subtract one H. In the worst
+ % case, this produces one tick position too much (but
+ % it won't be printed).
+ \advance\MIN by-\H\relax
+ \else
+ % Now, we want to activate the Tick set
+ % {lowest, lowest+H, ..., highest}
+ %
+ % Where
+ % lowest = I * log(10) + rest, |rest| < log(10).
+ % this is conceptionally different from the approach for
+ % linear axes, because H = j*log(10).
+ %
+ % remember the original xmin in MINH:
+ \MINH=\MIN
+ %
+ % and compute I and I*log(10) here:
+ \MIN=\pgfplots@loc@log@from@display@log@scale \MIN
+ \edef\pgfmathresult{\pgf@sys@tonumber{\MIN}}%
+ \pgfmathsetcount{\c@pgf@counta}{\pgfmathresult}%
+ \ifdim\MIN<0pt
+ % the truncation rounds TOWARDS 0 which is not what I want.
+ \advance\c@pgf@counta by-1
+ \fi
+ \MIN=\pgfplots@loc@log@to@display@log@scale pt
+ \multiply\MIN by\c@pgf@counta
+ \ifpgfplots@isuniformtick
+ \else
+ % This here is a special case to move the first tick
+ % near the lower axis limit.
+ %
+ % "Near" means either directly above or directly below ymin.
+ %
+ % My application example is as follows:
+ % Let H = 2*log(10).
+ % Furthermore, ymin = 3e-6, ymax= 8e-2. That means we can choose either
+ % 10^{-5}, 10^{-3}, 10^{-1}
+ % or
+ % 10^{-4}, 10^{-2}
+ % as ticks. Well, I prefer the first one.
+ %
+ % HEURISTICS: start as near to ymin as possible!
+ %
+ % We check here if we can come nearer to ymin if we
+ % shift the current tick by log(10):
+ % if( ymin - I * log(10) < 0.5*H -> use I+1, that means add log(10).
+ %
+ % that's equivalent to
+ % 2*(ymin - I * log(10)) - H < 0.
+ \advance\MINH by-\MIN
+ \multiply\MINH by2
+ \advance\MINH by-\H
+ %
+ \ifdim\MINH<0pt
+ \advance\MIN \pgfplots@loc@log@to@display@log@scale pt
+ \fi
+ \fi
+ \fi
+ \MINH=\MIN
+ \advance\MINH by\H
+ % Ok, now it can happen that only ONE tick label is placed in
+ % this range.
+ % That's useless, so check for it.
+ %
+ % That's the case if
+ % MIN < ORIGMIN && MAX < MIN+2 H
+ % MIN < ORIGMIN by construction (ok, MIN <= ORIGMIN by
+ % construction, but I don't care about this case).
+ % So: check only the second condition.
+%\message{Got MIN=\pgf@sys@tonumber\MIN; H=\pgf@sys@tonumber\H; MAX=\pgf@sys@tonumber\MAX.^^J}%
+ \def\pgfplots@tick@returnval@ready{0}%
+ %
+ \pgfplots@tmpa=\MINH
+ \advance\pgfplots@tmpa by\H
+ \ifdim\MAX<\pgfplots@tmpa
+ \if1\b@pgfplots@ticks@computed@tick@distance@is@final
+ % OK, we cannot auto adjust tick labels -- if if there are
+ % too few of them.
+ \else
+ \pgfplots@assign@default@tick@foraxis@autoadjust@result#1%
+ \fi
+ \fi
+ %
+ % assert that we have at least a minimal tick distance.
+ % FIXME :this minimum might actually be too small...
+ \ifdim\MINH=\MIN
+ \pgfplotsthrow{dimension too small in ticks}{#1}\pgfeov%
+ %
+ % make sure that the compilation succeeds:
+ \H=1pt %
+ \advance\MINH by\H
+ \fi
+ %
+ \if0\pgfplots@tick@returnval@ready
+ \xdef\pgfplots@glob@TMPb{\pgf@sys@tonumber{\H}}%
+ \advance\MAX by0.5\H % avoid rounding inaccuracies:
+ \xdef\pgfplots@glob@TMPa{\pgf@sys@tonumber{\MIN},\pgf@sys@tonumber{\MINH},...,\pgf@sys@tonumber{\MAX}}%
+ \fi
+%\message{final H=\the\H; returning \pgfplots@glob@TMPa.}%
+ \expandafter\let\csname pgfplots@#1tick\endcsname=\pgfplots@glob@TMPa
+ \expandafter\let\csname pgfplots@tick@distance@#1\endcsname=\pgfplots@glob@TMPb
+}%
+
% Computes tick positions using the current axis limits.
%
% Parameters:
@@ -1884,7 +2397,7 @@
\afterassignment\pgfplots@gobble@until@relax
\desirednumticks=\the\Wr\relax
\advance\desirednumticks by1
- \csname ifpgfplots@#1islinear\endcsname
+ \ifpgfplots@cur@is@linear
\ifnum\axisdefaulttryminticks>\desirednumticks\relax
\desirednumticks=\axisdefaulttryminticks\relax
\fi
@@ -1914,272 +2427,18 @@
\fi
%
\expandafter\ifx\csname pgfplots@#1tick\endcsname\pgfutil@empty
- % Ok, we have either log or linear axis and need default
- % ticks MIN,MIN+H,...,MAX.
- \let\MINH=\pgf@xa
- \let\H=\pgf@xb
- \let\MAX=\pgf@ya
- \let\MIN=\pgf@yb
- % compute step size 'H':
- \MAX=\csname pgfplots@#1max\endcsname pt %
- \advance\MAX by0.001pt % avoid round errors
- %\expandafter\MIN\the\c@pgf@counta pt
- \MIN=\csname pgfplots@#1min\endcsname pt %
- \H=\MAX
- \advance\H by-\MIN
- \ifdim\H<0pt \H=-1\H \fi
-%\message{Axis limit #1: [\the\MIN:\the\MAX], diff = \the\H.^^J}%
- \c@pgf@counta=\desirednumticks
- \advance\c@pgf@counta by-1 %
- \divide\H by\c@pgf@counta
-%\message{determining ticks for #1-axis: Wr := (width/max space between ticks) = \the\Wr, desirednumticks=max(\axisdefaulttryminticks, trunc(Wr)) = \the\desirednumticks, H#1=(axis range/(desirednumticks-1)) = \the\H^^J}%
%
- % SEARCH for the NEXT FEASABLE H.
- \edef\Hmacro{\pgf@sys@tonumber\H}%
- \ifpgfplots@cur@is@linear
- % CASE LINEAR AXIS
- \ifpgfplots@is@datascaled
- % This here works if the scaling trafo is linear.
- \pgfplotscoordmath{#1}{datascaletrafo noshift inverse}{\Hmacro}%
- \let\Hmacro=\pgfmathresult
- \else
- \pgfmathfloatparsenumber{\Hmacro}%
- \let\Hmacro=\pgfmathresult
- \fi
-%\message{Got T^{-1}(H#1) = \Hmacro^^J}%
- %
- \pgfplots@assign@default@tick@foraxis@normalizetickdist#1\Hmacro
- \let\Hmacro=\pgfmathresult
- %
-%\message{snapped-to-nicest = \Hmacro^^J}%
- \aftergroup\pgfplots@isuniformticktrue
- % The following code is carried out in floating point
- % arithmetics because it requires large data ranges.
- %
- % I want to compute MIN@new := I*H where I is chosen
- % such that MIN = I*H + rest with rest < H.
- % The problem is the possibly large range of MIN. I
- % can't work completely in the transformed datarange,
- % so numbers get too large.
- %
- % So, compute I := int( MIN / H ) (integer truncation)
- % in float arithmetics and then MIN@new := I*H
- \pgfmathfloatdivide@{\csname pgfplots@#1min@unscaled@as@float\endcsname}{\Hmacro}%
- \pgfmathfloatint@{\pgfmathresult}%
- \pgfmathfloatmultiply@{\pgfmathresult}{\Hmacro}%
- \let\MIN@new=\pgfmathresult
- % Ok, we are ready.
- % Now, convert everything into the fixed point data
- % range:
- \ifpgfplots@is@datascaled
- \pgfplotscoordmath{#1}{datascaletrafo}{\MIN@new}%
- \MIN=\pgfmathresult pt
- \pgfplotscoordmath{#1}{datascaletrafo noshift}{\Hmacro}%
- \H=\pgfmathresult pt
- \else
- \pgfmathfloattofixed\MIN@new
- \MIN=\pgfmathresult pt
- \pgfmathfloattofixed\Hmacro
- \H=\pgfmathresult pt
- \fi
- %
- % And, since we have used finite precision, I is most
- % likely to be large. So: subtract one H. In the worst
- % case, this produces one tick position too much (but
- % it won't be printed).
- \advance\MIN by-\H\relax
- \else
- % CASE LOG AXIS
- %
- % search for the "best" H= j* log(10), j an integer.
- %
- % And prefer j=1 if that is possible (otherwise minor
- % ticks are not useful).
- \pgfmath@basic@multiply@{\Hmacro}{\pgfplots@loc@log@from@display@log@scale}%
- \let\Hmacrobaseten=\pgfmathresult
- \expandafter\H\pgfmathresult pt
-%\message{ [ H / log(10) = \pgfmathresult ]}%
- \ifdim\H<2pt
- \H=1pt
- \else
- \ifnum\H<1pt
- \H=1pt
- \else
- \expandafter\pgfmathfloor\expandafter{\pgfmathresult}%
- \expandafter\H\pgfmathresult pt
- \fi
- \fi
- \ifdim\H=1pt
- \aftergroup\pgfplots@isuniformticktrue
- \pgfplots@isuniformticktrue
- \else
- \aftergroup\pgfplots@isuniformtickfalse
- \pgfplots@isuniformtickfalse
- \fi
-%\message{final H=\pgf@sys@tonumber{\H} * log(10)}%
- \H=\pgfplots@loc@log@to@display@log@scale\H
- % Now, we want to activate the Tick set
- % {lowest, lowest+H, ..., highest}
- %
- % Where
- % lowest = I * log(10) + rest, |rest| < log(10).
- % this is conceptionally different from the approach for
- % linear axes, because H = j*log(10).
- %
- % remember the original xmin in MINH:
- \MINH=\MIN
- %
- % and compute I and I*log(10) here:
- \MIN=\pgfplots@loc@log@from@display@log@scale \MIN
- \edef\pgfmathresult{\pgf@sys@tonumber{\MIN}}%
- \pgfmathsetcount{\c@pgf@counta}{\pgfmathresult}%
- \ifdim\MIN<0pt
- % the truncation rounds TOWARDS 0 which is not what I want.
- \advance\c@pgf@counta by-1
- \fi
- \MIN=\pgfplots@loc@log@to@display@log@scale pt
- \multiply\MIN by\c@pgf@counta
- \ifpgfplots@isuniformtick
- \else
- % This here is a special case to move the first tick
- % near the lower axis limit.
- %
- % "Near" means either directly above or directly below ymin.
- %
- % My application example is as follows:
- % Let H = 2*log(10).
- % Furthermore, ymin = 3e-6, ymax= 8e-2. That means we can choose either
- % 10^{-5}, 10^{-3}, 10^{-1}
- % or
- % 10^{-4}, 10^{-2}
- % as ticks. Well, I prefer the first one.
- %
- % HEURISTICS: start as near to ymin as possible!
- %
- % We check here if we can come nearer to ymin if we
- % shift the current tick by log(10):
- % if( ymin - I * log(10) < 0.5*H -> use I+1, that means add log(10).
- %
- % that's equivalent to
- % 2*(ymin - I * log(10)) - H < 0.
- \advance\MINH by-\MIN
- \multiply\MINH by2
- \advance\MINH by-\H
- %
- \ifdim\MINH<0pt
- \advance\MIN \pgfplots@loc@log@to@display@log@scale pt
- \fi
- \fi
- \fi
- \MINH=\MIN
- \advance\MINH by\H
- % Ok, now it can happen that only ONE tick label is placed in
- % this range.
- % That's useless, so check for it.
+ % OK, automatically compute ticks:
+ \pgfplots@assign@default@tick@foraxis@compute#1%
%
- % That's the case if
- % MIN < ORIGMIN && MAX < MIN+2 H
- % MIN < ORIGMIN by construction (ok, MIN <= ORIGMIN by
- % construction, but I don't care about this case).
- % So: check only the second condition.
-%\message{Got MIN=\pgf@sys@tonumber\MIN; H=\pgf@sys@tonumber\H; MAX=\pgf@sys@tonumber\MAX.^^J}%
- \def\pgfplots@tick@returnval@ready{0}%
- \pgfplots@tmpa=\MINH
- \advance\pgfplots@tmpa by\H
- \ifdim\MAX<\pgfplots@tmpa
- \pgfplots@if{pgfplots@#1islinear}{%
- \begingroup
- \def\pgfplots@tick@returnval@ready{1}%
- \pgfutil@ifundefined{pgfplots@assign@default@tick@foraxis@recurselevel}{%
- \def\pgfplots@assign@default@tick@foraxis@recurselevel{1}%
- }{%
- \pgfplotsutil@advancestringcounter\pgfplots@assign@default@tick@foraxis@recurselevel
- }%
- \ifnum\pgfplots@assign@default@tick@foraxis@recurselevel<15
- \c@pgf@counta=\axisdefaulttryminticks\relax
- \advance\c@pgf@counta by1
- \edef\axisdefaulttryminticks{\the\c@pgf@counta}%
-%\message{**TOO FEW TICK LABELS FOR #1. RECURSION with try min ticks=\axisdefaulttryminticks.**^^J}%
- % recurse.
- \pgfplots@assign@default@tick@foraxis{#1}%
- \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPa\csname pgfplots@#1tick\endcsname
- \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPb\csname pgfplots@tick@distance@#1\endcsname
- \else
- \pgfplotswarning{tick computation failed}{#1}{\axisdefaulttryminticks}\pgfeov%
- \def\pgfplots@tick@returnval@ready{0}%
- \fi
- \pgfmath@smuggleone\pgfplots@tick@returnval@ready
- \endgroup
- }{%
- % Case logarithmic axes and too few ticks.
- \aftergroup\pgfplots@isuniformtickfalse
- % ok, do something special.
- %
- % The idea is now to place ticks at
- % 10^{i*h} with properly choosen 'h'.
- %
- % So: apply basically the SAME code as above for linear
- % axis, just everything log 10! And keep in mind that all
- % coordinates are actually given as natural logarithms.
- \MIN\csname pgfplots@#1min\endcsname pt
- \H=\MAX
- \advance\H by-\MIN
- \ifdim\H<0pt \H=-1\H \fi
- \H=\pgfplots@loc@log@from@display@log@scale \H
-%\message{Axis limit #1: [\the\MIN:\the\MAX], diff/log(10) = \the\H.}%
- \c@pgf@counta=\desirednumticks\relax
- \advance\c@pgf@counta by-1
- \ifnum\c@pgf@counta>2
- % subtract one more. This algorithm here produces more
- % ticks than the normal one which is designed for 10^i
- \advance\c@pgf@counta by-1
- \fi
- \divide\H by\c@pgf@counta\relax
-%\message{determining ticks for #1-axis: Wr := (width/max space between ticks) = \the\Wr, desirednumticks=max(\axisdefaulttryminticks, trunc(Wr)) = \the\desirednumticks, H#1=(axis range/(desirednumticks-1)) = \the\H}%
- %
- % SEARCH for the NEXT FEASABLE H.
- \edef\Hmacro{\pgf@sys@tonumber\H}%
- \pgfmathfloatparsenumber{\Hmacro}%
- \pgfplots@assign@default@tick@foraxis@normalizetickdist#1\pgfmathresult
- %
- \expandafter\pgfmathfloattofixed\expandafter{\pgfmathresult}%
- \let\Hmacro=\pgfmathresult
- \H=\Hmacro pt %
- % Ok, our step size h for 10^{i*h} is ready!
-%\message{determined step size 10^{\Hmacro}}%
- % Now, we want to activate the Tick set {10^{i*H}, i in \Z}
- % compute I such that
- % 10^{min} = 10^{I * H + rest}; |rest| < H
- % -> I = round(xmin/H)
- % -> MIN = I * H
- % BUT EVERYTHING to log(10) basis!
- \MIN=\pgfplots@loc@log@from@display@log@scale \MIN
- \pgfmathlog@invoke@expanded\pgfmathdivide@{%
- {\pgf@sys@tonumber\MIN}%
- {\Hmacro}%
- }%
- \pgfmathsetcount{\c@pgf@counta}{\pgfmathresult}%
- \ifdim\MIN<0pt
- % the truncation rounds TOWARDS 0 which is not what I want.
- \advance\c@pgf@counta by-1
- \fi
- \MIN=\H\relax
- \multiply\MIN by\c@pgf@counta\relax
- %
- % convert back to basis 'e':
- \MIN=\pgfplots@loc@log@to@display@log@scale\MIN\relax
- \H=\pgfplots@loc@log@to@display@log@scale\H\relax
- \MINH=\MIN\relax
- \advance\MINH by\H\relax
- }%
- \fi
-%\message{final H=\the\H.}%
- \if0\pgfplots@tick@returnval@ready
- \xdef\pgfplots@glob@TMPb{\pgf@sys@tonumber{\H}}%
- \advance\MAX by0.5\H % avoid rounding inaccuracies:
- \xdef\pgfplots@glob@TMPa{\pgf@sys@tonumber{\MIN},\pgf@sys@tonumber{\MINH},...,\pgf@sys@tonumber{\MAX}}%
+ \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPa\csname pgfplots@#1tick\endcsname
+ \expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPb\csname pgfplots@tick@distance@#1\endcsname
+ \ifpgfplots@isuniformtick
+ \aftergroup\pgfplots@determinedefaultvalues@needs@check@uniformtickfalse
+ \else
+ % in this case, we better check...
+ \aftergroup\pgfplots@determinedefaultvalues@needs@check@uniformticktrue
\fi
- \aftergroup\pgfplots@determinedefaultvalues@needs@check@uniformtickfalse
\else
\expandafter\global\expandafter\let\expandafter\pgfplots@glob@TMPa\csname pgfplots@#1tick\endcsname
\gdef\pgfplots@glob@TMPb{}% will be computed later, in 'check uniform tick'