summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/pgfplots
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2008-02-18 00:19:53 +0000
committerKarl Berry <karl@freefriends.org>2008-02-18 00:19:53 +0000
commit957aeb141e1e62fc19b0aedb3bc36ad058226250 (patch)
tree8fb60c82c7d6811bcf6ea09b7d9d575093c959bd /Master/texmf-dist/tex/latex/pgfplots
parentb769336d7ffd1dc4d9b838487a070b86eab16060 (diff)
pgfplots update (17feb08)
git-svn-id: svn://tug.org/texlive/trunk@6666 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/pgfplots')
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/liststructure.sty2
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty262
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/pgfplots.sty2385
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/pgfplotshelpers.sty13
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/sciformat.sty861
5 files changed, 2558 insertions, 965 deletions
diff --git a/Master/texmf-dist/tex/latex/pgfplots/liststructure.sty b/Master/texmf-dist/tex/latex/pgfplots/liststructure.sty
index 8a0a9568449..c5930374f7d 100644
--- a/Master/texmf-dist/tex/latex/pgfplots/liststructure.sty
+++ b/Master/texmf-dist/tex/latex/pgfplots/liststructure.sty
@@ -35,7 +35,7 @@
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\ProvidesPackage{liststructure}[2008/26/01 Version 0.9]
+\ProvidesPackage{liststructure}[2008/02/17 Version 0.9.4]
\newtoks\TOKL@ta
\newtoks\TOKL@tb
diff --git a/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty b/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
index 81e252bbe27..9e9b57ea137 100644
--- a/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
+++ b/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
@@ -36,243 +36,14 @@
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\ProvidesPackage{pgfmathlog}[2008/26/01 Version 0.9.]
+\ProvidesPackage{pgfmathlog}[2008/02/17 Version 0.9.4]
\RequirePackage{pgf}[2007/01/01]
+\RequirePackage{sciformat}[2008/02/17]
+\RequirePackage{pgfplotshelpers}[2008/02/17]
-\RequirePackage{pgfplotshelpers}[2008/31/01]
-
-% Computes a normalised floating point representation for #1 of the
-% form
-% [+-]X.XXXXXXX*10^C
-% where
-% X.XXXXXX is a mantisse with first number != 0
-% and C is a count.
-%
-% This method does NOT use TeX Registers to represent the numbers! The
-% computation is COMPLETELY STRING BASED.
-% This allows numbers such at 10000000 or 5.23e-10 to be represented
-% properly, although TeX-registers would produce overflow/underflow
-% errors in these cases.
-%
-% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y
-%
-% Arguments:
-% #1 a -possibly non-normalized- number representation. Accepted input
-% format is
-% [+-]XXXXX.XXXXXX
-% [+-]XXXXX.XXXXXXeXXXX
-% [+-]0.0000XXXXXX
-% [+-]0.0000XXXXXXeXXXX
-% NOT accepted input format is
-% [+-]XXXXX [the period is missing]
-% [+-]XXXXXe10 [the period is missing]
-% [+-]0000.XXXXXX [leading zeros not supported]
-% [+-]XXXXX.XXXXXXEXXXXX [E notation not yet implemented]
-% #2 a macro name. \def#2{.....} will be used to assign the mantisse.
-% #3 a macro name. \def#3{.....} will be used to assign the exponent (base 10).
-%
-% Example:
-% \def\normalize#1{%
-% \pgfmathnormalisedfloatingpoint#1\to\M\powten\E
-% \[ #1 \mapsto \M\cdot 10^{\E} \]
-% }
-% \normalize{123.41251}%
-% \normalize{3.26101452e-06}%
+% See \sciparse docs
\def\pgfmathnormalisedfloatingpoint#1\to#2\powten#3{%
- \pgfmathnormalisedfloatingpoint@impl@possibly@signed#1\to#2\powten{#3}%
-}
-
-% first character MAY be + or -. This is checked, then
-% \pgfmathnormalisedfloatingpoint@impl@positive will be called for the
-% absolute value. The sign is inserted afterwards.
-\def\pgfmathnormalisedfloatingpoint@impl@possibly@signed#1#2\to#3\powten#4{%
- \def\pgfmathlogTMP{#1}%
- \def\pgfmathlogTMPB{-}%
- \if\pgfmathlogTMP\pgfmathlogTMPB
- \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#2.\to#3\powten{#4}%
- \edef#3{-#3}%
- \else
- \def\pgfmathlogTMPB{+}%
- \if\pgfmathlogTMP\pgfmathlogTMPB
- \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#2.\to#3\powten{#4}%
- \else
- \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#1#2.\to#3\powten{#4}%
- \fi
- \fi
-}
-
-% XXXX -> XXXX.0
-% XXXX.YYY -> XXXX.YYYY
-\def\pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#1.#2\to#3\powten#4{%
- %\tracingmacros=2\tracingcommands=2
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- \pgfmathnormalisedfloatingpoint@impl@positive@noperiod@possibly@SCI#1e\to#3\powten{#4}%
- \else
- \expandafter\pgfmathnormalisedfloatingpoint@impl@positive\pgfmathlog@pop@last@of@two@dots#1.#2\to#3\powten{#4}%
- \fi
-}
-\def\pgfmathlog@pop@last@of@two@dots#1.#2.{#1.#2}%
-
-\def\pgfmathnormalisedfloatingpoint@impl@positive@noperiod@possibly@SCI#1e#2\to#3\powten#4{%
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- % this case applies to
- % 1234 -> 1234.0
- \pgfmathnormalisedfloatingpoint@impl@positive#1.0\to#3\powten{#4}%
- \else
- % this case applies to
- % 1e1 -> 1.0e1
- % in this case, #1e#2 = 1e1e, so we have to discard a suffix 'e'.
- \edef\pgfmathlogTMP{#1.0e\pgfmathlog@popsuffix@e@expansion#2}%
- \expandafter\pgfmathnormalisedfloatingpoint@impl@positive\pgfmathlogTMP\to#3\powten{#4}%
- \fi
-}
-
-% XXXXX.XXXXX -> X.XXXXXXX * 10^4
-% 0.0000XXXXX -> X.XXXX * 10^{-5}
-%
-% or
-% XXXX.XXXXXeYYY -> X.XXXXXX* 10^{3+YYY}
-% 0.0000XXXXeYYY -> X.XXX* 10^{-5+YYY}
-%
-% this version does not accept a sign. A period is required.
-\def\pgfmathnormalisedfloatingpoint@impl@positive#1#2.#3\to#4\powten#5{%
-% \begingroup
-% FIXME! restore variables!!
- %\tracingmacros=2\tracingcommands=2
- %\tracingmacros=0\tracingcommands=0
- \pgfmathnormalisedfloatingpoint@positive@getexisting@exponent@e#3e\preexponentto\preexponentstring\exponenttocount\c@pgf@counta
- % will \c@pgf@counta will be initialised in the line above
- % \c@pgf@counta=0
- \ifnum#1=0
- % the case 0.0000XXXX
- % does also handle 0.0000XXXXeXXX
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- \c@pgf@countb=0
- \expandafter\pgfmathlog@count@leading@zeros\preexponentstring\to\c@pgf@countb
- \advance\c@pgf@countb by1
- \advance\c@pgf@counta by-\c@pgf@countb
- \edef#5{\the\c@pgf@counta}%
- \expandafter\pgfmathlog@assignmantisse\preexponentstring\to#4\countdownzerosfrom\c@pgf@countb
- \else
- % the case 000.0000XXXXX
- % is not allowed and does not make sense.
- \errmessage{INVALID NUMBER FORMAT: leading zeros 00*.* not supported yet}%
- \fi
- \else
- % the case NXXXXX.XXXXXXX
- % or NXXXXXX.XXXXXXeXXXX
- % where N in [1-9]
- \pgfmathlog@strlen#1#2\to\c@pgf@counta
- \advance\c@pgf@counta by-1
- \edef#4{#1.#2\preexponentstring}%
- \edef#5{\the\c@pgf@counta}%
- \fi
- %\tracingmacros=0\tracingcommands=0
-% \endgroup
-}
-
-% parses scientific notation and returns the exponent and everything
-% before the exponent like
-%
-% XXXXXXXeYYYY -> \def#2{XXXXXXX} #3=YYYY
-% or
-% XXXXXXXXe -> \def#2{XXXXXXXX} #3=0
-%
-% Examples:
-% - \pgfmathnormalisedfloatingpoint@exponent@e123456e\preexponentto\M\exponenttocount\acount
-% \M->123456
-% \acount=0
-% Please note that the input was 123456e -> at least 'e' is expected!
-%
-% - \pgfmathnormalisedfloatingpoint@exponent@e123456e-10e\preexponentto\M\exponenttocount\acount
-% \M->123456
-% \acount=-10
-% Again, the suffix 'e' is REQUIRED. This allows to reduce \ifs.
-\def\pgfmathnormalisedfloatingpoint@positive@getexisting@exponent@e#1e#2\preexponentto#3\exponenttocount#4{%
- \def#3{#1}%
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- #4=0
- \else
- \pgfmathlog@popsuffix@e#2\tocount{#4}%
- \fi
-}
-
-% XXXXXe -> #2=XXXXX where X in [+-0-9].
-\def\pgfmathlog@popsuffix@e#1e\tocount#2{%
- #2=#1
-}
-
-\def\pgfmathlog@popsuffix@e@expansion#1e{%
- #1%
-}%
-
-% 00000XXXXXX -> X.XXXXX
-% Inputs:
-% #1 = 00000XXXXXX
-% #2 a macro name
-% #3 a count in which the number of zeros plus one is contained (i.e.
-% the number of shifts).
-\def\pgfmathlog@assignmantisse#1\to#2\countdownzerosfrom#3{%
- \toks0={#1}%
- \loop
- \ifnum#3=1
- \else
- \expandafter\pgfmathlog@popfirst\the\toks0\to{\toks0}%
- \advance#3 by-1
- \repeat
- \edef\pgfmathlog@assignmantisseTMP{\the\toks0}%
- \ifx\pgfmathlog@assignmantisseTMP\empty
- % The case 0.0 * 10^0
- \def#2{0.0}%
- \else
- \expandafter\pgfmathlog@insertperiod\the\toks0\to{#2}%
- \fi
-}
-
-% XXXXXX -> X.XXXXX into #3
-\def\pgfmathlog@insertperiod#1#2\to#3{%
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- \def#3{#1.0}%
- \else
- \def#3{#1.#2}%
- \fi
-}
-
-% discards the first token.
-\def\pgfmathlog@popfirst#1#2\to#3{%
- #3={#2}%
-}
-
-% adds the string length of #1#2 into the count register #3.
-%
-% The register won't be initialised to zero!
-\def\pgfmathlog@strlen#1#2\to#3{%
- \advance#3 by1
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- \else
- \pgfmathlog@strlen#2\to{#3}%
- \fi
-}
-
-% Adds the number of leadings zeros of #1#2 into the count register
-% #3.
-%
-% The register won't be initialised to zero!
-\def\pgfmathlog@count@leading@zeros#1#2\to#3{%
- \ifnum#1=0
- \advance#3 by1
- \def\pgfmathlogTMP{#2}%
- \ifx\pgfmathlogTMP\empty
- \else
- \pgfmathlog@count@leading@zeros#2\to{#3}%
- \fi
- \fi
+ \sciparse#1\to#2\powten{#3}%
}
% Evaluates the natural logarithm, log(x) for 0.1<=x<=1.
@@ -386,7 +157,7 @@
\def\pgfmathlog@newton#1{%
\begingroup%
% compute #1 = M*10^E with normalised mantisse M = [+-]*[1-9].XXXXX
- \pgfmathnormalisedfloatingpoint#1\to\newtoninput@mantisse\powten\newtoninput@exponent
+ \sciparse#1\to\newtoninput@mantisse\powten\newtoninput@exponent
%
% Now, compute log(#1) = log(M) + E*log(10)
% \message{EVAL log(#1) = log(\newtoninput@mantisse) + \newtoninput@exponent*log(10) mit newton STARTS:}%
@@ -421,3 +192,24 @@
\endgroup%
}
+% Usage:
+% \pgfmathapproxequalto@macro\argone\argtwo\result
+%
+% -> will set \resulttrue or \resultfalse
+% -> check with \ifresult
+\def\pgfmathlog@approxequalto@macro#1#2#3{%
+ \begingroup%
+ \expandafter\pgfmath@x#1pt\relax%
+ \expandafter\pgfmath@y#2pt\relax%
+ \advance\pgfmath@x-\pgfmath@y%
+ \ifdim\pgfmath@x<0pt
+ \multiply\pgfmath@x by-1
+ \fi
+ \ifdim\pgfmath@x<0.0001pt\relax%
+ \expandafter\aftergroup\csname #3true\endcsname
+ \else%
+ \expandafter\aftergroup\csname #3false\endcsname
+ \fi%
+ \endgroup%
+}
+
diff --git a/Master/texmf-dist/tex/latex/pgfplots/pgfplots.sty b/Master/texmf-dist/tex/latex/pgfplots/pgfplots.sty
index 394cf16be6d..114db197b55 100644
--- a/Master/texmf-dist/tex/latex/pgfplots/pgfplots.sty
+++ b/Master/texmf-dist/tex/latex/pgfplots/pgfplots.sty
@@ -23,17 +23,33 @@
% along with this program. If not, see <http://www.gnu.org/licenses/>.
%
%--------------------------------------------
-\def\pgfplotsversion{0.92}
-\ProvidesPackage{pgfplots}[2008/31/01 Version \pgfplotsversion]
+\def\pgfplotsversion{0.92.4}
+\ProvidesPackage{pgfplots}[2008/02/17 Version \pgfplotsversion]
+
+% ATTENTION:
+% you MAY need one of
+% \def\pgfsysdriver{pgfsys-dvipdfm.def}
+% \def\pgfsysdriver{pgfsys-pdftex.def}
+% \def\pgfsysdriver{pgfsys-dvips.def}
+%
+% BEFORE the first \usepackage{pgf}, \usepackage{tikz} or
+% \usepackage{pgfplots}.
+% Default is
+% 'dvips' for 'latex'
+% 'pdftex' for 'pdflatex'
+% -> dvipdfm needs special attention.
+
\RequirePackage{xkeyval}[2006/11/18]
\RequirePackage{ifthen}
\RequirePackage{liststructure}
\RequirePackage{tikz}[2007/06/07]
+\RequirePackage{sciformat}
\RequirePackage{pgfmathlog}
\usetikzlibrary{plotmarks}
\def\prefix{pgfplots}
+% FIXME: reduce number of variables!
\newcount\axisticknum
\newcount\axis@tickposnum
\newcount\axis@xmode
@@ -46,14 +62,19 @@
\newdimen\axis@tmpa
\newdimen\axis@tmpb
\newif\ifaxis@isuniformtick
+\newif\ifaxis@enlargelimits
+\newif\ifaxis@enlargelimits@rel@thresh
+\newif\ifaxis@enlargelimits@auto
\let\axis@TMP=\empty
\let\axis@TMPB=\empty
+\let\axis@TMPC=\empty
\def\axis@leftover{}
\def\axis@rightover{}
\def\axisdefaultwidth{240pt}
\def\axisdefaultheight{207pt}
\def\axisdefaulttickwidth{35}% the maximum space between adjacent ticks (in pt, but don't specify the unit 'pt')
+\def\axisdefaulttryminticks{4}
\listnew{\blackwhiteplotspeclist}{%
mark options={fill=gray},mark=*\\%
@@ -84,56 +105,6 @@
\listcopy\coloredplotspeclist\to\autoplotspeclist%
%\listcopy\blackwhiteplotspeclist\to\autoplotspeclist%
-%--------------------------------------------------
-%
-% MARKERS:
-% mark repeat=3,mark phase=2
-% mark options={color=blue,rotate=180}
-% ball,ball color=blue
-% {*}
-% {x}
-% {+}
-% \usetikzlibrary{plotmarks}
-% {-}
-% {|}
-% {o}
-% {asterisk}
-% {star}
-% {oplus}
-% {oplus*}
-% {otimes}
-% {otimes*}
-% {square}
-% {square*}
-% {triangle}
-% {triangle*}
-% {diamond}
-% {diamond*}
-% {pentagon}
-% {pentagon*}
-%
-% LINES:
-% line width=2cm
-% [snake=zigzag]
-% [snake=brace]
-% [snake=triangles]
-% [snake=coil,segment length=4pt]
-% [snake=coil,segment aspect=0]
-% [snake=expanding waves,segment angle=7]
-% style=solid
-% style=dotted
-% style=densely dotted
-% style=loosely dotted
-% style=dashed
-% style=densely dashed
-% style=loosely dashed
-% dash pattern=on 2pt off 3pt on 4pt off 4pt
-% dash phase=10pt
-% Mit der 'double' und 'double distance' option gibts lustige effekte:
-% \draw[draw=white,double=red,very thick] (0,1) -- (1,0);
-% \draw[very thick,double distance=2pt] (1,0) arc (180:90:1cm);
-%--------------------------------------------------
-
\tikzstyle{every axis}=[]
\tikzstyle{every axis plot}=[]
\tikzstyle{every axis label}=[]
@@ -142,6 +113,10 @@
\tikzstyle{every axis title}=[at={(0.5,1)},above,yshift=6pt]
\tikzstyle{every tick}=[very thin,gray]
\tikzstyle{every minor tick}=[]
+\tikzstyle{every major tick}=[]
+\tikzstyle{every axis grid}=[style=help lines]
+\tikzstyle{every minor grid}=[]
+\tikzstyle{every major grid}=[]
\tikzstyle{every tick label}=[]
\tikzstyle{every x tick label}=[]
\tikzstyle{every y tick label}=[]
@@ -163,6 +138,8 @@
% - \tikzstyle{every axis legend}+=[at={(1,0.5)},anchor=east,outer sep=0.5cm]
% draws the legend INSIDE MIDDLE RIGHT, separated by 0.5cm from the axis.
\tikzstyle{every axis legend}=[%
+ cells={anchor=center},
+ inner xsep=3pt,inner ysep=2pt,nodes={inner sep=2pt,text depth=0.15em},
anchor=north east,%
shape=rectangle,%
fill=white,%
@@ -173,32 +150,49 @@
% outer sep=0.1cm]
-%
-% xticklabel:
-% im argument kann man '\axisticknum' und '\tick' verwenden.
-% '\tick' ist der eintrag aus '\xtick', der gerade bearbeitet wird,
-% '\axisticknum' seine nummer.
-%
-% yticklabel:
-% analog zu xticklabel.
-%
-% xfilter/yfilter
-% \def\meinxfilter#1\to#2{\def#2{1.4}}
-% xfilter=\meinxfilter
-%
-% if the filtered coordinate is empty string, it will be skipped.
\define@cmdkeys[\prefix]{axis}[axis@]{%
xmin,xmax,xticklabel,xtick,xtickten,xlabel,%
ymin,ymax,yticklabel,ytick,ytickten,ylabel,%
- trimxmin,trimxmax,trimymin,trimymax,%
subtickwidth,tickwidth,%
xfilter,yfilter,%
width,height,%
title,%
execute at begin plot,%
execute at end plot,%
+ enlargelimits,%
+ legend columns,%
x,y}%
+\long\def\axis@foreach@to@list#1\to#2{%
+ \listnewempty\axis@TMP
+ \begingroup
+ \foreach \i in {#1} {%
+ \globaldefs=1
+ \expandafter\listpushback\i\to\axis@TMP
+ \globaldefs=0
+ }%
+ \endgroup
+ \listcopy\axis@TMP\to#2\relax
+}
+
+\define@cmdkey[\prefix]{axis}[axis@]{xticklabels}{%
+ \expandafter\axis@foreach@to@list\axis@xticklabels\to\axis@xticklabels
+ %\expandafter\listnew\expandafter\axis@xticklabels\expandafter{\axis@xticklabels}%
+ \let\axis@xticklabel=\axis@user@ticklabel@list@x
+}
+\define@cmdkey[\prefix]{axis}[axis@]{yticklabels}{%
+ \expandafter\axis@foreach@to@list\axis@yticklabels\to\axis@yticklabels
+ %\expandafter\listnew\expandafter\axis@yticklabels\expandafter{\axis@yticklabels}%
+ \let\axis@yticklabel=\axis@user@ticklabel@list@y
+}
+
+\define@cmdkey[\prefix]{axis}[axis@]{minor tick length}{%
+ \expandafter\let\expandafter\axis@subtickwidth\csname axis@minor tick length\endcsname
+}
+\define@cmdkey[\prefix]{axis}[axis@]{major tick length}{%
+ \expandafter\let\expandafter\axis@tickwidth\csname axis@major tick length\endcsname
+}
+
% sets \axis@tickposnum to
% left=0
% right=1
@@ -206,11 +200,75 @@
\define@choicekey[\prefix]{axis}{tickpos}[\val\nr]{left,right,both}{%
\axis@tickposnum=\nr\relax
}
+\define@choicekey[\prefix]{axis}{legend plot pos}[\val\nr]{left,right,none}{%
+ \edef\axis@legend@plot@pos{\nr}%
+}
+
+\define@choicekey[\prefix]{axis}{anchor}[\val\nr]{north,north west,west,south west,south,south east,east,north east,center}{%
+ \edef\axis@anchorchoicenum{\nr}%
+}
+
+\define@choicekey[\prefix]{axis}{ticks}[\val\nr]{none,major,minor,both}{%
+ \expandafter\ifcase\nr\relax
+ \axis@xminorticksfalse
+ \axis@yminorticksfalse
+ \axis@xmajorticksfalse
+ \axis@ymajorticksfalse
+ \or
+ \axis@xminorticksfalse
+ \axis@yminorticksfalse
+ \axis@xmajortickstrue
+ \axis@ymajortickstrue
+ \or
+ \axis@xminortickstrue
+ \axis@yminortickstrue
+ \axis@xmajorticksfalse
+ \axis@ymajorticksfalse
+ \or
+ \axis@xminortickstrue
+ \axis@yminortickstrue
+ \axis@xmajortickstrue
+ \axis@ymajortickstrue
+ \fi
+}
+\define@choicekey[\prefix]{axis}{grid}[\val\nr]{none,major,minor,both}{%
+ \expandafter\ifcase\nr\relax
+ \axis@xminorgridsfalse
+ \axis@yminorgridsfalse
+ \axis@xmajorgridsfalse
+ \axis@ymajorgridsfalse
+ \or
+ \axis@xminorgridsfalse
+ \axis@yminorgridsfalse
+ \axis@xmajorgridstrue
+ \axis@ymajorgridstrue
+ \or
+ \axis@xminorgridstrue
+ \axis@yminorgridstrue
+ \axis@xmajorgridsfalse
+ \axis@ymajorgridsfalse
+ \or
+ \axis@xminorgridstrue
+ \axis@yminorgridstrue
+ \axis@xmajorgridstrue
+ \axis@ymajorgridstrue
+ \fi
+}
+
+
\define@boolkeys[\prefix]{axis}[axis@]{%
xminorticks,%
+ xmajorticks,%
yminorticks,%
+ ymajorticks,%
+ xminorgrids,%
+ xmajorgrids,%
+ yminorgrids,%
+ ymajorgrids,%
disablelogfilter,%
- enlargelimits}[true]
+ disabledatascaling,%
+ hide axis,%
+ scale only axis}[true]
% sets \axis@xmode to
% normal=0
@@ -226,63 +284,59 @@
\axis@ymode=\nr\relax
}
-% Options to legend:
-% textwidth=auto
-% textwidth=none
-% textwidth=DIMENSION
-\define@cmdkey[\prefix]{legend}[axis@legend@]{textwidth}[auto]{}%
-
-\define@cmdkey[\prefix]{legend}[axis@legend@]{font}[]{}
-
\long\def\axispreset#1{%
\presetkeys[\prefix]{axis}{#1}{}%
}
\long\def\legendpreset#1{%
- \presetkeys[\prefix]{legend}{#1}{}%
+ \errmessage{Sorry, legendpreset is now deprecated, along with the legend options text width and font. Legends are now TikZ-matrizes which provide better alignment and can be placed horizontally. See the manual for details.}%
}
\presetkeys[\prefix]{axis}{%
xmode=normal,
xmin=,
xmax=,
- trimxmin=,
- trimxmax=,
xlabel=,
xtick=,
xtickten=,
xticklabel=,
xminorticks=true,
+ xmajorticks=true,
+ xminorgrids=false,
+ xmajorgrids=false,
ymode=normal,
ymin=,
ymax=,
- trimymin=,
- trimymax=,
ylabel=,
ytick=,
ytickten=,
yticklabel=,
yminorticks=true,
+ ymajorticks=true,
+ yminorgrids=false,
+ ymajorgrids=false,
+ grid=none,%
tickpos=both,
xfilter=,
yfilter=,
title=,
width=,
height=,
+ anchor=south west,
subtickwidth=0.1cm,
tickwidth=0.15cm,
+ scale only axis=false,
+ hide axis=false,
+ legend columns=1,
+ legend plot pos=left,
x=,% is implicitly set by 'width' and/or '\axisdefaultwidth'
y=,% is implicitly set by 'height' and/or '\axisdefaultheight'
execute at begin plot=,%
execute at end plot=,%
- enlargelimits=false,
+ enlargelimits=auto,
disablelogfilter=false}{}
-\presetkeys[\prefix]{legend}{%
- textwidth=auto,
- font=}{}
-
-
-\def\logten{2.302585}
+\def\logten{2.3025851}
+\def\reciproc@logten{0.434294481903252}
\newcommand{\logi}[1]{%
\ifcase#1
@@ -300,7 +354,14 @@
\newcommand{\show@yticklabel}[2]{{%
\let\ticknum=#1%
- \def\tick{#2}%
+ \ifaxis@float@numerics@mode@y
+ % this here stores \\tick@S, \\tick@M, \\tick@E
+ \axis@inverse@datascaletrafo@y{#2}\to\tick
+ % .. and this here provides \tick as fixed point repr:
+ \scitofixedsingle\tick\tick
+ \else
+ \def\tick{#2}%
+ \fi
\axis@yticklabel
}}
@@ -309,10 +370,26 @@
% #2: der x wert dafuer
\newcommand{\show@xticklabel}[2]{{%
\let\ticknum=#1%
- \def\tick{#2}%
+ \ifaxis@float@numerics@mode@x
+ % this here stores \\tick@S, \\tick@M, \\tick@E
+ \axis@inverse@datascaletrafo@x{#2}\to\tick
+ % .. and this here provides \tick as fixed point repr:
+ \scitofixedsingle\tick\tick
+ \else
+ \def\tick{#2}%
+ \fi
\axis@xticklabel
}}
+\def\axis@user@ticklabel@list@x{%
+ \listselect\ticknum\of\axis@xticklabels\to\tick
+ \tick
+}
+\def\axis@user@ticklabel@list@y{%
+ \listselect\ticknum\of\axis@yticklabels\to\tick
+ \tick
+}
+
\newcommand{\axisdefaultticklabel}[0]{%
$\prettyprintnumber{\tick}$%
}
@@ -344,147 +421,184 @@
% Y-Achsen und Achsenbeschriftung LOG:
% 1: Ticks
-\newcommand{\yachse}[1]{%
+\newcommand{\axis@drawyaxis}[1]{%
+ \begingroup
+ \newif\ifneedsminorloop
\axisticknum=0
- \foreach \y in {#1} {
- %\pgfextracty{\axis@tmpa}{\pgfpointxy{0}{\logten*\y}}%
- \pgfextracty{\axis@tmpa}{\pgfpointxy{0}{\y}}%
- %
- \ifdim\axis@tmpa<\axis@ycoordminTEX
- \else
- \ifdim\axis@tmpa>\axis@ycoordmaxTEX
- \else
- % Achsenbeschriftung:
- \ifnum\axis@tickposnum=1
- \node at
- (\axis@xcoordmaxTEX\axis@leftover,\axis@tmpa)
- [right,style=every tick label,style=every y tick label]
- {\show@yticklabel\axisticknum\y};
- \else
- \node at
- (\axis@xcoordminTEX\axis@leftover,\axis@tmpa)
- [left,style=every tick label,style=every y tick label]
- {\show@yticklabel\axisticknum\y};
- \fi
- \global\advance\axisticknum by1
- \fi
- \fi
- \begin{scope}
- \clip (\axis@xcoordminTEX\axis@leftover, \axis@ycoordminTEX\axis@leftover)
- rectangle (\axis@xcoordmaxTEX\axis@rightover, \axis@ycoordmaxTEX\axis@rightover);
- % Y-Achsenticks links und rechts
- % in log:
- % beachte: log( i*10^k ) = log\i + k\log10 -> male ticks für i=1..9
+ \edef\axis@TMP{#1}%
+ \ifx\axis@TMP\empty
+ \else
\ifaxis@yminorticks
- \foreach \i in {1,...,9} {
- \pgfextracty{\axis@tmpb}{\pgfpointxy{0}{\logi\i}}%
- \advance\axis@tmpa by\axis@tmpb
- \draw[style=every tick,style=every minor tick]
+ \needsminorlooptrue
+ \fi
+ \ifaxis@yminorgrids
+ \needsminorlooptrue
+ \fi
+ \def\axis@placecomputedtick##1[##2]{%
+ \draw[##2]
\ifcase\axis@tickposnum
(\axis@xcoordminTEX\axis@leftover, \axis@tmpa)
- -- (\axis@xcoordminTEX+\axis@subtickwidth, \axis@tmpa)
+ -- (\axis@xcoordminTEX+##1, \axis@tmpa)
\or
(\axis@xcoordmaxTEX\axis@rightover, \axis@tmpa)
- -- (\axis@xcoordmaxTEX-\axis@subtickwidth, \axis@tmpa)
+ -- (\axis@xcoordmaxTEX-##1, \axis@tmpa)
\or
(\axis@xcoordminTEX\axis@leftover, \axis@tmpa)
- -- (\axis@xcoordminTEX+\axis@subtickwidth, \axis@tmpa)
+ -- (\axis@xcoordminTEX+##1, \axis@tmpa)
(\axis@xcoordmaxTEX\axis@rightover, \axis@tmpa)
- -- (\axis@xcoordmaxTEX-\axis@subtickwidth, \axis@tmpa)
+ -- (\axis@xcoordmaxTEX-##1, \axis@tmpa)
\fi
;
}%
- \fi
- \draw[style=every tick]
- \ifcase\axis@tickposnum
- (\axis@xcoordminTEX\axis@leftover,\axis@tmpa)
- -- (\axis@xcoordminTEX+\axis@tickwidth,\axis@tmpa)
- \or
- (\axis@xcoordmaxTEX\axis@rightover,\axis@tmpa)
- -- (\axis@xcoordmaxTEX-\axis@tickwidth,\axis@tmpa)
- \or
- (\axis@xcoordminTEX\axis@leftover,\axis@tmpa)
- -- (\axis@xcoordminTEX+\axis@tickwidth,\axis@tmpa)
- (\axis@xcoordmaxTEX\axis@rightover,\axis@tmpa)
- -- (\axis@xcoordmaxTEX-\axis@tickwidth,\axis@tmpa)
- \fi
- ;
- \end{scope}
- }
-}
-
-% X-Achsen und Achsenbeschriftung
-% 1: Ticks
-\newcommand{\xachse}[1]{%
- \axisticknum=0
- \foreach \x in {#1} {
- % \pgfextractx{\axis@tmpa}{\pgfpointxy{\logten*\x}{0}}%
- \pgfextractx{\axis@tmpa}{\pgfpointxy{\x}{0}}%
- %
- \ifdim\axis@tmpa<\axis@xcoordminTEX
- \else
- \ifdim\axis@tmpa>\axis@xcoordmaxTEX
+ \def\placecomputedgridline[##1]{%
+ \draw[##1]
+ (\axis@xcoordminTEX\axis@leftover, \axis@tmpa)
+ -- (\axis@xcoordmaxTEX\axis@rightover, \axis@tmpa)
+ ;
+ }%
+ \foreach \y in {#1} {
+ \pgfextracty{\axis@tmpa}{\pgfpointxy{0}{\y}}%
+ %
+ \ifdim\axis@tmpa<\axis@ycoordminTEX
\else
- % Achsenbeschriftung:
- \ifnum\axis@tickposnum=1
- \node at
- (\axis@tmpa,\axis@ycoordmaxTEX\axis@leftover)
- [above,style=every tick label,style=every x tick label]
- {\show@xticklabel\axisticknum\x};
+ \ifdim\axis@tmpa>\axis@ycoordmaxTEX
\else
- \node at
- (\axis@tmpa,\axis@ycoordminTEX\axis@leftover)
- [below,style=every tick label,style=every x tick label]
- {\show@xticklabel\axisticknum\x};
+ % Achsenbeschriftung:
+ \ifnum\axis@tickposnum=1
+ \node at
+ (\axis@xcoordmaxTEX\axis@leftover,\axis@tmpa)
+ [right,style=every tick label,style=every y tick label]
+ {\show@yticklabel\axisticknum\y};
+ \else
+ \node at
+ (\axis@xcoordminTEX\axis@leftover,\axis@tmpa)
+ [left,style=every tick label,style=every y tick label]
+ {\show@yticklabel\axisticknum\y};
+ \fi
\fi
- \global\advance\axisticknum by1
\fi
- \fi
+ \global\advance\axisticknum by1
+ \begin{scope}
+ \clip (\axis@xcoordminTEX\axis@leftover, \axis@ycoordminTEX\axis@leftover)
+ rectangle (\axis@xcoordmaxTEX\axis@rightover, \axis@ycoordmaxTEX\axis@rightover);
+ % Y-ticks left and/or right
+ % in log:
+ % log( i*10^k ) = log\i + k\log10 -> draw ticks for i=1..9
+ \ifneedsminorloop
+ \foreach \i in {1,...,9} {
+ % this code here is scoped inside of \foreach.
+ \pgfextracty{\axis@tmpb}{\pgfpointxy{0}{\logi\i}}%
+ \advance\axis@tmpa by\axis@tmpb
+ \ifaxis@yminorgrids
+ \placecomputedgridline[style=every axis grid,style=every minor grid]%
+ \fi
+ \ifaxis@yminorticks
+ \axis@placecomputedtick\axis@subtickwidth[style=every tick,style=every minor tick]%
+ \fi
+ }%
+ \fi
+ \ifaxis@ymajorgrids
+ \placecomputedgridline[style=every axis grid,style=every major grid]%
+ \fi
+ \ifaxis@ymajorticks
+ \axis@placecomputedtick\axis@tickwidth[style=every tick,style=every major tick]%
+ \fi
+ \end{scope}
+ }%
+ \fi
+ \endgroup
+}
- \begin{scope}
- \clip (\axis@xcoordminTEX\axis@leftover, \axis@ycoordminTEX\axis@leftover)
- rectangle (\axis@xcoordmaxTEX\axis@rightover, \axis@ycoordmaxTEX\axis@rightover);
- % Y-Achsenticks links und rechts
- % in log:
- % beachte: log( i*10^k ) = log\i + k\log10 -> male ticks für i=1..9
+% X-Achsen und Achsenbeschriftung
+% 1: Ticks
+\newcommand{\axis@drawxaxis}[1]{%
+ \begingroup
+ \axisticknum=0
+ \newif\ifneedsminorloop
+ \edef\axis@TMP{#1}%
+ \ifx\axis@TMP\empty
+ \else
\ifaxis@xminorticks
- \foreach \i in {1,...,9} {
- \pgfextractx{\axis@tmpb}{\pgfpointxy{\logi\i}{0}}%
- \advance\axis@tmpa by\axis@tmpb
- \draw[style=every tick,style=every minor tick]
+ \needsminorlooptrue
+ \fi
+ \ifaxis@xminorgrids
+ \needsminorlooptrue
+ \fi
+ \def\axis@placecomputedtick##1[##2]{%
+ \draw[##2]
\ifcase\axis@tickposnum
(\axis@tmpa, \axis@ycoordminTEX\axis@leftover)
- -- (\axis@tmpa, \axis@ycoordminTEX+\axis@subtickwidth)
+ -- (\axis@tmpa, \axis@ycoordminTEX+##1)
\or
(\axis@tmpa, \axis@ycoordmaxTEX\axis@rightover)
- -- (\axis@tmpa, \axis@ycoordmaxTEX-\axis@subtickwidth)
+ -- (\axis@tmpa, \axis@ycoordmaxTEX-##1)
\or
(\axis@tmpa, \axis@ycoordminTEX\axis@leftover)
- -- (\axis@tmpa, \axis@ycoordminTEX+\axis@subtickwidth)
+ -- (\axis@tmpa, \axis@ycoordminTEX+##1)
(\axis@tmpa, \axis@ycoordmaxTEX\axis@rightover)
- -- (\axis@tmpa, \axis@ycoordmaxTEX-\axis@subtickwidth)
+ -- (\axis@tmpa, \axis@ycoordmaxTEX-##1)
\fi
;
}%
- \fi
- \draw[style=every tick]
- \ifcase\axis@tickposnum
- (\axis@tmpa, \axis@ycoordminTEX\axis@leftover)
- -- (\axis@tmpa, \axis@ycoordminTEX+\axis@tickwidth)
- \or
- (\axis@tmpa, \axis@ycoordmaxTEX\axis@rightover)
- -- (\axis@tmpa, \axis@ycoordmaxTEX-\axis@tickwidth)
- \or
- (\axis@tmpa, \axis@ycoordminTEX\axis@leftover)
- -- (\axis@tmpa, \axis@ycoordminTEX+\axis@tickwidth)
- (\axis@tmpa, \axis@ycoordmaxTEX\axis@rightover)
- -- (\axis@tmpa, \axis@ycoordmaxTEX-\axis@tickwidth)
- \fi
- ;
- \end{scope}
- }
+ \def\placecomputedgridline[##1]{%
+ \draw[##1]
+ (\axis@tmpa, \axis@ycoordminTEX\axis@leftover)
+ -- (\axis@tmpa, \axis@ycoordmaxTEX\axis@rightover)
+ ;
+ }%
+ \foreach \x in {#1} {
+ \pgfextractx{\axis@tmpa}{\pgfpointxy{\x}{0}}%
+ %
+ \ifdim\axis@tmpa<\axis@xcoordminTEX
+ \else
+ \ifdim\axis@tmpa>\axis@xcoordmaxTEX
+ \else
+ % Achsenbeschriftung:
+ \ifnum\axis@tickposnum=1
+ \node at
+ (\axis@tmpa,\axis@ycoordmaxTEX\axis@leftover)
+ [above,style=every tick label,style=every x tick label]
+ {\show@xticklabel\axisticknum\x};
+ \else
+ \node at
+ (\axis@tmpa,\axis@ycoordminTEX\axis@leftover)
+ [below,style=every tick label,style=every x tick label]
+ {\show@xticklabel\axisticknum\x};
+ \fi
+ \fi
+ \fi
+ \global\advance\axisticknum by1
+ %
+ \begin{scope}
+ \clip (\axis@xcoordminTEX\axis@leftover, \axis@ycoordminTEX\axis@leftover)
+ rectangle (\axis@xcoordmaxTEX\axis@rightover, \axis@ycoordmaxTEX\axis@rightover);
+ % X-Axis ticks bottom and top
+ % in log:
+ % log( i*10^k ) = log\i + k\log10 -> draw ticks for i=1..9
+ \ifneedsminorloop
+ \foreach \i in {1,...,9} {
+ \pgfextractx{\axis@tmpb}{\pgfpointxy{\logi\i}{0}}%
+ \advance\axis@tmpa by\axis@tmpb
+ \ifaxis@xminorgrids
+ \placecomputedgridline[style=every axis grid,style=every minor grid]%
+ \fi
+ \ifaxis@xminorticks
+ \axis@placecomputedtick\axis@subtickwidth[style=every tick,style=every minor tick]%
+ \fi
+ }%
+ \fi
+ \ifaxis@xmajorgrids
+ \placecomputedgridline[style=every axis grid,style=every major grid]%
+ \fi
+ \ifaxis@xmajorticks
+ \axis@placecomputedtick\axis@tickwidth[style=every tick,style=every major tick]%
+ \fi
+ \end{scope}
+ }%
+ \fi
+ \endgroup
}
\def\axis@rememberplotspec#1{{%
@@ -505,7 +619,7 @@
\advance\c@pgf@countb by-\c@pgf@counta
\repeat
\listselect\c@pgf@countb\of\autoplotspeclist\to#1
- %\message{pgfplots.sty: using \string\autoplotspeclist\ specification no\#\the\c@pgf@countb (of \the\c@pgf@counta): #1}%
+%\message{pgfplots.sty: using \string\autoplotspeclist\ specification no\#\the\c@pgf@countb (of \the\c@pgf@counta): #1}%
\fi
}
@@ -532,135 +646,297 @@
%
% The linespec. will be used in the legend.
\long\def\addplot{%
- \@ifnextchar[{%
- \axis@addplotimpl%
- }{%
+ \@ifnextchar+{%
\axis@getautoplotspec into\nextplotspec
- % the space after ']' is required here:
- % FIXME:
- % - \addplot[]plot coordinates is NOT allowed!?
- \expandafter\axis@addplotimpl\expandafter[\nextplotspec]
+ \axis@addplotimplAPPEND
+ }{%
+ \@ifnextchar[{%
+ \axis@addplotimpl%
+ }{%
+ \axis@getautoplotspec into\nextplotspec
+ % the space after ']' is required here:
+ % FIXME:
+ % - \addplot[]plot coordinates is NOT allowed!?
+ \expandafter\axis@addplotimpl\expandafter[\nextplotspec]
+ }%
}%
}
+\long\def\axis@addplotimplAPPEND+[{%
+ \expandafter\axis@addplotimpl\expandafter[\nextplotspec,
+}
+
\long\def\axis@addplotimpl[#1] #2;{%
+%\tracingmacros=2\tracingcommands=2
% #2 = plot coordinates {...}
\ifx\csname axis@execute at begin plot\endcsname\empty
\else
\csname axis@execute at begin plot\endcsname
\fi
- \axis@rememberplotspec{[#1]}
+ \axis@rememberplotspec{[#1]}%
\ifaxis@filtercoords
% FIXME : FREE THIS VARIABLE:
- \axis@filtercoords#2\newplotcmdto\axis@filteredcoordinateplotcmd
- \ifaxis@draw@at@end
- \expandafter\axis@update@limits\axis@filteredcoordinateplotcmd;%
- \fi
- \def\axis@TMP{\axispath\draw[style=every axis plot,#1] }%
- \expandafter\axis@TMP\axis@filteredcoordinateplotcmd;%
- %\tracingmacros=2\tracingcommands=2
- %\tracingmacros=0\tracingcommands=0
+ \axis@filtercoords@and@up@limits#2;\newplotcmdto\axis@filteredcoordinateplotcmd
+ \def\axis@TMP{\axispath@impl{\draw[style=every axis plot,#1]}}%
+ \expandafter\axis@TMP\axis@filteredcoordinateplotcmd%
\else
\ifaxis@draw@at@end
- \axis@update@limits#2;%
+ \axis@update@limits{#2;}%
\fi
- \axispath\draw[style=every axis plot,#1] #2;%
+ \axispath@impl{\draw[style=every axis plot,#1]}#2;%
\fi
\ifx\csname axis@execute at end plot\endcsname\empty
\else
\csname axis@execute at end plot\endcsname
\fi
+%\tracingmacros=0\tracingcommands=0
}%
-\long\def\axis@update@limits plot coordinates #1;{%
-%\axis@update@limits@forpoint#1\axis@restinto\axis@TMP
- \def\axis@TMP{#1}%
- \def\axis@TMPB{ }%
- \ifx\axis@TMPB\axis@TMP% FIXME isn't there a better way to exclude spaces!?
- \let\axis@TMP=\empty
- \fi
- \loop
- \ifx\axis@TMP\empty
- \else
- \expandafter\axis@update@limits@forpoint\axis@TMP\axis@restinto\axis@TMP
- \ifx\axis@TMPB\axis@TMP% FIXME isn't there a better way to exclude spaces!?
- \let\axis@TMP=\empty
- \fi
- \repeat
+\long\def\axis@update@limits#1{%
+ \axis@foreach@plot@coord@do%
+ \axis@update@limits@for@one@point
+ \for
+ #1%
+ \EOI
}
-% #1: optional white spaces (will be ignored). FIXME is there a better
-% way? I could not get \ignorespaces into this ...
-\long\def\axis@update@limits@forpoint#1(#2,#3)#4\axis@restinto#5{%
+% PRECONDITIONS:
+% - 'floating point numerics active'
+% => coordinate filtering is active
+% => #1 and #2 are MACRO names
+% => these macros are encoded with \scisetcomponents
+% - no coordinate filters active
+% => #1 and #2 MAY be macros, but they must be valid TeX
+% length (without unit).
+\long\def\axis@update@limits@for@one@point#1#2{%
+%\tracingmacros=2\tracingcommands=2
+%\message{Updating limits for (#1,#2) ...}%
\ifaxis@autocompute@xlim
- \pgfmathlog@invoke@expanded\pgfmathmin@{{\axis@xmin}{#2}}%
- \let\axis@xmin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathmax@{{\axis@xmax}{#2}}%
- \let\axis@xmax=\pgfmathresult
+ \ifaxis@float@numerics@mode@x
+%\scitofixedsingle\axis@xmin\axis@TMP
+%\scitofixedsingle\axis@xmax\axis@TMPB
+%\message{current limits: xmin=\axis@TMP, xmax=\axis@TMPB}%
+ \scigetcomponents#1\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \scigetcomponents\axis@xmin\axis@lim@S\axis@lim@M\axis@lim@E
+ \scimathmin%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \and%
+ \axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \to%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \scisetcomponents\axis@xmin\axis@lim@S\axis@lim@M\axis@lim@E
+ %
+ \scigetcomponents\axis@xmax\axis@lim@S\axis@lim@M\axis@lim@E
+ \scimathmax%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \and%
+ \axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \to%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \scisetcomponents\axis@xmax\axis@lim@S\axis@lim@M\axis@lim@E
+%\scitofixedsingle\axis@xmin\axis@TMP
+%\scitofixedsingle\axis@xmax\axis@TMPB
+%\message{updated limits: xmin=\axis@TMP, xmax=\axis@TMPB}%
+ \else
+ \pgfmathmin{\axis@xmin}{#1}%
+ \let\axis@xmin=\pgfmathresult
+ \pgfmathmax{\axis@xmax}{#1}%
+ \let\axis@xmax=\pgfmathresult
+ \fi
\fi
\ifaxis@autocompute@ylim
- \pgfmathlog@invoke@expanded\pgfmathmin@{{\axis@ymin}{#3}}%
- \let\axis@ymin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathmax@{{\axis@ymax}{#3}}%
- \let\axis@ymax=\pgfmathresult
+ \ifaxis@float@numerics@mode@y
+%\scitofixedsingle\axis@ymin\axis@TMP
+%\scitofixedsingle\axis@ymax\axis@TMPB
+%\message{current limits: ymin=\axis@TMP, ymax=\axis@TMPB}%
+ \scigetcomponents#2\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \scigetcomponents\axis@ymin\axis@lim@S\axis@lim@M\axis@lim@E
+ \scimathmin%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \and%
+ \axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \to%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \scisetcomponents\axis@ymin\axis@lim@S\axis@lim@M\axis@lim@E
+ %
+ \scigetcomponents\axis@ymax\axis@lim@S\axis@lim@M\axis@lim@E
+ \scimathmax%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \and%
+ \axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \to%
+ \axis@lim@S\axis@lim@M\axis@lim@E
+ \scisetcomponents\axis@ymax\axis@lim@S\axis@lim@M\axis@lim@E
+%\scitofixedsingle\axis@ymin\axis@TMP
+%\scitofixedsingle\axis@ymax\axis@TMPB
+%\message{updated limits: ymin=\axis@TMP, ymax=\axis@TMPB}%
+ \else
+ \pgfmathmin{\axis@ymin}{#2}%
+ \let\axis@ymin=\pgfmathresult
+ \pgfmathmax{\axis@ymax}{#2}%
+ \let\axis@ymax=\pgfmathresult
+ \fi
\fi
- \def#5{#4}%
\axis@limits@are@computedtrue
+%\tracingmacros=0\tracingcommands=0
}
% Filters coordinates and writes a new, modified 'plot coordinates'
% command to macro #2.
-\long\def\axis@filtercoords plot coordinates #1\newplotcmdto#2{%
- %\edef#2{plot coordinates \verb|}|}%
+\long\def\axis@filtercoords@and@up@limits#1\newplotcmdto#2{%
\let#2=\empty
- \def\axis@TMP{#1}%
- \def\axis@TMPB{ }%
- \ifx\axis@TMPB\axis@TMP% FIXME isn't there a better way to exclude spaces!?
- \let\axis@TMP=\empty
- \fi
- \loop
- \ifx\axis@TMP\empty
- \else
- \expandafter\axis@filter@point\axis@TMP\appendto#2\axis@restinto\axis@TMP
- \ifx\axis@TMPB\axis@TMP% FIXME isn't there a better way to exclude spaces!?
- \let\axis@TMP=\empty
- \fi
- \repeat
- \edef#2{plot coordinates {#2}}%
-}
+ \let\axis@filter@output=#2
+ \axis@foreach@plot@coord@do%
+ \axis@filter@one@coord@pair
+ \for
+ #1%
+ \EOI
+ \edef#2{plot coordinates {\axis@filter@output};}%
+}%
-% #1: optional white spaces (will be ignored). FIXME is there a better
-% way? I could not get \ignorespaces into this ...
-\long\def\axis@filter@point#1(#2,#3)#4\appendto#5\axis@restinto#6{%
+\def\axis@filter@one@coord@pair#1#2{%
\ifx\axis@xfilter\empty
- \def\axis@filter@tmpx{#2}%
+ \def\axis@filter@tmp@x{#1}%
\else
- \let\axis@filter@tmpx=\empty
- \axis@xfilter#2\to\axis@filter@tmpx\relax
+ \let\axis@filter@tmp@x=\empty
+ \axis@xfilter#1\to\axis@filter@tmp@x
\fi
\ifx\axis@yfilter\empty
- \def\axis@filter@tmpy{#3}%
+ \def\axis@filter@tmp@y{#2}%
\else
- \let\axis@filter@tmpy=\empty
- \axis@yfilter#3\to\axis@filter@tmpy\relax
+ \let\axis@filter@tmp@y=\empty
+ \axis@yfilter#2\to\axis@filter@tmp@y
\fi
- \ifx\axis@filter@tmpx\empty
- \message{NOTE: coordinate (#2,#3) has been dropped because of the x-coordinate filter.}%
+ \ifx\axis@filter@tmp@x\empty
+ \message{NOTE: coordinate (#1,#2) has been dropped because of the x-coordinate filter.}%
\else
- \ifx\axis@filter@tmpy\empty
- \message{NOTE: coordinate (#2,#3) has been dropped because of the y-coordinate filter.}%
+ \ifx\axis@filter@tmp@y\empty
+ \message{NOTE: coordinate (#1,#2) has been dropped because of the y-coordinate filter.}%
\else
- \edef#5{#5 (\axis@filter@tmpx,\axis@filter@tmpy)}%
+ \ifaxis@draw@at@end
+ % update also axis limits:
+ \axis@update@limits@for@one@point{\axis@filter@tmp@x}{\axis@filter@tmp@y}%
+ \else
+ % apply data transformation directly.
+ \ifaxis@float@numerics@mode@x
+ \axis@datascaletrafo@x\axis@filter@tmp@x\to\axis@filter@tmp@x
+ \fi
+ \ifaxis@float@numerics@mode@y
+ \axis@datascaletrafo@y\axis@filter@tmp@y\to\axis@filter@tmp@y
+ \fi
+ \fi
+ % remind:
+ % \the\tokenregister
+ % will yield the contents of the token register, it will
+ % NOT expand recursively (like \expandafter)!
+ %
+ % Employ that here to maintain macros inside of
+ % \axis@filter@tmp[xy]
+ % (macros inside of those things are used by the floating
+ % point numerics to scale input data to TeX-lengths)
+ \pgfplots@toka=\expandafter{\axis@filter@output}%
+ \TOKL@ta=\expandafter{\axis@filter@tmp@x}%
+ \TOKL@tb=\expandafter{\axis@filter@tmp@y}%
+ \edef\axis@filter@output{\the\pgfplots@toka (\the\TOKL@ta,\the\TOKL@tb)}%
+%\message{FILTERING: appended \axis@filter@tmp@x,\axis@filter@tmp@y}% -> results in \axis@filter@output}%
\fi
\fi
- \def#6{#4}%
}
+
+% A looping command to loop through plot coordinates.
+% For every point, #3{X}{Y} will be invoked.
+%
+% No scoping is used during this operation, so you can access outer
+% variables.
+\long\def\axis@foreach@plot@coord@do#1\for plot coordinates #2;\EOI{%
+ \axis@foreach@plot@coord@ITERATE#1\n#2\EOI%
+}
+
+\def\axis@foreach@plot@coord@ITERATE#1\n{%
+ \@ifnextchar;{%
+ \axis@foreach@plot@coord@FINISH@SEMICOLON%
+ }{%
+ \@ifnextchar\EOI{%
+ \axis@foreach@plot@coord@FINISH%
+ }{%
+ \axis@foreach@plot@coord@NEXT#1\n%
+ }%
+ }%
+}
+
+\def\axis@foreach@plot@coord@NEXT#1\n(#2,#3){%
+ #1{#2}{#3}%
+ \axis@foreach@plot@coord@ITERATE#1\n
+}
+
+\def\axis@foreach@plot@coord@FINISH\EOI{}
+\def\axis@foreach@plot@coord@FINISH@SEMICOLON;\EOI{}
+
+% INPUT:
+% a sequence of points (SMeE,SMeE) (terminated with ';')
+% where S=sign, M=mantisse, E = exponent.
+% Such input is generated in the case axis@float@numerics@modetrue
+% by the coordinate filters.
+% OUTPUT:
+% proper sequence of fixed point coordinates which are the result of the
+% data scaling transformation (\axis@datascaletrafo@x).
+%
+% The output will be written into the macro #1.
+\long\def\axis@apply@data@scaletrafo@to@plot@data#1\to#2{%
+ \let#2=\empty
+ \let\axis@data@scaletrafo@result=\empty
+ \axis@foreach@plot@coord@do
+ \axis@apply@data@scaletrafo@to@one@point
+ \for
+ #1%
+ \EOI
+ \edef#2{plot coordinates {\axis@data@scaletrafo@result};}%
+ %\axis@apply@data@scaletrafo@to@plot@data@ITERATE\to#2 #1;%
+}
+
+\def\axis@apply@data@scaletrafo@to@one@point#1#2{%
+ \ifaxis@float@numerics@mode@x
+ \axis@decode@filtered@float@numerics#1\to\axis@filter@tmp@x
+ \axis@datascaletrafo@x\axis@filter@tmp@x\to\axis@filter@tmp@x
+ \else
+ \def\axis@filter@tmp@x{#1}%
+ \fi
+ \ifaxis@float@numerics@mode@y
+ \axis@decode@filtered@float@numerics#2\to\axis@filter@tmp@y
+ \axis@datascaletrafo@y\axis@filter@tmp@y\to\axis@filter@tmp@y
+ \else
+ \def\axis@filter@tmp@y{#2}%
+ \fi
+ \edef\axis@data@scaletrafo@result{\axis@data@scaletrafo@result (\axis@filter@tmp@x,\axis@filter@tmp@y)}%
+}
+
+
+\def\axis@decode@filtered@float@numerics#1#2e#3\to#4{%
+ \scisetcomponents#4{#1}{#2}{#3}%
+}
+
+
\long\def\axispath#1;{%
+ \axispath@impl{}#1;
+}
+
+% low-level \axispath implementation.
+% #1:
+% the command which is responsable for drawing.
+% - If #1 is NOT '\empty', we expect #2 to contain only
+% EXPANDABLE DATA.
+% That's important for postponed floating point arithmetics in #2.
+% - If #1='\empty', we don't make any assumption about #2
+% and process it as-is.
+%
+% #2: see above.
+\long\def\axispath@impl#1#2;{%
\ifaxis@draw@at@end
- \listpushback{#1;}\to\axis@draw@stored@plots%
+ \listpushback{#1}\to\axis@stored@plot@cmds
+ \listpushback{#2;}\to\axis@stored@plot@data
\else
- #1;%
+ #1#2;%
\fi
}
@@ -668,27 +944,14 @@
% Assigns a legend.
% Syntax:
% \legend{entry 1\\entry2\\entry3}
-% or
-% \legend[OPTIONS]{entry 1\\entry2\\}
-%
-% where OPTIONS is
-% - textwidth=auto | DIMEN | none
-% like
-% \legend[textwidth=auto]{entry 1\\entry2\\}
-% \legend[textwidth=2cm}{...}
-% \legend[textwidth=none}{...}
-%
-% The option "textwidth=auto" chooses the correct width automatically;
-% the option "textwidth=none" does not perform any line breaking and
-% "textwidth=DIMEN" uses the fixed dimenion DIMEN for the (total)
-% width of the legend.
-%
-% - font={...}
-% \legend[font=\Huge}{...}
\newcommand{\legend}[2][]{
{%
\globaldefs=1% this will ONLY store the options and the legend into global variables
- \setkeys[\prefix]{legend}{#1}%
+ \def\axis@TMP{#1}%
+ \ifx\axis@TMP\empty
+ \else
+ \errmessage{Sorry, legend are now deprecated. Legends are now TikZ-matrizes which provide better alignment and can be placed horizontally. See the manual for details.}%
+ \fi
\def\axis@TMP{#2}%
\ifx\axis@TMP\empty
\else
@@ -704,7 +967,7 @@
}%
}
-\def\getnextlegend{{%
+\def\axis@pop@next@legend{{%
\globaldefs=1
\listcheckempty\axis@plotspeclist
\iflistempty
@@ -722,116 +985,109 @@
\advance\axis@numplots by-1
}}
-\def\axis@setlegendfont{%
- \tikz@textfont
- \axis@legend@font
-}
-
-% Helper function for \axis@createlegend
-% It assigns the TOTAL width of the legend node to
-% the dimension register #1 and the option to #2 as macro.
-% Arguments:
-% #1 a temporary dimension register which will be filled with the
-% width.
-% #2 a macro name which will be filled with 'text width=XXXX'.
-% WARNING:
-% this function use the variables
-% - \axis@legend@textwidth (from keyval, see above)
-% - \axis@TMP
-% - \legendCOORDC
-% - \legendHSEP
-\def\axis@legend@determinewidth\to#1\optionto#2{%
- \def\axis@TMP{auto}%
- \ifx\axis@legend@textwidth\axis@TMP
- % OPTION
- % \legend[textwidth=auto]
+\long\def\axis@show@small@legendplots#1{
+ \draw#1
+ [mark repeat=2,mark phase=2]
+ plot coordinates {
+ (0cm,0cm)
+ (0.3cm,0cm)
+ (0.6cm,0cm)%
+ };%
+}
+
+% Typesets a legend node.
+%
+% It will either typeset a previously computed legend (which needs to be
+% stored in the macro \axis@already@computed@legend@node)
+%
+% or it creates a legend, stores the commands into the macro named
+% above and typesets it.
+\newcommand\axis@createlegend{%
+ \ifx\axis@already@computed@legend@node\empty
+ \listcheckempty\axis@legend
+ \iflistempty
+ \else
%
- % STEP 1: maximum width legend entries
- #1=0cm
+ %
\begingroup
- \listforeach\axis@legend\as\axis@curlegend{%
- \setbox0=\hbox{{%
- \pgfutil@selectfont% RESTORE normal fonts (have been resetted by PGF)
- \axis@setlegendfont
- \axis@curlegend%
- }}%
- \ifdim\wd0>#1
- \global#1=\wd0
- \fi
- }%
+ % assemble a
+ % \matrix {
+ % small plot & legend1\\
+ % small plot & legend2\\
+ % ...
+ % };
+ % command [and using the 'legend columns' option]
+ %
+ % \TOKL@ta={
+ % small plot & legend1\\
+ % small plot & legend2\\
+ % ...
+ % }
+ % ( I have allocated the token register in my simplelist.sty)
+ %
+ % \global\def\axis@TMP{
+ % \matrix {
+ % \TOKL@TA
+ % };
+ % }
+ % -> finally, \axis@TMP will contain the complete command.
+ \TOKL@ta={}%
+ \let\curcolumnNum=\c@pgf@counta
+ \let\maxcolumnCount=\c@pgf@countb
+ \let\legendplotpos=\c@pgf@countc
+ \legendplotpos\expandafter=\axis@legend@plot@pos
+ \curcolumnNum=0
+ \maxcolumnCount\expandafter=\csname axis@legend columns\endcsname\relax
+ %
+ \loop
+ \ifnum0<\axis@numplots\relax
+ \axis@pop@next@legend
+ \ifx\axis@curlegend\empty
+ \else
+ \advance\curcolumnNum by1
+ \edef\axis@TMP{%
+ \the\TOKL@ta
+ \ifcase\legendplotpos
+ % legend plot pos=left
+ \noexpand\axis@show@small@legendplots{\axis@curplotlist}%
+ \noexpand\pgfmatrixnextcell
+ \noexpand\node {\axis@curlegend};
+ \or
+ % legend plot pos=right
+ \noexpand\node {\axis@curlegend};
+ \noexpand\pgfmatrixnextcell
+ \noexpand\axis@show@small@legendplots{\axis@curplotlist}%
+ \or
+ % legend plot pos=none
+ \noexpand\node {\axis@curlegend};
+ \fi
+ \ifnum\curcolumnNum=\maxcolumnCount
+ \noexpand\\
+ \else
+ \ifnum\axis@numplots=0
+ \noexpand\\
+ \else
+ \noexpand\pgfmatrixnextcell
+ \fi
+ \fi
+ }%
+ \ifnum\curcolumnNum=\maxcolumnCount
+ \curcolumnNum=0
+ \fi
+ \expandafter\TOKL@ta\expandafter{\axis@TMP}%
+ \fi
+ \repeat
+ \TOKL@tb={\matrix[style=every axis legend]}%
+ \xdef\axis@TMP{%
+ \the\TOKL@tb {%
+ \the\TOKL@ta
+ };%
+ }%
\endgroup
- % STEP 2: add plot spec width:
- \expandafter\axis@tmpb\legendCOORDC
- \advance#1 by\axis@tmpb
- % STEP 3: hspace between plot spec and legend:
- \advance#1 by\legendHSEP
- %\advance#1 by1pt% FIXME I don't know why there was to few place!?
- \def#2{text width=\the#1,}%
- \else
- \def\axis@TMP{none}%
- \ifx\axis@legend@textwidth\axis@TMP
- % OPTION
- % \legend[textwidth=none]
- % don't make a '\node[text width=XX]' option:
- #1=0cm
- \def#2{}%
- \else
- % OPTION
- % \legend[textwidth=2cm]
- % just use it:
- \expandafter#1\axis@legend@textwidth
- \def#2{text width=\the#1,}%
+ \let\axis@already@computed@legend@node=\axis@TMP
\fi
\fi
- %
-}
-
-\newcommand\axis@createlegend{%
- \listcheckempty\axis@legend
- \iflistempty
- \else
- %
- \def\legendHSEP{5pt}%
- \def\legendCOORDB{0.3cm}%
- \def\legendCOORDC{0.6cm}%
- %
- \axis@legend@determinewidth\to\pgf@xa\optionto\axis@TMP
- %
- %
- % This code here invokes
- % \node[<CONTENTS OF \axis@TMP>,
- % ...
- % ]
- % where \axis@TMP contains a "text width=XXX" option.
- %DEBUG:
- %\draw[red] (0,0) rectangle (1,1);
- \expandafter\node\expandafter[\axis@TMP%
- style=every axis legend]
- {%
- \loop\ifnum0<\axis@numplots
- \getnextlegend
- \ifx\axis@curlegend\empty
- \else
- \vbox{%
- \noindent
- \begin{minipage}[c]{\legendCOORDC}%
- \tikz
- \expandafter\draw\axis@curplotlist
- [mark repeat=2,mark phase=2]
- plot coordinates {
- (0cm,0cm)
- (\legendCOORDB,0cm)
- (\legendCOORDC,0cm)};%
- \hss
- \end{minipage}
- %\expandafter\hskip\legendHSEP
- \axis@setlegendfont
- \axis@curlegend
- }%
- \fi
- \repeat
- };
- \fi
+ \axis@already@computed@legend@node
}
% Checks whether the argument to xtick or ytick is a UNIFORM tick
@@ -857,18 +1113,19 @@
\begingroup
\global\axis@isuniformticktrue
\newif\ifisfirst
+ \newif\iftwo@are@equal
\isfirsttrue
\foreach \x in {#1}{%
- \pgfmathlog@invoke@expanded\pgfmathdivide@{{\x}{\logten}}%
+ \pgfmathmultiply@\x\reciproc@logten
\let\cur=\pgfmathresult
% check whether
% \cur - last == 1 (last = \axis@TMPB)
\ifisfirst
\global\isfirstfalse
\else
- \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\cur}{\axis@TMPB}}%
- \def\axis@TMP{1.0}%
- \ifx\axis@TMP\pgfmathresult
+ \pgfmathsubtract@\cur\axis@TMPB%
+ \pgfmathlog@approxequalto@macro\pgfmathresult{1.0}{two@are@equal}%
+ \iftwo@are@equal
\else
\global\axis@isuniformtickfalse
\breakforeach
@@ -892,14 +1149,14 @@
}
\def\logtologtentomacro#1#2{%
- \pgfmathlog@invoke@expanded\pgfmathdivide@{{#1}{\logten}}%
+ \pgfmathmultiply@{#1}\reciproc@logten%
\expandafter\skipsuffixzero\pgfmathresult|%
\let#2=\pgfmathresult
}
% Expands to #1/log(10). It will also skip a suffix '.0'
\def\logtologten#1{%
- \pgfmathlog@invoke@expanded\pgfmathdivide@{{#1}{\logten}}%
+ \pgfmathmultiply@{#1}\reciproc@logten%
\expandafter\skipsuffixzero\pgfmathresult|%
\pgfmathresult
}
@@ -909,7 +1166,7 @@
\def\axis@compute@tick@times@logten#1\to#2{%
\global\let#2=\empty
\foreach \axis@TMPB in {#1} {%
- \pgfmathlog@invoke@expanded\pgfmathmultiply@{{\axis@TMPB}{\logten}}%
+ \pgfmathmultiply@\axis@TMPB\logten%
\ifx#2\empty
\xdef#2{\pgfmathresult}%
\else
@@ -918,43 +1175,77 @@
}%
}
-\def\axis@enlarge@xlim{%
- \ifcase\axis@xmode
- \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\axis@xmin}{0.5}}%
- \let\axis@xmin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathadd@{{\axis@xmax}{0.5}}%
- \let\axis@xmax=\pgfmathresult
+\def\axis@init@enlarge@limit@booleans{%
+ \axis@enlargelimits@autofalse
+ \axis@enlargelimitsfalse
+ \axis@enlargelimits@rel@threshfalse
+ \edef\axis@TMP{\axis@enlargelimits}%
+ %
+ \def\axis@TMPB{true}%
+ \ifx\axis@TMP\axis@TMPB
+ \axis@enlargelimitstrue
+ \else
+ \def\axis@TMPB{false}%
+ \ifx\axis@TMP\axis@TMPB
+ \else
+ \def\axis@TMPB{auto}%
+ \ifx\axis@TMP\axis@TMPB
+ \axis@enlargelimits@autotrue
+ \else
+ \begingroup
+ % try to read it as number:
+ \expandafter\pgf@xa\axis@enlargelimits pt\relax
+ \endgroup
+ \axis@enlargelimitstrue
+ \axis@enlargelimits@rel@threshtrue
+ \fi
+ \fi
+ \fi
+}
+
+\def\axis@enlarge@limit@for#1{%
+ \begingroup
+ \expandafter\let\expandafter\min\expandafter=\csname axis@#1min\endcsname
+ \expandafter\let\expandafter\max\expandafter=\csname axis@#1max\endcsname
+ \ifcase\csname axis@#1mode\endcsname
+ \ifaxis@enlargelimits@rel@thresh
+ \edef\enlargepercent{\axis@enlargelimits}%
+ \else
+ \def\enlargepercent{0.1}% FIXME : pack 10% as default into option 'enlargelimits' or so
+ \fi
+ \pgfmathsubtract@\max\min%
+ \expandafter\pgf@xa\pgfmathresult pt
+ \expandafter\pgf@xb\enlargepercent\pgf@xa
+ \ifdim\pgf@xb>0.001pt
+ % the case with
+ % enlargeabsolute ~= 0
+ % means that \min ~= \max.
+ % It is handled in another method.
+ \edef\enlargeabsolute{\pgf@sys@tonumber{\pgf@xb}}%
+ %
+ % compute xmin := xmin - enlargeabsolute
+ \pgfmathsubtract@\min\enlargeabsolute%
+ \let\min=\pgfmathresult
+ \pgfmathadd@\max\enlargeabsolute%
+ \let\max=\pgfmathresult
+ \fi
\or
% compute
- % \pgfmathsetmacro{\axis@xmin}{\axis@xmin - 0.5*\logten}%
- % \pgfmathsetmacro{\axis@xmax}{\axis@xmax + 0.5*\logten}%
+ % \pgfmathsetmacro{\min}{\min - 0.5*\logten}%
+ % \pgfmathsetmacro{\max}{\max + 0.5*\logten}%
% just a more efficiently (I hope so):
\expandafter\pgfmath@x\logten pt
\divide\pgfmath@x by2
- \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\axis@xmin}{\pgf@sys@tonumber{\pgfmath@x}}}%
- \let\axis@xmin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathadd@{{\axis@xmax}{\pgf@sys@tonumber{\pgfmath@x}}}%
- \let\axis@xmax=\pgfmathresult
- \fi
-}
-\def\axis@enlarge@ylim{%
- \ifcase\axis@ymode
- \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\axis@ymin}{0.5}}%
- \let\axis@ymin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathadd@{{\axis@ymax}{0.5}}%
- \let\axis@ymax=\pgfmathresult
- \or
- % compute
- % \pgfmathsetmacro{\axis@ymin}{\axis@ymin - 0.5*\logten}%
- % \pgfmathsetmacro{\axis@ymax}{\axis@ymax + 0.5*\logten}%
- % just a more efficiently (I hope so):
- \expandafter\pgfmath@y\logten pt
- \divide\pgfmath@y by2
- \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\axis@ymin}{\pgf@sys@tonumber{\pgfmath@y}}}%
- \let\axis@ymin=\pgfmathresult
- \pgfmathlog@invoke@expanded\pgfmathadd@{{\axis@ymax}{\pgf@sys@tonumber{\pgfmath@y}}}%
- \let\axis@ymax=\pgfmathresult
+ \pgfmathlog@invoke@expanded\pgfmathsubtract@{{\min}{\pgf@sys@tonumber{\pgfmath@x}}}%
+ \let\min=\pgfmathresult
+ \pgfmathlog@invoke@expanded\pgfmathadd@{{\max}{\pgf@sys@tonumber{\pgfmath@x}}}%
+ \let\max=\pgfmathresult
\fi
+ \xdef\axis@TMP{\min}%
+ \xdef\axis@TMPB{\max}%
+ \endgroup
+ \expandafter\let\csname axis@#1min\endcsname=\axis@TMP
+ \expandafter\let\csname axis@#1max\endcsname=\axis@TMPB
}
% Computes tick positions using the current axis limits.
@@ -963,13 +1254,32 @@
% \axisdefaulttickwidth
% Determines the maximum space which is not filled by at least one
% tick label (approximate, there is some rounding internally)
+% \axisdefaulttryminticks
+% see manual
+%
+% Idea:
+% We want ticks at each
+% { i*H, i in \Z }.
+% Of course, there shouldn't be TOO MUCH ticks.
+%
+% Our heuristics is to set
+% desirednumticks = round(ACTUAL WIDTH / axisdefaulttickwidth)
+% and generate H = (axis range) / desirednumticks.
%
-% Heuristics:
-% Set desirednumticks = trunc(ACTUAL WIDTH / axisdefaulttickwidth) +1
+% Since not all step sizes H look well, restrict H to a set of allowed
+% step sizes such as
+% { 1, 1/2, 1/5, 1/10 },
+% or, to be more precise:
+% { 1*10^e, 2*10^e, 5*10^e }
+% -> round to the nearest matching number!
%
-% and generate STEPSIZE = (axis range)/ desirednumticks
+% Then, the resulting tick is
+% TICK={MIN,MIN+H,...,MAX}
+% where
+% MIN = I*H
+% is chosen such that
+% axis minimum limit = I*H + rest; |rest| < H.
%
-% We actually restrict STEPSIZE to { 1, 1/2, 1/5, 1/10 }
%
% PRECONDITION:
% - limits are correct
@@ -980,6 +1290,11 @@
% - \ifaxis@needs@check@uniformtick is set
\def\axis@assign@default@tick@foraxis#1{%
\begingroup
+ % Shortcut-names:
+ \expandafter\let\expandafter\ifaxis@is@datascaled\csname ifaxis@float@numerics@mode@#1\endcsname
+ \expandafter\let\expandafter\axis@data@scale@trafo\csname axis@datascaletrafo@#1\endcsname
+ \expandafter\let\expandafter\axis@data@scale@inverse@trafo\csname axis@inverse@datascaletrafo@#1\endcsname
+ %
\let\desirednumticks=\c@pgf@countd
\let\Wr=\pgf@xc
\Wr=\csname axis@#1coordmaxTEX\endcsname
@@ -988,48 +1303,89 @@
\expandafter\expandafter\divide\Wr\axisdefaulttickwidth
\pgfmathsetcount{\desirednumticks}{\Wr}%
\advance\desirednumticks by1
+ \expandafter\ifnum\axisdefaulttryminticks>\desirednumticks
+ \expandafter\desirednumticks\axisdefaulttryminticks
+ \fi
\ifcase\csname axis@#1mode\endcsname
- % compute tick := MIN-h,MIN,....,MAX+h
- % where h is a determined step size and MIN and MAX are
- % (truncated) axis limits.
- %
- % The MIN-h and MAX+h is to support compatibility with the
- % enlargelimits option - there should be ticks in the
- % enlarged place.
- \pgfmathsetcount{\c@pgf@counta}{\csname axis@#1min\endcsname}%
- %\pgfmathsetcount{\c@pgf@countb}{\csname axis@#1max\endcsname}%
- \expandafter\ifdim\csname axis@#1min\endcsname pt<0pt
- % the truncation round TOWARDS 0 which is not what I want.
- \advance\c@pgf@counta by-1
- \fi
+ % compute tick := MIN,MIN+H,....,MAX
\let\MINH=\pgf@xa
\let\H=\pgf@xb
\let\MAX=\axis@tmpa
\let\MIN=\axis@tmpb
- % compute step size 'h':
+ % compute step size 'H':
\expandafter\MAX\csname axis@#1max\endcsname pt
\advance\MAX by0.001pt% avoid round errors
- \expandafter\MIN\the\c@pgf@counta pt
+ %\expandafter\MIN\the\c@pgf@counta pt
+ \expandafter\MIN\csname axis@#1min\endcsname pt
\H=\MAX
\advance\H by-\MIN
\c@pgf@counta=\desirednumticks
\advance\c@pgf@counta by-1
\divide\H by\c@pgf@counta
- %\message{Wr\the\Wr, desirednumticks=\the\desirednumticks, H=\the\H}%
- \ifdim\H<0.10001pt
- \H=0.1pt
+%\message{determining ticks for #1-axis: Wr := (width/max space between ticks) = \the\Wr, desirednumticks=max(\axisdefaulttryminticks, trunc(Wr)) = \the\desirednumticks, H=(axis range/(desirednumticks-1)) = \the\H}%
+ %
+ % SEARCH for the NEXT FEASABLE H.
+ %
+ \edef\Hmacro{\pgf@sys@tonumber\H}%
+ \ifaxis@is@datascaled
+ \expandafter\axis@data@scale@inverse@trafo\Hmacro\to\Hmacro
+ \else
+ \expandafter\sciparsesignsingle\expandafter{\Hmacro}\Hmacro
+ \fi
+ \scigetcomponents\Hmacro\H@S\H@M\H@E
+%\message{Got T^{-1}(H) = [\H@S] \H@M * 10^\H@E}%
+ % modify the mantisse:
+ \expandafter\H\H@M pt
+ \ifdim\H<2pt
+ \ifdim\H<1.5pt
+ \def\H@M{1.0}%
+ \else
+ \def\H@M{2.0}%
+ \fi
\else
- \ifdim\H<0.20001pt
- \H=0.2pt
+ \ifdim\H<4.9999pt
+ \ifdim\H<3.5pt
+ \def\H@M{2.0}%
+ \else
+ \def\H@M{5.0}%
+ \fi
\else
- \ifdim\H<0.5001pt
- \H=0.5pt
+ \ifdim\H<7.5pt
+ \def\H@M{5.0}%
\else
- \H=1pt
+ \def\H@M{1.0}%
+ \expandafter\c@pgf@counta\H@E
+ \advance\c@pgf@counta by1
+ \edef\H@E{\the\c@pgf@counta}%
\fi
\fi
\fi
- %\message{final H=\the\H}%
+ \scisetcomponents\Hmacro\H@S\H@M\H@E
+ \ifaxis@is@datascaled
+ \axis@data@scale@trafo\Hmacro\to\Hmacro
+ \else
+ \scitofixedsingle\Hmacro\Hmacro
+ \fi
+%\message{I have computed H=\Hmacro}%
+ \expandafter\H\Hmacro pt
+%\message{final H=\the\H}%
+ %
+ % Now, we want to activate the Tick set {i*H, i in \Z}
+ % compute I such that
+ % xmin = I * H + rest; |rest| < H
+ % -> I = round(xmin/H)
+ % -> MIN = I * H
+ \pgfmathlog@invoke@expanded\pgfmathdivide@{%
+ {\pgf@sys@tonumber\MIN}%
+ {\pgf@sys@tonumber\H}%
+ }%
+ \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
+ \multiply\MIN by\c@pgf@counta
\MINH=\MIN
\advance\MINH by\H
\xdef\axis@TMP{\pgf@sys@tonumber{\MIN},\pgf@sys@tonumber{\MINH},...,\pgf@sys@tonumber{\MAX}}%
@@ -1037,9 +1393,11 @@
\or
\expandafter\ifx\csname axis@#1tickten\endcsname\empty
% I want ticks at 10^k. So determine k_min and k_max.
- \pgfmathsetcount{\c@pgf@counta}{\csname axis@#1min\endcsname/\logten-1}%
+ %
+ % FIXME: optimize!
+ \pgfmathsetcount{\c@pgf@counta}{\csname axis@#1min\endcsname*\reciproc@logten-1}%
\pgfmathsetmacro{\tmp@min}{\c@pgf@counta*\logten}%
- \pgfmathsetcount{\c@pgf@counta}{\csname axis@#1max\endcsname/\logten}%
+ \pgfmathsetcount{\c@pgf@counta}{\csname axis@#1max\endcsname*\reciproc@logten}%
\pgfmathsetmacro{\tmp@max}{\c@pgf@counta*\logten}%
\pgfmathadd\tmp@min\logten%
\xdef\axis@TMP{\tmp@min,\pgfmathresult,...,\tmp@max}%
@@ -1052,55 +1410,182 @@
\fi
\endgroup
\expandafter\let\csname axis@#1tick\endcsname=\axis@TMP
- %\message{pgfplots.sty: #1tick set to \csname axis@#1tick\endcsname [#1mode=\the\csname axis@#1mode\endcsname, #1min=\csname axis@#1min\endcsname, #1max=\csname axis@#1max\endcsname].}%
+%\message{pgfplots.sty: #1tick set to \csname axis@#1tick\endcsname [#1mode=\the\csname axis@#1mode\endcsname, #1min=\csname axis@#1min\endcsname, #1max=\csname axis@#1max\endcsname].}%
}
-\def\axis@determinedefaultvalues{%
- % NOTIZ:
+% Helper method for
+% \axis@apply@data@scale@trafo@to@options@for
+% #1: the ticks
+% #2: the trafo macro name (the form taking three args)
+% #3: the output macro name
+\long\def\axis@apply@data@scale@trafo@to@user@ticks#1#2\to#3{%
+ \let#3=\empty
+ \foreach \axis@TMPB in {#1} {%
+ \expandafter\sciparsesign\expandafter{\axis@TMPB}\sci@S\sci@M\sci@E
+ #2\sci@S\sci@M\sci@E\to\axis@TMPB
+ \ifx#3\empty
+ \xdef#3{\axis@TMPB}%
+ \else
+ \xdef#3{#3,\axis@TMPB}%
+ \fi
+ }%
+ %
+}%
+
+% helper for \axis@apply@data@scale@trafo@to@options@for.
+\def\axis@compute@number@order@for@trafo@isdimen#1\tocount#2{%
+ \edef\axis@TMP{\pgf@sys@tonumber{#1}}%
+ \expandafter\sciparsesign\expandafter{\axis@TMP}\S\M\E
+ \expandafter#2\E\relax
+ \advance#2 by1
+}
+
+% helper for \axis@apply@data@scale@trafo@to@options@for.
+%
+\def\axis@compute@number@order@for@trafo@isfloat#1\tocount#2{%
+ \scigetcomponents#1\S\M\E
+ \expandafter#2\E\relax
+ \advance#2 by1
+}
+
+% Initialises the data scale transformation and applies it to any
+% user specified options.
+%
+% PRECONDITION:
+% - all axis limits are available in float representation
+% (i.e. with \scisetcomponents)
+% - \axis@set@default@size@options has been called before
+% POSTCONDITION:
+% - the scaling transformation is set up,
+% - all axis limits are transformed,
+% - any user input (like ticks and tick labels)
+% will reflect the changes.
+\def\axis@apply@data@scale@trafo@to@options@for#1{%
+ % initialise data scale transformation
+ % T(x) = 10^{q-m} * x
+ %
+ \begingroup
+ \let\data@max@order=\c@pgf@counta
+ \let\data@cur@order=\c@pgf@countb
+ \let\data@dimen=\pgf@xa
+ \let\data@dimen@order=\c@pgf@countc
+ %
+ % Step 1: compute 'm', the data order
+ \expandafter\axis@compute@number@order@for@trafo@isfloat
+ \csname axis@#1min\endcsname
+ \tocount\data@cur@order
+ %
+ \data@max@order=\data@cur@order
+ %
+ \expandafter\axis@compute@number@order@for@trafo@isfloat
+ \csname axis@#1max\endcsname
+ \tocount\data@cur@order
%
- % wenn ich AUTOMATISCH aus (x_i,y_i)
- % [xy]min und [xy]max ausrechnen will, muss ich
- % ggf.
- % xmin = min_{i} { untere_gaussklammer(log(x_i) / log10) }
- % rechnen
+ \ifnum\data@cur@order>\data@max@order
+ \data@max@order=\data@cur@order
+ \fi
+ %
+ % Step 2: compute 'q', the #1-size of the axis.
+ \expandafter\ifx\csname axis@#1\endcsname\empty
+ % We have 'width' or 'height'.
+ %
+ % Use the order of these parameters.
+ \def\axis@TMP{#1}%
+ \def\axis@TMPB{x}%
+ \ifx\axis@TMP\axis@TMPB
+ \expandafter\data@dimen\axis@width\relax
+ \else
+ \def\axis@TMPB{y}%
+ \ifx\axis@TMP\axis@TMPB
+ \expandafter\data@dimen\axis@height\relax
+ \fi
+ \fi
+ \axis@compute@number@order@for@trafo@isdimen
+ \data@dimen
+ \tocount\data@dimen@order
+ % This here is to avoid inaccuracies in the final
+ % axis rectangle size, see \axis@initsizes:
+ \advance\data@dimen@order by-1
+ \else
+ % FIXME:
+ % we have either the 'x=1cm' or 'y=1cm' option!
+ % How should I initialise the trafo!?
+ \data@dimen@order=3
+ \fi
+ %
+%\message{Direction #1: data max order=\the\data@max@order; data dimen order=\the\data@dimen@order. }%
+ \advance\data@dimen@order by-\data@max@order
+ \xdef\axis@TMP{\the\data@dimen@order}%
+ \endgroup
+%\message{Initialising the data scale transformation in direction #1 to \axis@TMP...}%
+ % COMPLETE INITIALISATION:
+ \ifaxis@EMERGENCY@FORCE@DATA@TRAFO@TO@IDENTITY
+ \message{WARNING: the automatic scaling of input data has been DISABLED to allow axispath commands [otherwise, axispath commands would not know of the pgfplots scalings - leading to wrong images). DISABLING THE DATA SCALING LIMITS THE DATA RANGE! I hope I can fix this issue as soon as possible. Please take a look at the manual for more information. If you get 'OVERFLOW' or 'UNDERFLOW' errors, you may need to disable the axispath.}%
+ \def\axis@TMP{0}%
+ \expandafter\let\csname axis@data@scale@trafo@SHIFT@#1\endcsname\axis@TMP
+ \else
+ \expandafter\let\csname axis@data@scale@trafo@SHIFT@#1\endcsname\axis@TMP
+ \fi
+ %
+ % ... and apply transformation to any user input
+ %
+ % Transform axis limits:
+ \expandafter\expandafter\csname axis@datascaletrafo@#1\endcsname\csname axis@#1min\endcsname\to\axis@TMP
+ \expandafter\let\csname axis@#1min\endcsname=\axis@TMP
+ %
+ \expandafter\expandafter\csname axis@datascaletrafo@#1\endcsname\csname axis@#1max\endcsname\to\axis@TMP
+ \expandafter\let\csname axis@#1max\endcsname=\axis@TMP
+ %
+ % Convert any user-specified ticks:
+ \edef\axis@TMP{\csname axis@#1tick\endcsname}%
+ % this here should also work with 'xtick=\empty', the "No tick" command.
+ \ifx\axis@TMP\empty
+ \else
+%\message{Converting #1tick='\csname axis@#1tick\endcsname'}%
+ \pgfplots@toka=\expandafter{\csname axis@datascaletrafo@#1@three\endcsname}%
+ \edef\axis@TMP{{\csname axis@#1tick\endcsname}\the\pgfplots@toka}%
+ \expandafter\axis@apply@data@scale@trafo@to@user@ticks\axis@TMP\to\axis@TMPC
+ \expandafter\let\csname axis@#1tick\endcsname=\axis@TMPC
+ \fi
%
+ % Transform any explicit axis unit scalings:
+ \expandafter\ifx\csname axis@#1\endcsname\empty
+ \else
+%\message{Converting #1 unit scale='\csname axis@#1\endcsname' ... }%
+ \expandafter\pgfmathparse\expandafter{\csname axis@#1\endcsname}%
+ \expandafter\expandafter\csname axis@inverse@datascaletrafo@tofixed@#1\endcsname\pgfmathresult\to\axis@TMP
+ \edef\axis@TMP{\axis@TMP pt}%
+ \expandafter\edef\csname axis@#1\endcsname{\axis@TMP}%
+%\message{to #1='\csname axis@#1\endcsname'.}%
+ \fi
+}
+
+\def\axis@determinedefaultvalues{%
\ifx\axis@xmin\empty
\errmessage{Sorry, the argument 'xmin=NUM' is mandatory to draw axes }%
+ \def\axis@xmin{0}%
\fi
\ifx\axis@xmax\empty
\errmessage{Sorry, the argument 'xmax=NUM' is mandatory to draw axes }%
+ \def\axis@xmax{1}%
\fi
\ifx\axis@ymin\empty
\errmessage{Sorry, the argument 'ymin=NUM' is mandatory to draw axes }%
+ \def\axis@ymin{0}%
\fi
\ifx\axis@ymax\empty
\errmessage{Sorry, the argument 'ymax=NUM' is mandatory to draw axes }%
+ \def\axis@ymax{1}%
\fi
%
+ \axis@set@default@size@options
%
- \ifx\axis@trimxmin\empty
- \else
- \pgfmathlog@invoke@expanded\pgfmathmax@{{\axis@xmin}{\axis@trimxmin}}%
- \let\axis@xmin=\pgfmathresult
+ \ifaxis@float@numerics@mode@x
+ \axis@apply@data@scale@trafo@to@options@for x%
\fi
- \ifx\axis@trimxmax\empty
- \else
- \pgfmathlog@invoke@expanded\pgfmathmin@{{\axis@xmax}{\axis@trimxmax}}%
- \let\axis@xmax=\pgfmathresult
- \fi
- \ifx\axis@trimymin\empty
- \else
- \pgfmathlog@invoke@expanded\pgfmathmax@{{\axis@ymin}{\axis@trimymin}}%
- %\pgfmathmax\axis@ymin\axis@trimymin%
- \let\axis@ymin=\pgfmathresult
+ \ifaxis@float@numerics@mode@y
+ \axis@apply@data@scale@trafo@to@options@for y%
\fi
- \ifx\axis@trimymax\empty
- \else
- \pgfmathlog@invoke@expanded\pgfmathmin@{{\axis@ymax}{\axis@trimymax}}%
- %\pgfmathmin\axis@ymax\axis@trimymax%
- \let\axis@ymax=\pgfmathresult
- \fi
- %
%
\ifnum\axis@xmode=0
\axis@xminorticksfalse
@@ -1108,23 +1593,35 @@
\ifnum\axis@ymode=0
\axis@yminorticksfalse
\fi
+ %
+ \axis@init@enlarge@limit@booleans
\ifaxis@enlargelimits
% relax the sizes.
%
% Idea: if the user chose his xmin,xmax tight to his data,
% this here will look better.
- \axis@enlarge@xlim
- \axis@enlarge@ylim
+ \axis@enlarge@limit@for x
+ \axis@enlarge@limit@for y
\else
- % FIXME : this here should be user-configurable!
- \ifaxis@autocompute@xlim
- \axis@enlarge@xlim
- \fi
- \ifaxis@autocompute@ylim
- \axis@enlarge@ylim
+ \ifaxis@enlargelimits@auto
+ \ifaxis@hide
+ % there is no axis, so skip this enlargement (unless
+ % the user explizitly requests it)
+ \else
+ % FIXME : this here should be user-configurable!
+ \ifaxis@autocompute@xlim
+ \axis@enlarge@limit@for x
+ \fi
+ \ifaxis@autocompute@ylim
+ \axis@enlarge@limit@for y
+ \fi
+ \fi
\fi
\fi
%
+ \axis@avoid@empty@axis@range@for x%
+ \axis@avoid@empty@axis@range@for y%
+ %
\axis@initsizes
%
\newif\ifaxis@xisuniform
@@ -1187,6 +1684,7 @@
\fi
}
+
% Helper method for initsizes.
%
% It computes a scaling such that \axis@width = SCALE * ACTUAL WIDTH.
@@ -1208,7 +1706,14 @@
% -> \axis@tmpXscale = (X - c) / (x *(xmax-xmin))
%
% \axis@tmpa := X-c:
- \advance\axis@tmpa by-45pt% FIXME determine 'c' correctly!
+ \ifaxis@scale@only@axis
+ \else
+ \advance\axis@tmpa by-45pt% FIXME determine 'c' correctly!
+ \fi
+ \ifdim\axis@tmpa<0pt
+ \errmessage{Error: Plot width `\axis@width' is too small. This can't be realised while maintaining constant width for y-labels. Sorry, label width are only approximate. You will need to adjust your width.}%
+ \axis@tmpa=0pt
+ \fi
% \axis@tmpb := x*(xmax-xmin):
\axis@tmpb=\axis@xcoordmaxTEX
\advance\axis@tmpb by-\axis@xcoordminTEX
@@ -1217,13 +1722,11 @@
{\pgf@sys@tonumber\axis@tmpb}%
}%
\let#1=\pgfmathresult
- %--------------------------------------------------
- % \message{pgfplots.sty: Computing 'x' such that 'width = c + x*(xmax-xmin)';
- % c=estimated,
- % width-c =\the\axis@tmpa,
- % x*(xmax[=\the\axis@xcoordmaxTEX] - xmin[=\the\axis@xcoordminTEX)]) = \the\axis@tmpb
- % -> x-scale =#1 }%
- %--------------------------------------------------
+%\message{pgfplots.sty: Computing 'x' such that 'width = c + x*(xmax-xmin)';
+% c=estimated,
+% width-c =\the\axis@tmpa,
+% x*(xmax[=\the\axis@xcoordmaxTEX] - xmin[=\the\axis@xcoordminTEX)]) = \the\axis@tmpb
+% -> x-scale =#1 }%
}
% The same as \axis@initsizes@getXscale, just for the height.
@@ -1235,7 +1738,14 @@
% -> \axis@tmpXscale = (X - c) / (x *(xmax-xmin))
%
% \axis@tmpa := X-c:
- \advance\axis@tmpa by-45pt% FIXME determine 'c' correctly!
+ \ifaxis@scale@only@axis
+ \else
+ \advance\axis@tmpa by-45pt\relax% FIXME determine 'c' correctly!
+ \fi
+ \ifdim\axis@tmpa<0pt
+ \errmessage{Error: Plot height `\axis@height' is too small. This can't be realised while maintaining constant height for x-labels. Sorry, label heights are only approximate. You will need to adjust your height.}%
+ \axis@tmpa=0pt
+ \fi
% \axis@tmpb := x*(xmax-xmin):
\axis@tmpb=\axis@ycoordmaxTEX
\advance\axis@tmpb by-\axis@ycoordminTEX
@@ -1244,28 +1754,110 @@
{\pgf@sys@tonumber\axis@tmpb}%
}%
\let#1=\pgfmathresult
- %--------------------------------------------------
- % \message{pgfplots.sty: Computing 'y' such that 'height = c + y*(ymax-ymin)';
- % %height=\axis@height,
- % c=estimated,
- % height-c =\the\axis@tmpa,
- % y*(ymax[=\the\axis@ycoordmaxTEX] - ymin[=\the\axis@ycoordminTEX)]) = \the\axis@tmpb
- % -> y-scale =#1 }%
- %--------------------------------------------------
-}
-
-% PRECONDITION: correct axis limits
-% POSTCONDITION: the current x- and y unit vectors are changed;
-% \axis@[xy]coord{min,max}TEX are set
+%\message{pgfplots.sty: Computing 'y' such that 'height = c + y*(ymax-ymin)';
+% height=\axis@height,
+% c=estimated,
+% height-c =\the\axis@tmpa,
+% y*(ymax[=\the\axis@ycoordmaxTEX] - ymin[=\the\axis@ycoordminTEX)]) = \the\axis@tmpb
+% -> y-scale =#1 }%
+}
+
+
+% Checks whether axis limits in coordinate #1 are approximately equal.
%
-\def\axis@initsizes{%
- % INIT.
- %
- % The axes 'x' and 'y' vectors will be scaled such that the total
- % size is (\axisdefaultwidth, \axisdefaultheight).
- %
- % If the user specifies ONE of width OR height,
- % the plot will be resized; keeping the aspect ratio.
+% If that is the case, force a non-zero width of the range.
+%
+\def\axis@avoid@empty@axis@range@for#1{%
+ % Check if axis limits are empty:
+ \begingroup
+ \expandafter\let\expandafter\if@cur@is@scaled\csname ifaxis@float@numerics@mode@#1\endcsname
+ \expandafter\let\expandafter\min\csname axis@#1min\endcsname
+ \expandafter\let\expandafter\max\csname axis@#1max\endcsname
+ \let\min@d=\pgf@xa
+ \let\max@d=\pgf@xb
+ \let\diff=\pgf@xc
+ \newif\ifrange@is@approx@equal
+ \expandafter\min@d\min pt
+ \expandafter\max@d\max pt
+ \diff=\max@d
+ \advance\diff by-\min@d
+ % FIXME : I need a RELATIVE check here!
+ % but: real number point division is expensive
+ \if@cur@is@scaled
+ % this here should be sufficient because the axis
+ % has absolute values of order O( 10^3 ) or so.
+ \ifdim\diff<1pt
+ \range@is@approx@equaltrue
+ \fi
+ \else
+ % there is no data scaling, so I should be much more defensive
+ % with absolute thresholds...
+ \ifdim\diff<0.05pt
+ \range@is@approx@equaltrue
+ \fi
+ \fi
+ \ifrange@is@approx@equal
+%\message{avoid range is approx equal for coord #1: MODIFYING (\min,\max)...}%
+ % the case \min ~= \max
+ %
+ % enlarge \max and shrink \min:
+ \ifdim\max@d<0pt
+ \ifdim\max@d<-1pt
+ \max@d=0.8\max@d
+ \min@d=1.2\min@d
+ \else
+ \advance\max@d by-1pt
+ \advance\min@d by1pt
+ \fi
+ \else
+ \ifdim\max@d>1pt
+ \max@d=1.2\max@d
+ \min@d=0.8\min@d
+ \else
+ \ifdim\max@d=0pt
+ \if@cur@is@scaled
+ % we can't simply add a constant in the
+ % transformed range.
+ %
+ % So: set limits to [-1,1] = [-1.0e0,+1.0e0]
+ \def\sci@S{2}%
+ \def\sci@M{1.0}%
+ \def\sci@E{0}%
+ \csname axis@datascaletrafo@#1@three\endcsname\sci@S\sci@M\sci@E\to\min
+ \def\sci@S{1}%
+ \def\sci@M{1.0}%
+ \def\sci@E{0}%
+ \csname axis@datascaletrafo@#1@three\endcsname\sci@S\sci@M\sci@E\to\max
+%\message{[trafo shift = \csname axis@data@scale@trafo@SHIFT@#1\endcsname; setting limits -1:1]}%
+ \expandafter\min@d\min pt
+ \expandafter\max@d\max pt
+ \else
+ \advance\max@d by1pt
+ \advance\min@d by-1pt
+ \fi
+ \else
+ \advance\max@d by1pt
+ \advance\min@d by-1pt
+ \fi
+ \fi
+ \fi
+ \xdef\axis@TMP{\pgf@sys@tonumber{\min@d}}%
+ \xdef\axis@TMPB{\pgf@sys@tonumber{\max@d}}%
+%\message{ -> #1 = \axis@TMP : \axis@TMPB;}%
+ \else
+ \global\let\axis@TMP=\min%
+ \global\let\axis@TMPB=\max%
+ \fi
+ \endgroup
+ \expandafter\let\csname axis@#1min\endcsname=\axis@TMP
+ \expandafter\let\csname axis@#1max\endcsname=\axis@TMPB
+}
+
+% PRECONDITION:
+% none
+% POSTCONDITION:
+% \axis@default@aspect@ratio is set.
+\def\axis@compute@default@aspect@ratio{%
\expandafter\pgfmath@x\axisdefaultwidth
\expandafter\pgfmath@y\axisdefaultheight
\pgfmathlog@invoke@expanded\pgfmathdivide@{%
@@ -1273,52 +1865,70 @@
{\pgf@sys@tonumber{\pgfmath@y}}%
}%
\let\axis@default@aspect@ratio=\pgfmathresult
+}
+
+\def\axis@set@default@size@options{%
+ % The axes 'x' and 'y' vectors will be scaled such that the total
+ % size is (\axisdefaultwidth, \axisdefaultheight).
%
- \pgfpointxy{\axis@xmin}{\axis@ymin}%
- \axis@xcoordminTEX=\pgf@x
- \axis@ycoordminTEX=\pgf@y
- \pgfpointxy{\axis@xmax}{\axis@ymax}%
- \axis@xcoordmaxTEX=\pgf@x
- \axis@ycoordmaxTEX=\pgf@y
- %
- %-----------------------------------------
- % PROCESS THE 'width' and 'height' options
- %-----------------------------------------
+ % If the user specifies ONE of width OR height,
+ % the plot will be resized; keeping the aspect ratio.
%
- % FIXME: make these variables LOCAL:
- \let\axis@tmpXscale=\empty%
- \let\axis@tmpYscale=\empty%
+ \let\axis@default@aspect@ratio=\empty
% CASES:
% hasx := 'x' option non-empty
% hasy := 'y' option non-empty
% W := 'width' option non-empty
% H := 'height' option non-empty
%
- % hasx hasy
- % 0 0 -> work depend on W and H:
- % W H
- % 0 0 -> use \axisdefaultwidth and \axisdefaultheight
- % 0 1 -> determine s:=\axis@tmpYscale and y*=s, x*=s (aspect ratio)
- % 1 0 -> determine s:=\axis@tmpXscale and " " "
- % 1 1 -> use specified width and height
- % 0 1 -> use specified y vector, xscale by 'W' option (NO ASPECT RATIO)
- % W
- % 0 -> use \axisdefaultwidth
- % 1 -> determine s:=\axis@tmpXscale
- % 1 0 -> use specified x vector, yscale by 'H' option (NO ASPECT RATIO)
- % H
- % 0 -> use \axisdefaultheight
- % 1 -> determine s:=\axis@tmpYscale
- % 1 1 -> use specified x AND y vector (ignore W and H)
+ % hasx = 1 -> width is not interesting; we use 'x' option.
+ % hasx = 0 -> determine final width:
+ % W H
+ % 0 0 -> \axisdefaultwidth
+ % 0 1 -> determine width out of H and the default aspect ratio
+ % 1 X -> ok, use the user parameter.
+ %
+ % hasy = 1 -> height is not interesting, we use 'y' option.
+ % hasy = 0 -> determine final height:
+ % W H
+ % 0 0 -> \axisdefaultheight
+ % X 1 -> ok, use the user parameter
+ % 1 0 -> determine height out of W and the default aspect ratio
%
\ifx\axis@x\empty
\ifx\axis@y\empty
- % The case hasx=0, hasy=0, W=0 H=0:
- % the other cases for hasx=0, hasy=0 follow below.
- \ifx\axis@width\empty\ifx\axis@height\empty
- \let\axis@width=\axisdefaultwidth
- \let\axis@height=\axisdefaultheight
- \fi\fi
+ % hasx=0, hasy=0
+ %
+ % -> KEEP ASPECT RATIO if just one W, or H is given!
+ \ifx\axis@width\empty
+ \ifx\axis@height\empty
+ % The case hasx=0, hasy=0, W=0 H=0:
+ \let\axis@width=\axisdefaultwidth
+ \let\axis@height=\axisdefaultheight
+ \else
+ % The case hasx=0, hasy=0, W=0 H=1:
+ \axis@compute@default@aspect@ratio
+ \expandafter\pgfmath@y\axis@height
+ \pgfmathlog@invoke@expanded\pgfmathmultiply@{%
+ {\pgf@sys@tonumber{\pgfmath@y}}%
+ {\axis@default@aspect@ratio}%
+ }%
+ \edef\axis@width{\pgfmathresult pt}%
+ \fi
+ \else
+ \ifx\axis@height\empty
+ % The case hasx=0, hasy=0, W=1 H=0:
+ \axis@compute@default@aspect@ratio
+ \expandafter\pgfmath@x\axis@width
+ \pgfmathlog@invoke@expanded\pgfmathdivide@{%
+ {\pgf@sys@tonumber{\pgfmath@x}}%
+ {\axis@default@aspect@ratio}%
+ }%
+ \edef\axis@height{\pgfmathresult pt}%
+ \else
+ % The case hasx=0, hasy=0, W=1 H=1:
+ \fi
+ \fi
\else
% hasx=0, hasy=1, W=0:
\ifx\axis@width\empty
@@ -1333,12 +1943,43 @@
\fi
\fi
\fi
+}
+
+% PRECONDITION:
+% - final axis limits are given in transformed range
+% - \axis@set@default@size@options has been invoked before
+% POSTCONDITION:
+% - the current x- and y unit vectors are changed;
+% - \axis@[xy]coord{min,max}TEX are set
+%
+\def\axis@initsizes{%
+ % INIT.
+ %
+ %
+ \pgfpointxy{\axis@xmin}{\axis@ymin}%
+ \axis@xcoordminTEX=\pgf@x
+ \axis@ycoordminTEX=\pgf@y
+ \pgfpointxy{\axis@xmax}{\axis@ymax}%
+ \axis@xcoordmaxTEX=\pgf@x
+ \axis@ycoordmaxTEX=\pgf@y
+ %
+ %
+ %-----------------------------------------
+ % PROCESS THE 'width' and 'height' options
+ %-----------------------------------------
+ %
+ % FIXME: make these variables LOCAL:
+ %
+ \let\axis@rectangle@width=\empty
+ \let\axis@rectangle@height=\empty
%
- % common code for the cases if one of W,H is 1:
\ifx\axis@x\empty
\ifx\axis@width\empty
- \else
- \axis@initsizes@getXscale\into\axis@tmpXscale
+ \errmessage{INTERNAL LOGIC ERROR! WIDTH NOT SET}%
+ \fi
+ \axis@initsizes@getXscale\into\axis@tmpXscale
+ \ifaxis@scale@only@axis
+ \let\axis@rectangle@width=\axis@width
\fi
\else
\def\axis@tmpXscale{1}%
@@ -1346,45 +1987,18 @@
%
\ifx\axis@y\empty
\ifx\axis@height\empty
- \else
- \axis@initsizes@getYscale\into\axis@tmpYscale
+ \errmessage{INTERNAL LOGIC ERROR! HEIGHT NOT SET}%
+ \fi
+ \axis@initsizes@getYscale\into\axis@tmpYscale
+ \ifaxis@scale@only@axis
+ \let\axis@rectangle@height=\axis@height
\fi
\else
\def\axis@tmpYscale{1}%
\fi
%
- \ifx\axis@x\empty\ifx\axis@y\empty
- % hasx=0, hasy=0 and ...
- %
- % -> KEEP ASPECT RATIO!
- %
- % CASE W=0 H=1:
- \ifx\axis@width\empty
- \ifx\axis@height\empty
- \else
- \expandafter\pgfmath@y\axis@height
- \pgfmathlog@invoke@expanded\pgfmathmultiply@{%
- {\pgf@sys@tonumber{\pgfmath@y}}%
- {\axis@default@aspect@ratio}%
- }%
- \edef\axis@width{\pgfmathresult pt}%
- \axis@initsizes@getXscale\into\axis@tmpXscale
- \fi
- \else% CASE W=1 H=0:
- \ifx\axis@height\empty
- \expandafter\pgfmath@x\axis@width
- \pgfmathlog@invoke@expanded\pgfmathdivide@{%
- {\pgf@sys@tonumber{\pgfmath@x}}%
- {\axis@default@aspect@ratio}%
- }%
- \edef\axis@height{\pgfmathresult pt}%
- \axis@initsizes@getYscale\into\axis@tmpYscale
- \fi
- \fi
- \fi\fi
- % IMPLEMENTATION NOTE:
- % if(Xscale=empty or Yscale=empty)
- % -> LOGIC ERROR above.
+ %
+ % assert( \axis@tmpXscale != \empty && \axis@tmpYscale != \empty )
%
% Apply scaling:
\pgfpointxy{\axis@tmpXscale}{\axis@tmpYscale}%
@@ -1401,34 +2015,127 @@
\pgfsetyvec{\pgfpoint{0pt}{\axis@y}}%
\fi
%
+ % Determine final rectangle dimensions.
+ % There are the following cases:
+ % 1. the user really wants a fixed dimension,
+ % i.e. he used 'scale only axis'.
+ % Then, we have to work to get the correct dimension!
+ %
+ % Up to now, the scaling mechanism looses to many significant
+ % digits such that the final width/height differs by 1-2 pt.
+ %
+ % If I am not mistaken, this does ONLY affect the final size,
+ % not the relative plot precision.
+ %
+ % FIXME : really compute the plot precision!
+ %
+ % 2. The use specified width and/or height, but not 'scale only
+ % axis'. Accept inaccurate final widths/heights (see above).
+ %
+ % 3. The user supplied 'x' and or 'y'. Simply use them, its
+ % accurate.
+ %
\pgfpointxy{\axis@xmin}{\axis@ymin}%
\axis@xcoordminTEX=\pgf@x
\axis@ycoordminTEX=\pgf@y
\pgfpointxy{\axis@xmax}{\axis@ymax}%
- \axis@xcoordmaxTEX=\pgf@x
- \axis@ycoordmaxTEX=\pgf@y
- %-----------------------------------------
+ \ifx\axis@rectangle@width\empty
+ \axis@xcoordmaxTEX=\pgf@x
+ \else
+ % this 'if' here should only make a difference of about
+ % 1-2pt, not more.
+ %
+ % and I am quite sure that this inaccuracy (and this
+ % work-around) only affects the
+ % final size, not the relative plot accuracy.
+ \axis@xcoordmaxTEX=\axis@xcoordminTEX
+ \expandafter\advance\expandafter\axis@xcoordmaxTEX\axis@width
+ \fi
+ \ifx\axis@rectangle@height\empty
+ \axis@ycoordmaxTEX=\pgf@y
+ \else
+ \axis@ycoordmaxTEX=\axis@ycoordminTEX
+ \expandafter\advance\expandafter\axis@ycoordmaxTEX\axis@height
+ \fi
+%--------------------------------------------------
+% \begingroup
+% \pgf@x=\axis@xcoordmaxTEX\advance\pgf@x by-\axis@xcoordminTEX
+% \pgf@y=\axis@ycoordmaxTEX\advance\pgf@y by-\axis@ycoordminTEX
+% \message{Axis scaling x=\axis@tmpXscale, y=\axis@tmpYscale\ yields lower-left-corner (\axis@xmin,\axis@ymin) = (\the\axis@xcoordminTEX,\the\axis@ycoordminTEX) and upper right (\axis@xmax,\axis@ymax) = (\the\axis@xcoordmaxTEX,\the\axis@ycoordmaxTEX). Axis dimensions are width=\the\pgf@x, height=\the\pgf@y.}%
+% \endgroup
+%--------------------------------------------------
}
\def\axis@BEGIN@init@and@draw@axis{%
\axis@determinedefaultvalues
- % X-Achsenbeschriftung:
- % LADE DIE \axis@xtick -variable REIN
- \expandafter\xachse\expandafter{\axis@xtick}
- %
- % Y-Achsen und Achsenbeschriftung:
- \expandafter\yachse\expandafter{\axis@ytick}%
-
- % Äußerer Rahmen:
- \draw
- (\axis@xcoordminTEX, \axis@ycoordminTEX)
- rectangle (\axis@xcoordmaxTEX, \axis@ycoordmaxTEX);
+ % move the anchor to (0,0):
+ \expandafter\ifcase\axis@anchorchoicenum
+ % north:
+ \begin{scope}[
+ yshift=-\axis@ycoordmaxTEX,
+ xshift=-0.5\axis@xcoordminTEX-0.5\axis@xcoordmaxTEX
+ ]
+ \or% north west:
+ \begin{scope}[
+ yshift=-\axis@ycoordmaxTEX,
+ xshift=-\axis@xcoordminTEX
+ ]
+ \or% west:
+ \begin{scope}[
+ yshift=-0.5\axis@ycoordminTEX-0.5\axis@ycoordmaxTEX,
+ xshift=-\axis@xcoordminTEX
+ ]
+ \or% south west:
+ \begin{scope}[
+ yshift=-\axis@ycoordminTEX,
+ xshift=-\axis@xcoordminTEX
+ ]
+ \or% south:
+ \begin{scope}[
+ yshift=-\axis@ycoordminTEX,
+ xshift=-0.5\axis@xcoordminTEX-0.5\axis@xcoordmaxTEX
+ ]
+ \or% south east:
+ \begin{scope}[
+ yshift=-\axis@ycoordminTEX,
+ xshift=-\axis@xcoordmaxTEX
+ ]
+ \or% east:
+ \begin{scope}[
+ yshift=-0.5\axis@ycoordminTEX-0.5\axis@ycoordmaxTEX,
+ xshift=-\axis@xcoordmaxTEX
+ ]
+ \or% north east:
+ \begin{scope}[
+ yshift=-\axis@ycoordmaxTEX,
+ xshift=-\axis@xcoordmaxTEX
+ ]
+ \or% center
+ \begin{scope}[
+ yshift=-0.5\axis@ycoordminTEX-0.5\axis@ycoordmaxTEX,
+ xshift=-0.5\axis@xcoordminTEX-0.5\axis@xcoordmaxTEX
+ ]
+ \fi
\begin{scope}
- \clip
- (\axis@xcoordminTEX, \axis@ycoordminTEX)
- rectangle (\axis@xcoordmaxTEX, \axis@ycoordmaxTEX);
+ \ifaxis@hide
+ \clip
+ (\axis@xcoordminTEX, \axis@ycoordminTEX)
+ rectangle (\axis@xcoordmaxTEX, \axis@ycoordmaxTEX);
+ \else
+
+ % X-Achsenbeschriftung:
+ % LADE DIE \axis@xtick -variable REIN
+ \expandafter\axis@drawxaxis\expandafter{\axis@xtick}
+ %
+ % Y-Achsen und Achsenbeschriftung:
+ \expandafter\axis@drawyaxis\expandafter{\axis@ytick}%
+ \draw[clip]
+ (\axis@xcoordminTEX, \axis@ycoordminTEX)
+ rectangle (\axis@xcoordmaxTEX, \axis@ycoordmaxTEX);
+
+ \fi
}
\def\axis@END@init@and@draw@axis{%
@@ -1448,6 +2155,34 @@
}%
}
+\tikzdeclarecoordinatesystem{axis}{\axis@evalute@tikz@coord@system@interface#1\axis@coord@end}
+
+
+% Assigns \pgfmathresult := canvas coordinate (#2) for axis #1.
+\long\def\axis@evalute@tikz@coord@system@interface@for#1#2{%
+ \expandafter\let\expandafter\if@datascaled@cur\csname ifaxis@float@numerics@mode@#1\endcsname
+ \expandafter\ifcase\csname axis@#1mode\endcsname
+ \if@datascaled@cur
+ \csname axis@datascaletrafo@fromfixed@#1\endcsname#2\to\pgfmathresult
+ \else
+ \def\pgfmathresult{#2}%
+ \fi
+ \or
+ \pgfmathlog@{#2}%
+ \fi
+}
+
+\long\def\axis@evalute@tikz@coord@system@interface#1,#2\axis@coord@end{%
+ \begingroup
+ \axis@evalute@tikz@coord@system@interface@for{x}{#1}%
+ \let\axis@evaluate@tikz@coord@x=\pgfmathresult
+ \axis@evalute@tikz@coord@system@interface@for{y}{#2}%
+ \xdef\axis@TMP{\axis@evaluate@tikz@coord@x pt}%
+ \xdef\axis@TMPB{\pgfmathresult pt}%
+ \endgroup
+ \pgfpointxy{\axis@TMP}{\axis@TMPB}%
+}
+
% In case of (semi-) logplots, this command will
% - assign a filter which invokes \pgfmathlog@{} for each coordinate
% - replace any user-specified coordinate by its log.
@@ -1455,105 +2190,285 @@
% All subsequent commands will then work with logarithmic coordinates.
%
% @see pgfmathlog.sty for details about the implementation of log().
-\def\axis@preparelog@filtering{%
- \ifnum\axis@xmode=1
- % any user-specified axis limits:
- \ifx\axis@xmin\empty
- \else
- \expandafter\pgfmathlog@\expandafter{\axis@xmin}%
- \let\axis@xmin=\pgfmathresult
- \fi
- \ifx\axis@xmax\empty
+%
+% PRECONDITION:
+% - The user input options have been set correctly,
+% - the option processing has not yet begun
+%
+% POSTCONDITION:
+% - any user input for log-axis has been replaced by its log
+% - coordinate filters to compute logs are installed
+%
+% See also:
+% \axis@apply@data@scale@trafo@to@options@for
+\def\axis@prepare@coord@filtering@for#1{%
+ \expandafter\ifcase\csname axis@#1mode\endcsname
+ \ifaxis@disabledatascaling
+ \csname axis@float@numerics@mode@#1false\endcsname
+ \axis@float@numerics@modefalse
\else
- \expandafter\pgfmathlog@\expandafter{\axis@xmax}%
- \let\axis@xmax=\pgfmathresult
+ \csname axis@float@numerics@mode@#1true\endcsname
+ \axis@float@numerics@modetrue
\fi
- %
- % any user specified axis ticks:
- \ifx\axis@xtick\empty
- \else
- \expandafter\axis@filter@input@ticks@with@log\expandafter{\axis@xtick}%
- \edef\axis@xtick{\axis@TMP}%
+ \ifaxis@float@numerics@mode
+ % Install coordinate filters that
+ % - read input as normalised floating point numbers,
+ % - return [SIGN][MANTISSE]eEXPONENT
+ % Motivation:
+ % 1. we can compute axis limits using such data
+ % 2. we can remember the floating point representation for
+ % the data scaling transformation.
+ % ATTENTION:
+ % this here is a preprocessing step! You will need to
+ % apply the data scaling later!
+ % see
+ % \axis@apply@data@scaletrafo@to@plot@data
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1filter\endcsname
+ \ifx\axis@TMP\empty
+ \expandafter\def\csname addplot@float@numerics@#1filter\endcsname##1\to##2{%
+ \sciparsesign{##1}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \scisetcomponents{##2}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \edef##2{\axis@tmp@S\axis@tmp@M e\axis@tmp@E}%
+ }%
+ \else
+ \expandafter\let\csname axis@#1filter@orig\endcsname=\axis@TMP
+ \expandafter\def\csname addplot@float@numerics@#1filter\endcsname##1\to##2{%
+ \csname axis@#1filter@orig\endcsname##1\to##2\relax
+ \ifx##2\empty
+ \else
+ \expandafter\sciparsesign\expandafter{##2}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \scisetcomponents{##2}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \edef##2{\axis@tmp@S\axis@tmp@M e\axis@tmp@E}%
+ \fi
+ }%
+ \fi
+ \expandafter\let\expandafter\axis@TMP\csname addplot@float@numerics@#1filter\endcsname
+ \expandafter\let\csname axis@#1filter\endcsname\axis@TMP
+ %
+ % Check for any existing axis limits:
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1min\endcsname
+ \ifx\axis@TMP\empty
+ \else
+ \expandafter\sciparsesign\expandafter{\axis@TMP}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \expandafter\scisetcomponents\csname axis@#1min\endcsname\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \fi
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1max\endcsname
+ \ifx\axis@TMP\empty
+ \else
+ \expandafter\sciparsesign\expandafter{\axis@TMP}\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \expandafter\scisetcomponents\csname axis@#1max\endcsname\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \fi
\fi
- \ifx\axis@xfilter\empty
- \def\addplot@log@compute@xfilter##1\to##2{%
- \pgfmathlog@{##1}%
- \let##2=\pgfmathresult
- }%
+ \or
+ \ifaxis@disablelogfilter
\else
- \let\axis@xfilter@orig=\axis@xfilter
- \def\addplot@log@compute@xfilter##1\to##2{%
- \pgfmathlog@{##1}%
- \ifx\pgfmathresult\empty
- \let##2=\empty
- \else
- \expandafter\axis@xfilter@orig\pgfmathresult\to##2\relax
- \fi
- }%
+ % any user-specified axis limits:
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1min\endcsname
+ \ifx\axis@TMP\empty
+ \else
+ \expandafter\pgfmathlog@\expandafter{\axis@TMP}%
+ \expandafter\let\csname axis@#1min\endcsname=\pgfmathresult
+ \fi
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1max\endcsname
+ \ifx\axis@TMP\empty
+ \else
+ \expandafter\pgfmathlog@\expandafter{\axis@TMP}%
+ \expandafter\let\csname axis@#1max\endcsname=\pgfmathresult
+ \fi
+ %
+ % any user specified axis ticks:
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1tick\endcsname
+ \ifx\axis@TMP\empty
+ \else
+ \expandafter\axis@filter@input@ticks@with@log\expandafter{\axis@TMP}%
+ \expandafter\edef\csname axis@#1tick\endcsname{\axis@TMP}%
+ \fi
+ %
+ \expandafter\let\expandafter\axis@TMP\csname axis@#1filter\endcsname
+ \ifx\axis@TMP\empty
+ \expandafter\def\csname addplot@log@compute@#1filter\endcsname##1\to##2{%
+ \pgfmathlog@{##1}%
+ \let##2=\pgfmathresult
+ }%
+ \else
+ \expandafter\let\csname axis@#1filter@orig\endcsname=\axis@TMP
+ \expandafter\def\csname addplot@log@compute@#1filter\endcsname##1\to##2{%
+ \pgfmathlog@{##1}%
+ \ifx\pgfmathresult\empty
+ \let##2=\empty
+ \else
+ \expandafter\expandafter\csname axis@#1filter@orig\endcsname\pgfmathresult\to##2\relax
+ \fi
+ }%
+ \fi
+ \expandafter\let\expandafter\axis@TMP\csname addplot@log@compute@#1filter\endcsname
+ \expandafter\let\csname axis@#1filter\endcsname\axis@TMP
\fi
- \def\axis@xfilter{\addplot@log@compute@xfilter}%
\fi
- %
- \ifnum\axis@ymode=1
- % any user-specified axis limits:
- \ifx\axis@ymin\empty
- \else
- \expandafter\pgfmathlog@\expandafter{\axis@ymin}%
- \let\axis@ymin=\pgfmathresult
- \fi
- \ifx\axis@ymax\empty
- \else
- \expandafter\pgfmathlog@\expandafter{\axis@ymax}%
- \let\axis@ymax=\pgfmathresult
- \fi
- %
- % any user specified axis ticks:
- \ifx\axis@ytick\empty
+}
+
+\def\axis@create@axis@descriptions{%
+ \ifaxis@hide
+ \else
+ \ifx\axis@xlabel\empty
\else
- \expandafter\axis@filter@input@ticks@with@log\expandafter{\axis@ytick}%
- \edef\axis@ytick{\axis@TMP}%
+ \axisshowxlabel
\fi
- \ifx\axis@yfilter\empty
- \def\addplot@log@compute@yfilter##1\to##2{%
- \pgfmathlog@{##1}%
- \let##2=\pgfmathresult
- }%
+ \ifx\axis@ylabel\empty
\else
- \let\axis@yfilter@orig=\axis@yfilter
- \def\addplot@log@compute@yfilter##1\to##2{%
- \pgfmathlog@{##1}%
- \ifx\pgfmathresult\empty
- \let##2=\empty
- \else
- \expandafter\axis@yfilter@orig\pgfmathresult\to##2\relax
- \fi
- }%
+ \axisshowylabel
\fi
- \def\axis@yfilter{\addplot@log@compute@yfilter}%
\fi
+ \ifx\axis@title\empty
+ \else
+ \axisshowtitle
+ \fi
+ \axis@createlegend
+}
+
+% DATA TRANSFORMATION T(x) = X
+%
+% Input:
+% a number in the original data range, given in **floating** point representation
+% Output:
+% a fixed point number in transformed range
+% @see
+% \axis@datascaletrafo@x@three
+% \axis@datascaletrafo@fromfixed@x
+\def\axis@datascaletrafo@x#1\to#2{%
+ \scigetcomponents#1\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \axis@datascaletrafo@x@three\axis@tmp@S\axis@tmp@M\axis@tmp@E\to#2
+}
+
+% Overloaded function.
+% Input:
+% The same as above, but with Sign, Mantisse, Exponent.
+% #1,#2 and #3 are expected to be MACRO NAMES.
+\def\axis@datascaletrafo@x@three#1#2#3\to#4{%
+ \def\axis@TMP{\scimathshift{#1}{#2}{#3}}%
+ \expandafter\axis@TMP\expandafter{\axis@data@scale@trafo@SHIFT@x}%
+ \scitofixed{#1}{#2}{#3}{#4}%
+}
+
+% Overloaded function.
+% Input:
+% a FIXED point number instead of a floating point one.
+% @see \axis@datascaletrafo@x
+\def\axis@datascaletrafo@fromfixed@x#1\to#2{%
+ \begingroup
+ \sciparsesign{#1}\axis@S\axis@M\axis@E
+ \axis@datascaletrafo@x@three\axis@S\axis@M\axis@E\to{#2}%
+ \global\let\axis@TMP=#2\relax
+ \endgroup
+ \let#2=\axis@TMP
+}
+
+\def\axis@datascaletrafo@y#1\to#2{%
+ \scigetcomponents#1\axis@tmp@S\axis@tmp@M\axis@tmp@E
+ \axis@datascaletrafo@y@three\axis@tmp@S\axis@tmp@M\axis@tmp@E\to#2
+}
+\def\axis@datascaletrafo@y@three#1#2#3\to#4{%
+ \def\axis@TMP{\scimathshift{#1}{#2}{#3}}%
+ \expandafter\axis@TMP\expandafter{\axis@data@scale@trafo@SHIFT@y}%
+ \scitofixed{#1}{#2}{#3}{#4}%
+}
+\def\axis@datascaletrafo@fromfixed@y#1\to#2{%
+ \begingroup
+ \sciparsesign{#1}\axis@S\axis@M\axis@E
+ \axis@datascaletrafo@y@three\axis@S\axis@M\axis@E\to{#2}%
+ \global\let\axis@TMP=#2\relax
+ \endgroup
+ \let#2=\axis@TMP
+}
+
+% INVERSE transformation x = T^{-1}( X )
+% Input:
+% a fixed point number in transformed domain
+% Output:
+% a number in the data domain, given in floating point
+% representation
+\def\axis@inverse@datascaletrafo@x#1\to#2{%
+ \expandafter\sciparsesignsingle\expandafter{#1}#2
+ \edef\axis@TMP{\noexpand#2{-\axis@data@scale@trafo@SHIFT@x}}%
+ \expandafter\scimathshiftsingle\axis@TMP
+}
+
+\def\axis@inverse@datascaletrafo@y#1\to#2{%
+ \expandafter\sciparsesignsingle\expandafter{#1}#2
+ \edef\axis@TMP{\noexpand#2{-\axis@data@scale@trafo@SHIFT@y}}%
+ \expandafter\scimathshiftsingle\axis@TMP
+}
+
+% Overloaded function.
+%
+% In contrast to \axis@inverse@datascaletrafo@x, this method
+% returns a number in FIXED point representation.
+% @see \axis@inverse@datascaletrafo@x
+\def\axis@inverse@datascaletrafo@tofixed@x#1\to#2{%
+ \axis@inverse@datascaletrafo@x#1\to{#2}%
+ \scitofixedsingle{#2}{#2}%
+}
+\def\axis@inverse@datascaletrafo@tofixed@y#1\to#2{%
+ \axis@inverse@datascaletrafo@y#1\to{#2}%
+ \scitofixedsingle{#2}{#2}%
}
\newenvironment{axis}[1][]{%
\begingroup
- \begin{scope}[style=every axis]
+% \def\axis@setkeys{\setkeys*[\prefix]{axis}}%
+%\tracingmacros=2\tracingcommands=2
+% \message{Der every-axis-style ist gerade \csname tikz@st@every axis\endcsname}%
+%\tracingmacros=0\tracingcommands=0
+% \expandafter\expandafter\expandafter\axis@setkeys
+ % \expandafter\expandafter\expandafter{\csname tikz@st@every axis\endcsname}%
+ \begin{scope}[style=every axis,%
+ x=1pt,y=1pt% see below
+ ]
+ % The explicit specification of 'x' and 'y' as 1pt is to avoid
+ % numeric overflow/underflow during scale computations:
+ %
+ % The scaling (i.e. proper values for 'x' and 'y') will be
+ % determined later-on, dependend on the axis limits. Since axis
+ % limits are implicitly in units of 1pt, it is reasonable to use
+ % '1pt' here as well.
+ %
+ %
%--------------------------------------------------
% \draw[very thin,color=gray,xstep=1,ystep=\logten]
% (\xcoordmin\axis@leftover,\ycoordmin)
% grid (\xcoordmax\axis@rightover,\ycoordmax);
%--------------------------------------------------
\setkeys[\prefix]{axis}{#1}%
- \setkeys[\prefix]{legend}{}%
%
+ % --------------------
+ % Allocations:
+ % --------------------
\listnewempty\axis@plotspeclist
\listnewempty\axis@legend
- \listnewempty\axis@draw@stored@plots
+ \listnewempty\axis@stored@plot@cmds
+ \listnewempty\axis@stored@plot@data
+ \newif\ifaxis@autocompute@xlim
+ \newif\ifaxis@autocompute@ylim
+ \newif\ifaxis@filtercoords
+ \newif\ifaxis@float@numerics@mode@x
+ \newif\ifaxis@float@numerics@mode@y
+ \newif\ifaxis@float@numerics@mode
+ % rename '\ifaxis@hide axis' to mask the white space:
+ \expandafter\let\expandafter\ifaxis@hide\csname ifaxis@hide axis\endcsname
+ % the same for other options with white spaces:
+ \expandafter\let\expandafter\ifaxis@scale@only@axis\csname ifaxis@scale only axis\endcsname
+ \newif\ifaxis@draw@at@end
+ \newif\ifaxis@limits@are@computed
+ \newif\ifaxis@EMERGENCY@FORCE@DATA@TRAFO@TO@IDENTITY
+ \axis@numplots=0
+ \let\axis@already@computed@legend@node=\empty
%
- \ifaxis@disablelogfilter
- \else
- \axis@preparelog@filtering
- \fi
+ % --------------------
+ % Option preprocessing
+ % --------------------
+ \axis@prepare@coord@filtering@for x
+ \axis@prepare@coord@filtering@for y
%
- \newif\ifaxis@filtercoords
\ifx\axis@xfilter\empty
\else
\axis@filtercoordstrue
@@ -1562,46 +2477,66 @@
\else
\axis@filtercoordstrue
\fi
- %
- \axis@numplots=0
- %
- \newif\ifaxis@autocompute@xlim
- \newif\ifaxis@autocompute@ylim
- \newif\ifaxis@draw@at@end
- \newif\ifaxis@limits@are@computed
- \axis@limits@are@computedtrue
+ %
\ifx\axis@xmin\empty
\axis@autocompute@xlimtrue
\def\axis@xmin{16300}%
+ \ifaxis@float@numerics@mode@x
+ \scisetcomponents\axis@xmin{1}{1.0}{324}%
+ \fi
\fi
\ifx\axis@xmax\empty
\axis@autocompute@xlimtrue
\def\axis@xmax{-16300}%
+ \ifaxis@float@numerics@mode@x
+ \scisetcomponents\axis@xmax{2}{1.0}{324}%
+ \fi
\fi
\ifx\axis@ymin\empty
\axis@autocompute@ylimtrue
\def\axis@ymin{16300}%
+ \ifaxis@float@numerics@mode@y
+ \scisetcomponents\axis@ymin{1}{1.0}{324}%
+ \fi
\fi
\ifx\axis@ymax\empty
\axis@autocompute@ylimtrue
\def\axis@ymax{-16300}%
+ \ifaxis@float@numerics@mode@y
+ \scisetcomponents\axis@ymax{2}{1.0}{324}%
+ \fi
\fi
%
\ifaxis@autocompute@xlim
\axis@draw@at@endtrue
\axis@limits@are@computedfalse
+ \else
+ \axis@limits@are@computedtrue
\fi
\ifaxis@autocompute@ylim
\axis@draw@at@endtrue
\axis@limits@are@computedfalse
+ \else
+ \axis@limits@are@computedtrue
\fi
%
%
+ % --------------------
+ % Start axis:
+ % either postponed to \end or directly.
+ % --------------------
+ %
\ifaxis@draw@at@end
\else
\axis@BEGIN@init@and@draw@axis
\fi
}{%
+ %\end{axis}:
+ % --------------------
+ % All plotting commands
+ % have been done.
+ % -> apply postponed drawing commands!
+ % --------------------
\ifaxis@draw@at@end
\ifaxis@limits@are@computed
\else
@@ -1612,7 +2547,20 @@
\def\axis@ymax{1}%
\fi
\axis@BEGIN@init@and@draw@axis
- \listforeach\axis@draw@stored@plots\as\plotcmd{\plotcmd}%
+ \listforeach\axis@stored@plot@cmds\as\plotcmd{%
+ \listpopfront\axis@stored@plot@data\to\plotdata
+ \ifaxis@float@numerics@mode
+ \ifx\plotcmd\empty
+ \plotdata
+ \else
+ % Apply the data scaling transformation
+ \expandafter\axis@apply@data@scaletrafo@to@plot@data\plotdata\to\plotdata
+ \expandafter\plotcmd\plotdata
+ \fi
+ \else
+ \expandafter\plotcmd\plotdata
+ \fi
+ }%
\fi
\axis@END@init@and@draw@axis
%
@@ -1622,20 +2570,9 @@
x={\axis@xcoordmaxTEX-\axis@xcoordminTEX},
y={\axis@ycoordmaxTEX-\axis@ycoordminTEX}
]%
- \ifx\axis@xlabel\empty
- \else
- \axisshowxlabel
- \fi
- \ifx\axis@ylabel\empty
- \else
- \axisshowylabel
- \fi
- \ifx\axis@title\empty
- \else
- \axisshowtitle
- \fi
- \axis@createlegend
+ \axis@create@axis@descriptions
\end{scope}%
+ \end{scope}% this scope starts inside of \axis@BEGIN@init@and@draw@axis
%
\end{scope}%
\endgroup
diff --git a/Master/texmf-dist/tex/latex/pgfplots/pgfplotshelpers.sty b/Master/texmf-dist/tex/latex/pgfplots/pgfplotshelpers.sty
index 203f16379ee..304448fbef4 100644
--- a/Master/texmf-dist/tex/latex/pgfplots/pgfplotshelpers.sty
+++ b/Master/texmf-dist/tex/latex/pgfplots/pgfplotshelpers.sty
@@ -22,7 +22,9 @@
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\ProvidesPackage{pgfplotshelpers}[2008/31/01 Version 0.9]
+\ProvidesPackage{pgfplotshelpers}[2008/02/17 Version 0.9.4]
+
+\newtoks\pgfplots@toka
\def\prettyprintnumberprecision{2}
@@ -54,10 +56,11 @@
% It uses \prettyprintnumberprecision digits after the comma.
\def\prettyprintnumber#1{%
\begingroup
-%\tracingmacros=2\tracingcommands=2
- \edef\argument{#1}%
- \expandafter\prettyprintnumber@impl\argument.\END
-%\tracingmacros=0\tracingcommands=0
+% \edef\argument{#1}%
+% \expandafter\prettyprintnumber@impl\argument.\END
+ \edef\argument{#1\noexpand\prec\prettyprintnumberprecision}%
+ \expandafter\fixedpointround\argument\to\result
+ \result
\endgroup
}
diff --git a/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty b/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty
new file mode 100644
index 00000000000..493aca948d1
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty
@@ -0,0 +1,861 @@
+%--------------------------------------------
+%
+% Package sciformat.sty
+%
+% Provides support for floating point number representations of the
+% form
+%
+% S * M * 10^e
+%
+% with S in [-,+,0], 0<M<10, e in Z.
+%
+% Example:
+%
+% +1.62452*10^-8
+%
+% The conversion routines are complete text-based.
+%
+% Copyright 2007/2008 by Christian Feuersänger.
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+%--------------------------------------------
+\ProvidesPackage{sciformat}[2008/02/17 v.0.9.4]
+\RequirePackage{pgf}[2007/01/01]
+\RequirePackage{pgfplotshelpers}[2008/02/17]
+
+% Computes a normalised floating point representation for #1 of the
+% form
+% [+-]X.XXXXXXX*10^C
+% where
+% X.XXXXXX is a mantisse with first number != 0
+% and C is a count.
+%
+% This method does NOT use TeX Registers to represent the numbers! The
+% computation is COMPLETELY STRING BASED.
+% This allows numbers such at 10000000 or 5.23e-10 to be represented
+% properly, although TeX-registers would produce overflow/underflow
+% errors in these cases.
+%
+% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y
+%
+% Arguments:
+% #1 a -possibly non-normalized- number representation. Accepted input
+% format is
+% [+-]XXXXX.XXXXXX
+% [+-]XXXXX.XXXXXXeXXXX
+% [+-]0.0000XXXXXX
+% [+-]0.0000XXXXXXeXXXX
+% NOT accepted input format is
+% [+-]0000.XXXXXX [leading zeros not supported]
+% [+-]XXXXX.XXXXXXEXXXXX [E notation not yet implemented]
+% #2 a macro name. \def#2{.....} will be used to assign the mantisse.
+% #3 a macro name. \def#3{.....} will be used to assign the exponent (base 10).
+%
+% Example:
+% \def\normalize#1{%
+% \sciparse#1\to\M\powten\E
+% \[ #1 \mapsto \M\cdot 10^{\E} \]
+% }
+% \normalize{123.41251}%
+% \normalize{3.26101452e-06}%
+%
+% REMARKS:
+% - the mantisse will ALWAYS have a period and one following number.
+% - Special case: the number +- 0 will always have the mantisse 0.0. The sign and
+% the exponent is undefined.
+\def\sciparse#1\to#2\powten#3{%
+ \begingroup
+ \sciparse@impl@possibly@signed#1\to#2\powten{#3}%
+ \xdef\sciparseTMP{%
+ \noexpand\def\noexpand#2{#2}%
+ \noexpand\def\noexpand#3{#3}%
+ }%
+ \endgroup
+ \sciparseTMP
+}
+
+% Overloaded scientific parser.
+%
+% In addition to '\sciparse', this method checks for '+- 0' cases
+% and sets #2 accordingly.
+%
+% \S #2: will be \def'ed to one of [0,1,2] with
+% 0 == '0', ( \def#2{0} )
+% 1 == '+',
+% 2 == '-',
+% -> can be used with \ifcase
+% \M #3: will be filled with a positive mantisse (undefined in case \S=0).
+% \E #4: the exponent basis 10 (an integer). Undefined in case \S = 0.
+%
+% Example:
+% \sciparsesign141.212\S\M\E
+% -> \S = 1, \M = 1.41212, \E =2
+%
+\def\sciparsesign#1#2#3#4{%
+ \begingroup
+ \sciparsesign@impl@possibly@signed#1\S#2\M#3\E{#4}%
+ \def\sciparseTMP{0}%
+ \ifx\sciparseTMP#2\relax
+ \def#4{0}%
+ \fi
+ \xdef\sciparseTMP{%
+ \noexpand\def\noexpand#2{#2}%
+ \noexpand\def\noexpand#3{#3}%
+ \noexpand\def\noexpand#4{#4}%
+ }%
+ \endgroup
+ \sciparseTMP
+}
+
+\def\sciparsesignsingle#1#2{%
+ \begingroup
+ \sciparsesign{#1}\sci@S\sci@M\sci@E
+ \xdef\sciparseTMP{\noexpand\scisetcomponents{\noexpand#2}{\sci@S}{\sci@M}{\sci@E}}%
+ \endgroup
+ \sciparseTMP
+}
+
+% Compares
+% x = Sign(#1) #2 * 10^#3
+% with
+% y = Sign(#4) #5 * 10^#6
+%
+% example:
+% \scimathlessthan\S\M\E\and\SS\MM\EE
+% \ifscimathlessthan
+% is smaller!
+% \else
+% is not smaller.
+% \fi
+%
+% and sets the boolean
+% \ifscimathlessthan := (x<y).
+\def\scimathlessthan#1#2#3\and#4#5#6{%
+ \scimathlessthanfalse
+ \begingroup
+ \let\S@first=\c@pgf@counta
+ \let\S@second=\c@pgf@countb
+ \S@first\expandafter=#1\relax
+ \S@second\expandafter=#4\relax
+ \ifcase\S@first
+ % x = 0 -> (x<y <=> y >0)
+ \ifnum1=\S@second
+ \aftergroup\scimathlessthantrue
+ \fi
+ \or
+ % x > 0 -> (x<y <=> ( y > 0 && |x| < |y|) )
+ \ifnum1=\S@second
+ % y>0:
+ \scimathlessthan@positive\M#2\E#3\MM#5\EE{#6}%
+ \fi
+ \or
+ % x < 0 -> (x<y <=> (y >= 0 || |x| > |y|) )
+ \ifnum2=\S@second
+ % 'y<0':
+ \scimathlessthan@positive\M#5\E#6\MM#2\EE{#3}%
+ \else
+ \aftergroup\scimathlessthantrue
+ \fi
+ \fi
+ \endgroup
+}
+
+\def\scimathmax#1#2#3\and#4#5#6\to#7#8#9{%
+ \scimathlessthan#1#2#3\and#4#5#6\relax
+ \ifscimathlessthan
+ \let#7=#4
+ \let#8=#5
+ \let#9=#6
+ \else
+ \let#7=#1
+ \let#8=#2
+ \let#9=#3
+ \fi
+}
+
+\def\scimathmin#1#2#3\and#4#5#6\to#7#8#9{%
+ \scimathlessthan#1#2#3\and#4#5#6\relax
+ \ifscimathlessthan
+ \let#7=#1
+ \let#8=#2
+ \let#9=#3
+ \else
+ \let#7=#4
+ \let#8=#5
+ \let#9=#6
+ \fi
+}
+
+% Takes \S, \M and \E as sign, mantisse and exponent and computes a
+% fixed point representation for that number.
+%
+% example:
+% \S=1
+% \M=4.2
+% \E=1
+% \scitofixed\S\M\E\result
+% -> 42.0
+\def\scitofixed#1#2#3#4{%
+ \begingroup
+ \let\sci@sign=\c@pgf@counta
+ \sci@sign\expandafter=#1\relax
+ \ifnum0=\sci@sign
+ \xdef\sciparseTMP{0.0}%
+ \else
+ \expandafter\scitofixed@impl#2\E#3\END
+ \ifnum2=\sci@sign
+ \xdef\sciparseTMP{-\sciparseTMP}%
+ \fi
+ \fi
+ \endgroup
+ \let#4=\sciparseTMP
+}
+
+% Single macro SCI-representation to #2.
+\def\scitofixedsingle#1#2{%
+ \begingroup
+ \scigetcomponents{#1}\sci@S\sci@M\sci@E
+ \scitofixed\sci@S\sci@M\sci@E{#2}%
+ \global\let\sciparseTMP=#2%
+ \endgroup
+ \let#2=\sciparseTMP
+}
+
+% Takes a SINGLE macro representing a floating point and extracts
+% sign, mantisse and exponent.
+% #1: the name of the single macro.
+% The expansion of #1 is COMPLETELY independend of associated
+% floating point number. You can even use \def#1{foo bar}
+% so change the meaning of #1 without affecting the number.
+% #2: will be set to #1's sign
+% #3: will be set to #1's mantisse
+% #4: will be set to #1's exponent
+%
+% @see scisetcomponents
+\def\scigetcomponents#1#2#3#4{%
+ \expandafter\let\expandafter#2\csname\string#1@S\endcsname
+ \expandafter\let\expandafter#3\csname\string#1@M\endcsname
+ \expandafter\let\expandafter#4\csname\string#1@E\endcsname
+}
+
+% Assigns sign #2, mantisse #3 and exponent #4 to a single macro
+% representing the floating point.
+%
+% #1: the target name. Will create macros #1@S, #1@M and #1@E
+% which will be filled with #2, #3 and #4.
+%
+% Remark:
+% It is perfectly save to use the macro name #1 for other uses since
+% only the '@{S,M,E}' - macros are used to maintain the numerical
+% information.
+%
+% @see scigetcomponents
+\def\scisetcomponents#1#2#3#4{%
+ \expandafter\edef\csname\string#1@S\endcsname{#2}%
+ \expandafter\edef\csname\string#1@M\endcsname{#3}%
+ \expandafter\edef\csname\string#1@E\endcsname{#4}%
+}
+
+% Divides or multiplies the input number by 10^#4 using an arithmetic
+% left/right shift.
+%
+% Input:
+% #1 Sign macro
+% #2 Mantisse macro
+% #3 exponent macro
+% #4 a positive or negative integer number denoting the shift.
+%
+% Example:
+% \scimathshift\S\M\E4
+\def\scimathshift#1#2#3#4{%
+ \begingroup
+ \c@pgf@counta\expandafter=#3\relax
+ \advance\c@pgf@counta by#4\relax
+ \xdef\sciparseTMP{\the\c@pgf@counta}%
+ \endgroup
+ \let#3=\sciparseTMP
+}
+
+\def\scimathshiftsingle#1#2{%
+ \begingroup
+ \expandafter\let\expandafter\E\csname\string#1@E\endcsname
+ \c@pgf@counta\expandafter=\E\relax
+ \advance\c@pgf@counta by#2\relax
+ \xdef\sciparseTMP{\the\c@pgf@counta}%
+ \endgroup
+ \expandafter\let\csname\string#1@E\endcsname\sciparseTMP%
+}
+
+
+% Rounds a fixed point number #1 to #2 digits precision and returns
+% the result into macro #3.
+%
+% This method is PURELY text based and can work with arbirtrary
+% precision (well, limited to TeX's stack size and integer size).
+\def\fixedpointround#1\prec#2\to#3{%
+ \begingroup
+ \pgfplots@toka={}%
+ \let\fp@round@next=\empty
+ \let\fp@round@prec=\c@pgf@countb
+ \let\fp@offsetbehindperiod=\c@pgf@counta
+ \let\fp@round@lastzeros=\c@pgf@countc
+ \let\fp@round@trg=#3\relax
+ \def\fp@round@input{#1}%
+ \fp@round@prec=#2\relax
+ \fp@round@lastzeros=0
+ \fp@offsetbehindperiod=-1 % means: no period found so far
+ \fixedpointround@impl@ITERATE@NODOT #1\fp@round@EOI
+ \xdef\sciparseTMP{\fp@round@trg}%
+ \endgroup
+ \let#3=\sciparseTMP
+}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IMPL
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% \fixedpointround implementation in WORDS:
+%
+% coarse idea:
+% 1. collect all digits/sign BEFORE the first period in REVERSE order
+% 2. then, collect UP TO \prec digits after the period in REVERSE order
+% Steps 1. and 2. lead to the digit [sign] sequence
+% "x_{-p} x_{-p+1} ... x_{-2} x_{-1} '.' x_0 ... x_r"
+% where 'r' is the total number of digits. The integer 'p' denotes the
+% ACTUALLY collected number of digits behind the period.
+%
+% Let 'k' be the desired precision.
+%
+% There are exactly TWO cases:
+% 1. The case with p<=k and x_{-p-1} = end of input.
+% 2. The case with p=k and x_{-p-1} is a further, next character.
+%
+% Then, we do in case 1.)
+% discard any unused zeros at the tail of our number (possibly
+% including the period)
+%
+% and in case 2.)
+% if NEXT DIGIT < 5:
+% do exactly the same as in case 1.) above and discard any
+% following digits.
+% else
+% let q := -p
+% while(x_q = 9 and q<=r )
+% if q>=0
+% set x_q = '0'
+% else
+% discard digit x_q='9'
+% fi
+% ++q
+% if q=0
+% discard the period
+% fi
+% end while
+% if q = r+1
+% insert a '1'
+% else
+% set x_q = x_q + 1
+% fi
+% fi
+%
+% All these loops have been implemented in spaghetti-code below.
+% Sorry, I fear its hard to understand. In principle, everything is
+% realised using more or less finite state machines (with some number
+% counting logic).
+%
+% Some comments:
+% - The token register \pgfplots@toka is used to accumulate the REVERSED input number.
+% - \fp@round@EOI always denotes 'END OF INPUT'.
+% - in the second stage, we need to reverse \pgfplots@toka.
+% This is -again- done with \pgfplots@toka.
+
+\def\fixedpointround@impl@discard@period#1.#2\fp@round@EOI{%
+ \def\fp@round@trg{#1}%
+}
+
+\def\fixedpointround@impl@gobble@rest@and@start#1\fp@round@EOI{%
+ \fixedpointround@impl@start
+}
+\def\fixedpointround@impl@gobble@and@start\fp@round@EOI{%
+ \fixedpointround@impl@start
+}
+\def\fixedpointround@impl@gobble\fp@round@EOI{}%
+
+\def\fixedpointround@impl@start{%
+ \ifx\fp@round@next\empty
+ \ifnum\fp@offsetbehindperiod<0
+ \edef\fp@round@trg{\fp@round@input}%
+ \else
+ \ifnum\fp@offsetbehindperiod>\fp@round@prec
+ \errmessage{Internal logic error in fixedpointround at [I] - should not have happened!?}%
+ \fi
+ \fixedpointround@impl@discard@suffix@zeros
+ \fi
+ \else
+ \ifnum\fp@offsetbehindperiod=\fp@round@prec
+ \else
+ \errmessage{Internal logic error in fixedpointround at [II] - should not have happened!? I have offsetbehindperiod=\the\fp@offsetbehindperiod and prec = \the\fp@round@prec}%
+ \fi
+ \expandafter\ifnum\fp@round@next<5
+ \fixedpointround@impl@discard@suffix@zeros
+ \else
+ \multiply\fp@offsetbehindperiod by-1
+ %\edef\fp@round@trg{B\the\pgfplots@toka B}%
+ \expandafter\fixedpointround@impl@ADD@ONE\the\pgfplots@toka\fp@round@EOI
+ \fi
+ \fi
+}
+
+\def\fixedpointround@impl@ADD@ONE{%
+ \pgfplots@toka={}%
+ \fixedpointround@impl@ADD@ONE@ITERATE
+}
+\def\fixedpointround@impl@ADD@ONE@ITERATE{%
+ \@ifnextchar\fp@round@EOI{%
+ \edef\fp@round@trg{1\the\pgfplots@toka}%
+ \fixedpointround@impl@gobble
+ }{%
+ \@ifnextchar.{%
+ \fixedpointround@impl@ADD@ONE@NEXT@COLLECT
+ }{%
+ \@ifnextchar+{%
+ \fixedpointround@impl@ADD@ONE@NEXT@COLLECT
+ }{%
+ \@ifnextchar-{%
+ \fixedpointround@impl@ADD@ONE@NEXT@COLLECT
+ }{%
+ \fixedpointround@impl@ADD@ONE@NEXT
+ }%
+ }%
+ }%
+ }%
+}
+
+\def\fixedpointround@impl@ADD@ONE@ITERATE@gobble@dot.{%
+ \fixedpointround@impl@ADD@ONE@ITERATE
+}
+
+\def\fixedpointround@impl@ADD@ONE@NEXT@COLLECT#1{%
+ \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}%
+ \fixedpointround@impl@ADD@ONE@ITERATE
+}
+\def\fixedpointround@impl@ADD@ONE@NEXT#1{%
+ \ifnum#1=9
+ \ifnum\fp@offsetbehindperiod<0
+ % silently DROP digit
+ \else
+ \pgfplots@toka=\expandafter{\expandafter0\the\pgfplots@toka}%
+ \fi
+ \advance\fp@offsetbehindperiod by1
+ \ifnum\fp@offsetbehindperiod=0
+ \def\fp@round@nextcmd{\fixedpointround@impl@ADD@ONE@ITERATE@gobble@dot}%
+ \else
+ \def\fp@round@nextcmd{\fixedpointround@impl@ADD@ONE@ITERATE}%
+ \fi
+ \else
+ % re-use this counter:
+ \fp@round@lastzeros=#1
+ \advance\fp@round@lastzeros by1
+ \edef\fp@round@trg{\the\fp@round@lastzeros\the\pgfplots@toka}%
+ \pgfplots@toka=\expandafter{\fp@round@trg}%
+ \def\fp@round@nextcmd{\fixedpointround@impl@REVERSE@ITERATE}%
+ \fi
+ \fp@round@nextcmd
+}
+
+
+\def\fixedpointround@impl@discard@suffix@zeros{%
+ \ifnum\fp@round@lastzeros=\fp@offsetbehindperiod
+ \expandafter\fixedpointround@impl@discard@period\fp@round@input\fp@round@EOI
+ \else
+ \ifnum\fp@round@lastzeros=0
+ \expandafter\fixedpointround@impl@REVERSE\the\pgfplots@toka\fp@round@EOI
+ \else
+ \expandafter\fixedpointround@impl@discard@suffix@zeros@ITERATE\the\pgfplots@toka\fp@round@EOI
+ \fi
+ \fi
+}
+
+% PRECONDITION:
+% \fp@round@lastzeros > 0
+\def\fixedpointround@impl@discard@suffix@zeros@ITERATE#1{%
+ \advance\fp@round@lastzeros by-1
+ \ifnum\fp@round@lastzeros=0
+ \def\fp@round@nextcmd{\fixedpointround@impl@REVERSE}%
+ \else
+ \def\fp@round@nextcmd{\fixedpointround@impl@discard@suffix@zeros@ITERATE}%
+ \fi
+ \fp@round@nextcmd
+}
+
+\def\fixedpointround@impl@REVERSE{%
+ \pgfplots@toka={}%
+ \fixedpointround@impl@REVERSE@ITERATE
+}
+
+\def\fixedpointround@impl@REVERSE@ITERATE{%
+ \@ifnextchar\fp@round@EOI{%
+ \edef\fp@round@trg{\the\pgfplots@toka}%
+ \fixedpointround@impl@gobble
+ }{%
+ \fixedpointround@impl@REVERSE@NEXT
+ }%
+}
+
+\def\fixedpointround@impl@REVERSE@NEXT#1{%
+ \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}%
+ \fixedpointround@impl@REVERSE@ITERATE
+}
+
+\def\fixedpointround@impl@BEGIN@DOT.{%
+ \pgfplots@toka=\expandafter{\expandafter.\the\pgfplots@toka}%
+ \fp@offsetbehindperiod=0
+ \fixedpointround@impl@ITERATE@DOT
+}
+\def\fixedpointround@impl@ITERATE@DOT{%
+ \@ifnextchar\fp@round@EOI{%
+ % finished.
+ \fixedpointround@impl@gobble@and@start
+ }{%
+ \fixedpointround@impl@NEXT@DOT
+ }%
+}
+\def\fixedpointround@impl@NEXT@DOT#1{%
+ \ifnum\fp@offsetbehindperiod=\fp@round@prec
+ \def\fp@round@next{#1}%
+ \def\fp@round@nextcmd{\fixedpointround@impl@gobble@rest@and@start}%
+ \else
+ \advance\fp@offsetbehindperiod by1
+ \ifnum#1=0
+ \advance\fp@round@lastzeros by1
+ \else
+ \fp@round@lastzeros=0
+ \fi
+ \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}%
+ \def\fp@round@nextcmd{\fixedpointround@impl@ITERATE@DOT}%
+ \fi
+ \fp@round@nextcmd
+}%
+
+\def\fixedpointround@impl@ITERATE@NODOT{%
+ \@ifnextchar\fp@round@EOI{%
+ \fixedpointround@impl@gobble@and@start
+ }{%
+ \@ifnextchar.{%
+ \fixedpointround@impl@BEGIN@DOT
+ }{%
+ \fixedpointround@impl@NEXT@NODOT
+ }%
+ }%
+}
+\def\fixedpointround@impl@NEXT@NODOT#1{%
+ \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}%
+ \fixedpointround@impl@ITERATE@NODOT
+}%
+
+%--------------------------------------------
+% END of fixedpointround implementation.
+%--------------------------------------------
+
+\newif\ifscimathlessthan
+
+% first character MAY be + or -. This is checked, then
+% \sciparse@impl@positive will be called for the
+% absolute value. The sign is inserted afterwards.
+\def\sciparse@impl@possibly@signed#1#2\to#3\powten#4{%
+ \def\sciparseTMP{#1}%
+ \def\sciparseTMPB{-}%
+ \if\sciparseTMP\sciparseTMPB
+ \sciparse@impl@positive@possibly@noperiod#2.\to#3\powten#4\S\sciparseTMPB%
+ \edef#3{-#3}%
+ \else
+ \def\sciparseTMPB{+}%
+ \if\sciparseTMP\sciparseTMPB
+ \sciparse@impl@positive@possibly@noperiod#2.\to#3\powten#4\S\sciparseTMPB%
+ \else
+ \sciparse@impl@positive@possibly@noperiod#1#2.\to#3\powten#4\S\sciparseTMPB%
+ \fi
+ \fi
+}
+
+% the same as above, only the return value is different.
+\def\sciparsesign@impl@possibly@signed#1#2\S#3\M#4\E#5{%
+ \def\sciparseTMP{#1}%
+ \def\sciparseTMPB{-}%
+ \if\sciparseTMP\sciparseTMPB
+ \def#3{2}%
+ \sciparse@impl@positive@possibly@noperiod#2.\to#4\powten#5\S#3%
+ \else
+ \def#3{1}%
+ \def\sciparseTMPB{+}%
+ \if\sciparseTMP\sciparseTMPB
+ \sciparse@impl@positive@possibly@noperiod#2.\to#4\powten#5\S#3%
+ \else
+ \sciparse@impl@positive@possibly@noperiod#1#2.\to#4\powten#5\S#3%
+ \fi
+ \fi
+}
+
+% XXXX -> XXXX.0
+% XXXX.YYY -> XXXX.YYYY
+\def\sciparse@impl@positive@possibly@noperiod#1.#2\to#3\powten#4\S#5{%
+%\tracingmacros=2\tracingcommands=2
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ \sciparse@impl@positive@noperiod@possibly@SCI#1e\to#3\powten#4\S{#5}%
+ \else
+ \expandafter\sciparse@impl@positive\sciformat@pop@last@of@two@dots#1.#2\to#3\powten#4\S{#5}%
+ \fi
+}
+\def\sciformat@pop@last@of@two@dots#1.#2.{#1.#2}%
+
+\def\sciparse@impl@positive@noperiod@possibly@SCI#1e#2\to#3\powten#4\S#5{%
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ % this case applies to
+ % 1234 -> 1234.0
+ \sciparse@impl@positive#1.0\to#3\powten#4\S{#5}%
+ \else
+ % this case applies to
+ % 1e1 -> 1.0e1
+ % in this case, #1e#2 = 1e1e, so we have to discard a suffix 'e'.
+ \edef\sciparseTMP{#1.0e\sciformat@popsuffix@e@expansion#2}%
+ \expandafter\sciparse@impl@positive\sciparseTMP\to#3\powten#4\S{#5}%
+ \fi
+}
+
+% XXXXX.XXXXX -> X.XXXXXXX * 10^4
+% 0.0000XXXXX -> X.XXXX * 10^{-5}
+%
+% or
+% XXXX.XXXXXeYYY -> X.XXXXXX* 10^{3+YYY}
+% 0.0000XXXXeYYY -> X.XXX* 10^{-5+YYY}
+%
+% this version does not accept a sign. A period is required.
+%
+% The return value #6 will be \def'ed to '0' if the resulting mantisse is '0'.
+% Won't be touched otherwise.
+\def\sciparse@impl@positive#1#2.#3\to#4\powten#5\S#6{%
+% \begingroup
+% FIXME! restore variables!!
+%\tracingmacros=2\tracingcommands=2
+%\tracingmacros=0\tracingcommands=0
+ \sciparse@positive@getexisting@exponent@e#3e\preexponentto\preexponentstring\exponenttocount\c@pgf@counta
+ % will \c@pgf@counta will be initialised in the line above
+ % \c@pgf@counta=0
+ \ifnum#1=0
+ % the case 0.0000XXXX
+ % does also handle 0.0000XXXXeXXX
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ \c@pgf@countb=0
+ \expandafter\sciformat@count@leading@zeros\preexponentstring\to\c@pgf@countb
+ \advance\c@pgf@countb by1
+ \advance\c@pgf@counta by-\c@pgf@countb
+ \edef#5{\the\c@pgf@counta}%
+ \expandafter\sciformat@assignmantisse\preexponentstring\to#4\countdownzerosfrom\c@pgf@countb\S{#6}%
+ \else
+ % the case 000.0000XXXXX
+ % is not allowed and does not make sense.
+ \errmessage{INVALID NUMBER FORMAT: leading zeros 00*.* not supported yet}%
+ \fi
+ \else
+ % the case NXXXXX.XXXXXXX
+ % or NXXXXXX.XXXXXXeXXXX
+ % where N in [1-9]
+ \sciformat@strlen#1#2\to\c@pgf@counta
+ \advance\c@pgf@counta by-1
+ \edef#4{#1.#2\preexponentstring}%
+ \edef#5{\the\c@pgf@counta}%
+ \fi
+%\tracingmacros=0\tracingcommands=0
+% \endgroup
+}
+
+% parses scientific notation and returns the exponent and everything
+% before the exponent like
+%
+% XXXXXXXeYYYY -> \def#2{XXXXXXX} #3=YYYY
+% or
+% XXXXXXXXe -> \def#2{XXXXXXXX} #3=0
+%
+% Examples:
+% - \sciparse@exponent@e123456e\preexponentto\M\exponenttocount\acount
+% \M->123456
+% \acount=0
+% Please note that the input was 123456e -> at least 'e' is expected!
+%
+% - \sciparse@exponent@e123456e-10e\preexponentto\M\exponenttocount\acount
+% \M->123456
+% \acount=-10
+% Again, the suffix 'e' is REQUIRED. This allows to reduce \ifs.
+\def\sciparse@positive@getexisting@exponent@e#1e#2\preexponentto#3\exponenttocount#4{%
+ \def#3{#1}%
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ #4=0
+ \else
+ \sciformat@popsuffix@e#2\tocount{#4}%
+ \fi
+}
+
+% XXXXXe -> #2=XXXXX where X in [+-0-9].
+\def\sciformat@popsuffix@e#1e\tocount#2{%
+ #2=#1
+}
+
+\def\sciformat@popsuffix@e@expansion#1e{%
+ #1%
+}%
+
+% 00000XXXXXX -> X.XXXXX
+% Inputs:
+% #1 = 00000XXXXXX
+% #2 a macro name
+% #3 a count in which the number of zeros plus one is contained (i.e.
+% the number of shifts).
+% #4 a macro name which will be \def'ed to '0' if the resulting
+% mantisse is 0. Won't be touched otherwise.
+\def\sciformat@assignmantisse#1\to#2\countdownzerosfrom#3\S#4{%
+ \pgfplots@toka={#1}%
+ \loop
+ \ifnum#3=1
+ \else
+ \expandafter\sciformat@popfirst\the\pgfplots@toka\to{\pgfplots@toka}%
+ \advance#3 by-1
+ \repeat
+ \edef\sciformat@assignmantisseTMP{\the\pgfplots@toka}%
+ \ifx\sciformat@assignmantisseTMP\empty
+ % The case 0.0 * 10^0
+ \def#2{0.0}%
+ \def#4{0}%
+ \else
+ \expandafter\sciformat@insertperiod\the\pgfplots@toka\to{#2}%
+ \fi
+}
+
+% XXXXXX -> X.XXXXX into #3
+\def\sciformat@insertperiod#1#2\to#3{%
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ \def#3{#1.0}%
+ \else
+ \def#3{#1.#2}%
+ \fi
+}
+
+% discards the first token.
+\def\sciformat@popfirst#1#2\to#3{%
+ #3={#2}%
+}
+
+% adds the string length of #1#2 into the count register #3.
+%
+% The register won't be initialised to zero!
+\def\sciformat@strlen#1#2\to#3{%
+ \advance#3 by1
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ \else
+ \sciformat@strlen#2\to{#3}%
+ \fi
+}
+
+% Adds the number of leadings zeros of #1#2 into the count register
+% #3.
+%
+% The register won't be initialised to zero!
+\def\sciformat@count@leading@zeros#1#2\to#3{%
+ \ifnum#1=0
+ \advance#3 by1
+ \def\sciparseTMP{#2}%
+ \ifx\sciparseTMP\empty
+ \else
+ \sciformat@count@leading@zeros#2\to{#3}%
+ \fi
+ \fi
+}
+
+
+
+
+
+
+\def\scimathlessthan@positive\M#1\E#2\MM#3\EE#4{%
+ \c@pgf@counta\expandafter=#2\relax
+ \c@pgf@countb\expandafter=#4\relax
+ \ifnum\c@pgf@counta<\c@pgf@countb
+ \aftergroup\scimathlessthantrue
+ \else
+ \ifnum\c@pgf@counta=\c@pgf@countb\relax
+ \pgfmath@xa\expandafter=#1 pt\relax
+ \pgfmath@xb\expandafter=#3 pt\relax
+ \ifdim\pgfmath@xa<\pgfmath@xb
+ \aftergroup\scimathlessthantrue
+ \fi
+ \fi
+ \fi
+}
+
+\def\scitofixed@impl#1.#2\E#3\END{%
+ \let\scitofixed@exponent=\c@pgf@countb
+ \scitofixed@exponent\expandafter=#3\relax
+ \ifnum\scitofixed@exponent<0
+ \pgfplots@toka={0.}%
+ \loop
+ \ifnum\scitofixed@exponent<-1
+ \pgfplots@toka=\expandafter{\the\pgfplots@toka 0}%
+ \advance\scitofixed@exponent by1
+ \repeat
+ \def\sciparseTMPB{#2}%
+ \def\sciparseTMPC{0}%
+ \ifx\sciparseTMPB\sciparseTMPC
+ \xdef\sciparseTMP{\the\pgfplots@toka #1}%
+ \else
+ \xdef\sciparseTMP{\the\pgfplots@toka #1#2}%
+ \fi
+ \else
+ \ifnum\scitofixed@exponent=0
+ \xdef\sciparseTMP{#1.#2}%
+ \else
+ \pgfplots@toka={#1}%
+ \scitofixed@impl@collectmantisse#2\count\scitofixed@exponent
+ \xdef\sciparseTMP{\the\pgfplots@toka}%
+ \fi
+ \fi
+}
+
+\def\scitofixed@impl@collectmantisse#1#2\count#3{%
+ \pgfplots@toka=\expandafter{\the\pgfplots@toka #1}%
+ \advance\scitofixed@exponent by-1
+ \def\sciparseTMPB{#2}%
+ \ifx\sciparseTMPB\empty
+ \loop
+ \ifnum\scitofixed@exponent>0
+ \pgfplots@toka=\expandafter{\the\pgfplots@toka 0}%
+ \advance\scitofixed@exponent by-1
+ \repeat
+ \else
+ \ifnum\scitofixed@exponent=0
+ \pgfplots@toka=\expandafter{\the\pgfplots@toka .#2}%
+ \else
+ \scitofixed@impl@collectmantisse#2\count#3%
+ \fi
+ \fi
+}