%--------------------------------------------
%
% Package pgfplots
%
% Provides a user-friendly interface to create function plots (normal
% plots, semi-logplots and double-logplots).
%
% It is based on Till Tantau's PGF package.
%
% Copyright 2007-2010 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 .
%
%--------------------------------------------
% This file contains the code to process coordinates
% - coordinate input: \addplot and its variants,
% - coordinate loops,
% - single coordinate processing
%
% -> see \pgfplots@addplot
% To be called inside of an axis as soon as the axis is ready and all
% point commands can be invoked.
\def\pgfplotspoint@initialisation{%
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@v00\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@v01\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@v10\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@v11\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@0v0\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@0v1\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@1v0\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@1v1\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@00v\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@01v\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@10v\endcsname\relax
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@11v\endcsname\relax
%
% Installs e_x, e_y and e_z such that (0,0) is the 'south west'
% anchor of the axis and (1,1) the 'north east'.
% It is used inside of descriptions.
\def\pgfplots@install@description@xyzvec{%
% this here is also used in color bars!
\ifpgfplots@deprecated@anchors
\pgfpointadd{\pgfplotspointxaxis}{\pgfplotspointyaxis}%
\else
\pgfplotspointbbdiagonal
\fi
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
% do not use \pgfqpoint here - it may have been replaced
% (compare \pgfplots@change@pgfpoints@to@descriptioncs)
\pgfsetxvec{\global\pgf@x=\pgf@xa \global\pgf@y=0pt }%
\pgfsetyvec{\global\pgf@x=0pt \global\pgf@y=\pgf@ya}%
\pgfsetzvec{\global\pgf@x=0pt \global\pgf@y=0pt }%
}%
%
% The \pgfplotsqpointxyz method (or its 2d counterpart) are THE
% point method. If you override them, all other coordinate systems
% should inherit the changes as well.
\edef\pgfplotsplothandlerpointxyz##1##2##3{%
\ifpgfplots@curplot@threedim
\noexpand\pgfplotsqpointxyz{##1}{##2}{##3}%
\else
\noexpand\pgfplotsqpointxy{##1}{##2}%
\fi
}%
%
% A point command such that (0,0) is the 'south west' and (1,1)
% the 'north east' point of an axis.
\def\pgfplotspointdescriptionxy##1##2{%
\pgf@process{%
\pgfplots@install@description@xyzvec
\pgfpointadd
{\ifpgfplots@deprecated@anchors
\pgfplotspointminminmin
\else
\pgfplotspointbblowerleft
\fi}%
{\pgfpointxy@orig{##1}{##2}}%
%I use the '@orig' variant here because descriptions may
%\let\pgfpointxy=\pgfplotspointdescriptionxy
}%
}%
% the 'q' variant:
\def\pgfplotsqpointdescriptionxy##1##2{%
\pgf@process{%
\pgfplots@install@description@xyzvec
\pgfpointadd
{\ifpgfplots@deprecated@anchors
\pgfplotspointminminmin
\else
\pgfplotspointbblowerleft
\fi}%
{\pgfqpointxy@orig{##1}{##2}}%
}%
}%
\pgfplotspoint@initialisation@axes
\pgfplotspoint@initialisation@units
\pgfplotspoint@initialisation@center
%
% declare the '[xyz]ticklabel cs'
\tikzdeclarecoordinatesystem{xticklabel}{\pgfplotspointticklabelcs{x}{##1}}%
\tikzdeclarecoordinatesystem{yticklabel}{\pgfplotspointticklabelcs{y}{##1}}%
\tikzdeclarecoordinatesystem{zticklabel}{\pgfplotspointticklabelcs{z}{##1}}%
\tikzdeclarecoordinatesystem{xticklabel*}{\pgfplotspointticklabelnoshiftcs{x}{##1}}%
\tikzdeclarecoordinatesystem{yticklabel*}{\pgfplotspointticklabelnoshiftcs{y}{##1}}%
\tikzdeclarecoordinatesystem{zticklabel*}{\pgfplotspointticklabelnoshiftcs{z}{##1}}%
%
% does also declare the 'near xticklabel*' variants.
\pgfplotsdeclareborderanchorforticklabelaxis{x}{near xticklabel}%
\pgfplotsdeclareborderanchorforticklabelaxis{y}{near yticklabel}%
\pgfplotsdeclareborderanchorforticklabelaxis{z}{near zticklabel}%
%
\pgfkeysdef{/tikz/sloped like x axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{x}}}%
\pgfkeysdef{/tikz/sloped like y axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{y}}}%
\pgfkeysdef{/tikz/sloped like z axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{z}}}%
%
}%
% Determine final axes this does also fix the axis' dimension.
% 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.
% POSTCONDITION: the macros
% \pgfplotspointminminmin
% \pgfplotspoint[xyz]axis
% \pgfplotspoint[xyz]axislength
% are defined (globally).
%
\def\pgfplotspoint@initialisation@axes{%
\begingroup
\ifpgfplots@threedim
\def\pgfplotspointmaxminmin{\pgfplotsqpointxyz{\pgfplots@xmax}{\pgfplots@ymin}{\pgfplots@zmin}}%
\def\pgfplotspointminmaxmin{\pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymax}{\pgfplots@zmin}}%
\pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymin}{\pgfplots@zmin}%
\else
\def\pgfplotspointmaxminmin{\pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymin}}%
\def\pgfplotspointminmaxmin{\pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymax}}%
\pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymin}%
\fi
\xdef\pgfplotspointminminmin{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
% ATTENTION: I re-use registers here! Make sure they won't be
% overwritten! \pgfpointdiff and \pgfplotsqpointxy are ok in this respect.
\let\pgfplots@xcoordminTEX=\pgf@xb
\let\pgfplots@ycoordminTEX=\pgf@yb
\pgfplots@xcoordminTEX=\pgf@x
\pgfplots@ycoordminTEX=\pgf@y
%
%--------------------------------------------------
% FIXME : WHAT IS THIS HERE FOR?
% \pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymax}%
% \ifx\pgfplots@rectangle@width\pgfutil@empty
% \def\pgfplots@tmp@xmax@ymin{\pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymin}}%
% \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.
% \pgf@x=\pgfplots@xcoordminTEX
% \advance\pgf@x by\pgfplots@width
% \edef\pgfplots@tmp@xmax@ymin{\noexpand\pgfqpoint{\the\pgf@x}{\noexpand\pgfplots@ycoordminTEX}}%
% \fi
% \ifx\pgfplots@rectangle@height\pgfutil@empty
% \def\pgfplots@tmp@xmin@ymax{\pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymax}}%
% \else
% \pgf@x=\pgfplots@ycoordminTEX
% \advance\pgf@x\pgfplots@height
% \edef\pgfplots@tmp@xmin@ymax{\noexpand\pgfqpoint{\noexpand\pgfplots@xcoordminTEX}{\the\pgf@x}}%
% \fi
%--------------------------------------------------
\pgfpointdiff
{\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}}
{\pgfplotspointmaxminmin}%
\xdef\pgfplotspointxaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
\pgfmathveclen{\pgf@x}{\pgf@y}%
\xdef\pgfplotspointxaxislength{\pgfmathresult pt}%
%
\pgfpointdiff
{\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}}
{\pgfplotspointminmaxmin}%
\xdef\pgfplotspointyaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
\pgfmathveclen{\pgf@x}{\pgf@y}%
\xdef\pgfplotspointyaxislength{\pgfmathresult pt}%
%
\ifpgfplots@threedim
\pgfpointdiff
{\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}}
{\pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymin}{\pgfplots@zmax}}%
\xdef\pgfplotspointzaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
\pgfmathveclen{\pgf@x}{\pgf@y}%
\xdef\pgfplotspointzaxislength{\pgfmathresult pt}%
\else
\global\let\pgfplotspointzaxis=\pgfpointorigin
\gdef\pgfplotspointzaxislength{0pt}%
\fi
\endgroup
%
}
% PRECONDITION: called after \pgfplotspoint@initialisation@axes
% POSTCONDITION:
% \pgfplotspointcenter is defined.
\def\pgfplotspoint@initialisation@center{%
\begingroup
%
%
\ifpgfplots@threedim
%
\pgfpointscale
{0.5}%
{\pgfplotspointxaxis
\pgf@xa=\pgf@x
\pgf@xb=\pgf@y
\pgfplotspointyaxis%
\advance\pgf@xa by\pgf@x
\advance\pgf@xb by\pgf@y
\pgfplotspointzaxis%
\advance\pgf@xa by\pgf@x
\advance\pgf@xb by\pgf@y
\pgf@x=\pgf@xa
\pgf@y=\pgf@xb
}%
\xdef\pgfplotspointcenter{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
\else
\pgfpointscale
{0.5}%
{\pgfpointadd
\pgfplotspointxaxis%
\pgfplotspointyaxis%
}%
\xdef\pgfplotspointcenter{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}%
\fi
\endgroup
}
% PRECONDITION:
% the unit vectors are set up
%
% POSTCONDITION:
% \pgfplotspointunit[xyz]
% \pgfplotspointunit[xyz]length
% \pgfplotspointunit[xyz]invlength
% are all set up.
\def\pgfplotspoint@initialisation@units{%
\edef\pgfplotspointunitx{\pgf@x=\the\pgf@xx\space\pgf@y=\the\pgf@xy\space}%
\edef\pgfplotspointunity{\pgf@x=\the\pgf@yx\space\pgf@y=\the\pgf@yy\space}%
\let\pgfplotsunitxlength=\pgfplots@x@veclength
\let\pgfplotsunitylength=\pgfplots@y@veclength
\let\pgfplotsunitxinvlength=\pgfplots@x@inverseveclength
\let\pgfplotsunityinvlength=\pgfplots@y@inverseveclength
\ifpgfplots@threedim
\edef\pgfplotspointunitz{\pgf@x=\the\pgf@zx\space\pgf@y=\the\pgf@zy\space}%
\let\pgfplotsunitzlength=\pgfplots@z@veclength
\let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength
\fi
}%
% The idea here is the following:
%
% 1. A point coordinate (,) without units should use
% relative axis coordinate system.
%
% 2. Any other point coordinate should not be altered.
%
% Former versions installed a shift and changed e_x, e_y and
% e_z. However, that was misleading as it disabled point 2).
% So, my idea here is to replace \pgfpointxy and \pgfqpointxy
% such that they install the correct coordinate system before
% doing anything else.
\def\pgfplots@change@pgfpoints@to@descriptioncs{%
%
\let\pgfpointxy=\pgfplotspointdescriptionxy
\let\pgfqpointxy=\pgfplotsqpointdescriptionxy
% e_z is zero, so the xyz variants ignore z:
\def\pgfpointxyz##1##2##3{\pgfpointxy{##1}{##2}}%
\def\pgfqpointxyz##1##2##3{\pgfqpointxy{##1}{##2}}%
%
}%
% \pgfplotspointticklabelcs{}{}
% or
% \pgfplotspointticklabelcs[]{}{}
%
% Yields a point in the 'ticklabel cs'.
%
% The 'xticklabel cs' is a coordinate system which expects either one
% or two coordinates. The first is the coordinate on the axis where
% x tick label will be placed (or would be placed). The first
% coordinate '0' means the lower aixs site and the value '1' the upper
% range. The second (optional) coordinate of 'xticklabel cs' is a
% shift in direction of the outer normal vector of the axis. The
% minimum shift is the largest' tick labels dimensions. If the second
% argument is omitted, the will be used (0pt if this
% argument has been omitted as well).
%
% \pgfplotspointticklabelcs#1#2:
% #1 is the axis (either x,y or z)
% #2 is the coordinate (either or ,)
%
% @see \pgfplotsvalueoflargesttickdimen
%
% This command actually boils down to a
% \pgfplotsqpointoutsideofticklabelaxisrel
% invocation which. Thus, you *can* get the *same* effect by using
% basic level commands -- and you are not restricted to the tick label
% axis.
% @see \pgfplotsqpointoutsideofaxisrel
\def\pgfplotspointticklabelcs{\pgfutil@ifnextchar[%
{\pgfplotspointticklabelcs@opt}%
{\pgfplotspointticklabelcs@opt[0pt]}%
}%
\def\pgfplotspointticklabelcs@opt[#1]#2#3{%
\pgfutil@in@{,}{#3}%
\ifpgfutil@in@
\edef\pgfplots@loc@TMPa{#3}%
\else
\edef\pgfplots@loc@TMPa{#3,#1}%
\fi
\def\pgfplots@loc@TMPb##1,##2\relax{%
% invoke
% \pgfplotsqpointoutsideofticklabelaxisrel{#2}{##1}{ticklabel dimen + ##2}:
\begingroup
\pgfmathparse{##2}%
\pgf@xa=\pgfmathresult pt\relax
\advance\pgf@xa by\pgfplotsvalueoflargesttickdimen{#2} %<- keep this space!
\xdef\pgfplots@glob@TMPa{\pgf@sys@tonumber\pgf@xa}%
\endgroup
\def\pgfplots@loc@TMPa{\pgfplotsqpointoutsideofticklabelaxisrel{#2}{##1}}%
\expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@glob@TMPa}%
}%
\expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\relax
}%
\def\pgfplotspointticklabelnoshiftcs#1#2{%
\pgfutil@in@{,}{#2}%
\ifpgfutil@in@
\edef\pgfplots@loc@TMPa{#2}%
\else
\edef\pgfplots@loc@TMPa{#2,0}%
\fi
\def\pgfplots@loc@TMPb##1,##2\relax{%
% invoke
% \pgfplotsqpointoutsideofticklabelaxisrel{#2}{##1}{##2}:
\pgfmathparse{##2}%
\def\pgfplots@loc@TMPa{\pgfplotsqpointoutsideofticklabelaxisrel{#1}{##1}}%
\expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}%
}%
\expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\relax
}%
% Converts a dimen (with unit!) to a corresponding x, y or z
% coordinate.
% The result will be written to \pgfmathresult (without units).
%
% It is possible to use the result within the \pointxyz command(s).
%
% #1: the axis (x,y or z)
% #2: the dimen
%
% example:
% \pgfplotsconvertunittocoordinate{x}{5pt}
\def\pgfplotsconvertunittocoordinate#1#2{%
\begingroup
\pgf@xa=#2\relax
\pgf@xa=\csname pgfplots@#1@inverseveclength\endcsname\pgf@xa
\edef\pgfmathresult{\pgf@sys@tonumber\pgf@xa}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
% This is the same as using \pgfplotsconvertunittocoordinate for each
% component #1, #2 and #3. The results are directly communicated to
% \pgfplotsqpointxyz.
%
% Expects #1, #2 and #3 to be numbers with units and issues a \pgfplotsqpointxyz
\def\pgfplotsqpointxyzabsolutesize#1#2#3{%
\begingroup
\pgf@xa=#1\relax
\pgf@xa=\pgfplots@x@inverseveclength\pgf@xa
\pgf@xb=#2\relax
\pgf@xb=\pgfplots@y@inverseveclength\pgf@xb
\pgf@ya=#3\relax
\pgf@ya=\pgfplots@z@inverseveclength\pgf@ya
\xdef\pgfplots@glob@TMPa{{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@ya}}%
\endgroup
\expandafter\pgfplotsqpointxyz\pgfplots@glob@TMPa
}%
% Denotes a point in a twodimensional hyperplane. The hyperplane is
% one of the six planes of the threedimensional axis cube.
%
% The meaning of coordinates #1 and #2 will be redefined depending on
% which surface we are currently processing. You can get the axis
% names for '#1' (a) and '#2' (b) using the macros
% \pgfplotspointonorientedsurfaceA (one of the characters x,y or z)
% and
% \pgfplotspointonorientedsurfaceB.
% The surface normal direction is
% \pgfplotspointonorientedsurfaceN.
%
% Example:
% \pgfplotspointonorientedsurfaceabsetupfor xyz
% \pgfplotspointonorientedsurfaceabsetupforsetz{}{0}
%
% ->
% \pgfplotspointonorientedsurfaceA = x
% \pgfplotspointonorientedsurfaceB = y
% \pgfplotspointonorientedsurfaceN = z
% \pgfplotspointonorientedsurfacespec = {ab0}
% \pgfplotspointonorientedsurfacespecunordered = {vv0}
% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{3}{4}{}
%
% \pgfplotspointonorientedsurfaceabsetupfor yxz
% \pgfplotspointonorientedsurfaceabsetupforsetz{}{0}
% ->
% \pgfplotspointonorientedsurfaceA = y
% \pgfplotspointonorientedsurfaceB = x
% \pgfplotspointonorientedsurfaceN = z
% \pgfplotspointonorientedsurfacespec = {ba0}
% \pgfplotspointonorientedsurfacespecunordered = {vv0}
% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{4}{3}{}
%
% @see \pgfplotspointonorientedsurfaceabsetupfor xyz
\def\pgfplotspointonorientedsurfaceab#1#2{%
\pgfplots@error{Internal logic error: \string\pgfplotspointonorientedsurfaceab\ used although surface has not been declared! You need to call \string\pgfplotspointonorientedsurfaceabsetupfor xyz\ or its friends to do so.}%
}%
% This is a shortcut for
% \pgfpointadd
% {\pgfplotspointonorientedsurfaceab{#1}{#2}}
% {}
%
% where #3 is a dimension (a number with unit).
\def\pgfplotspointonorientedsurfaceabwithbshift#1#2#3{%
\begingroup
\pgf@xa=#3\relax
\ifdim\pgf@xa=0pt
\else
\pgf@xa=\csname pgfplots@\pgfplotspointonorientedsurfaceB @inverseveclength\endcsname\pgf@xa
\fi
\advance\pgf@xa by#2pt
\edef\pgfplots@loc@b{\pgf@sys@tonumber\pgf@xa}%
\pgf@process{\pgfplotspointonorientedsurfaceab{#1}{\pgfplots@loc@b}}%
\endgroup
}
\pgfkeyssetvalue{/pgfplots/oriented surf installed}{}
% This macro will be defined after
% \pgfplotspointonorientedsurfaceabsetupfor...
% routines. It expands to a three-character string
% where the first character contains information about the x axis,
% the second about the y axis and the third about the z axis.
%
% The single characters can be one of
% - 'a' - the corresponding axis is the PRIMARY direction of the
% oriented surface.
% - 'b' - the corresponding axis is the SECONDARY direction of the
% oriented surface.
% - anything else - the characters provides as second argument for
% \pgfplotspointonorientedsurfaceabsetupforsetz{}{}, for example.
% Common choices are '0' for lower limit, '1' for upper limit and
% '2' for other.
\def\pgfplotspointonorientedsurfacespec{}%
% Similar to \pgfplotspointonorientedsurfacespec, this macro encodes
% the currently active oriented surface.
% However, it only contains the characters 'v', '0' and '1' and '2'.
% The distinction 'v in {a,b}' is eliminated.
\def\pgfplotspointonorientedsurfacespecunordered{}%
% As \pgfplotspointonorientedsurfacespec, this macro contains
% information about the current oriented surface: it contains the
% fixed symbol '0', '1' or '2' describing the only direction which is
% fixed.
\def\pgfplotspointonorientedsurfacespecsymbol{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}
\def\pgfplotspointonorientedsurfaceabsetupfor#1#2#3{%
\pgfutil@ifundefined{pgfplotspointonorientedsurfaceabsetupfor@@#1#2#3}{%
\pgfplots@error{Sorry, \string\pgfplotspointonorientedsurfaceabsetupfor\space#1#2#3 is not yet implemented.}%
}{
\csname pgfplotspointonorientedsurfaceabsetupfor@@#1#2#3\endcsname
}%
}%
%
% Initialises \pgfplotspointonorientedsurfaceab such that 'a' is the x
% axis and 'b' is the y axis and the z coordinate has been fixed with
% \pgfplotspointonorientedsurfaceabsetupforsetz{}.
%
% The Z value needs to be fixed with
% \pgfplotspointonorientedsurfaceabsetupforsetz .
\def\pgfplotspointonorientedsurfaceabsetupfor@@xyz{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedz}}%
\def\pgfplotspointonorientedsurfaceA{x}%
\def\pgfplotspointonorientedsurfaceB{y}%
\def\pgfplotspointonorientedsurfaceN{z}%
\edef\pgfplotspointonorientedsurfacespec{ab\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@yxz{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedz}}%
\def\pgfplotspointonorientedsurfaceA{y}%
\def\pgfplotspointonorientedsurfaceB{x}%
\def\pgfplotspointonorientedsurfaceN{z}%
\edef\pgfplotspointonorientedsurfacespec{ba\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@xzy{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedy}{##2}}%
\def\pgfplotspointonorientedsurfaceA{x}%
\def\pgfplotspointonorientedsurfaceB{z}%
\def\pgfplotspointonorientedsurfaceN{y}%
\edef\pgfplotspointonorientedsurfacespec{a\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol b}%
\edef\pgfplotspointonorientedsurfacespecunordered{v\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol v}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@zxy{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedy}{##1}}%
\def\pgfplotspointonorientedsurfaceA{z}%
\def\pgfplotspointonorientedsurfaceB{x}%
\def\pgfplotspointonorientedsurfaceN{y}%
\edef\pgfplotspointonorientedsurfacespec{b\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol a}%
\edef\pgfplotspointonorientedsurfacespecunordered{v\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol v}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@yzx{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedx}{##1}{##2}}%
\def\pgfplotspointonorientedsurfaceA{y}%
\def\pgfplotspointonorientedsurfaceB{z}%
\def\pgfplotspointonorientedsurfaceN{x}%
\edef\pgfplotspointonorientedsurfacespec{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol ab}%
\edef\pgfplotspointonorientedsurfacespecunordered{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol vv}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@zyx{%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedx}{##2}{##1}}%
\def\pgfplotspointonorientedsurfaceA{z}%
\def\pgfplotspointonorientedsurfaceB{y}%
\def\pgfplotspointonorientedsurfaceN{x}%
\edef\pgfplotspointonorientedsurfacespec{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol ba}%
\edef\pgfplotspointonorientedsurfacespecunordered{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol vv}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
% Fixes 'x' to #1 for use in
% \pgfplotspointonorientedsurfaceabsetupfor zyx and
% \pgfplotspointonorientedsurfaceabsetupfor yzx.
%
% #1: The fixed value for 'x' (a coordinate in transformed range).
% #2: a one-character symbol describing 'x'.
% Command characters are
% 0 : x is the lower x-axis range.
% 1 : x is the upper x-axis range.
% 2 : other.
\def\pgfplotspointonorientedsurfaceabsetupforsetx#1#2{%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedx{#1}%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}%
}%
\def\pgfplotspointonorientedsurfaceabsetupforsety#1#2{%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedy{#1}%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}%
}%
\def\pgfplotspointonorientedsurfaceabsetupforsetz#1#2{%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedz{#1}%
\edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}%
}%
% Helper methods which should be used if no Z component exists (pure
% 2d plots).
\def\pgfplotspointonorientedsurfaceabsetupfor@@xy{%
\def\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{0}%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxy{##1}{##2}}%
\def\pgfplotspointonorientedsurfaceA{x}%
\def\pgfplotspointonorientedsurfaceB{y}%
\def\pgfplotspointonorientedsurfaceN{z}%
\edef\pgfplotspointonorientedsurfacespec{ab\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
\def\pgfplotspointonorientedsurfaceabsetupfor@@yx{%
\def\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{0}%
\def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxy{##2}{##1}}%
\def\pgfplotspointonorientedsurfaceA{y}%
\def\pgfplotspointonorientedsurfaceB{x}%
\def\pgfplotspointonorientedsurfaceN{z}%
\edef\pgfplotspointonorientedsurfacespec{ba\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}%
\pgfkeysvalueof{/pgfplots/oriented surf installed}%
}%
% Assuming we have an oriented surface installed, this command defines
% \pgfplotsretval to be the three-char-string such that the 'a' axis
% if the oriented surface takes value '#1', the 'b' axis of the
% oriented surface takes '#2' and the remaining axis has its fixed
% symbol anyway.
\def\pgfplotspointonorientedsurfaceabtolinespec#1#2{%
\expandafter\pgfplotspointonorientedsurfaceabtolinespec@a\pgfplotspointonorientedsurfacespec\relax#1%
\expandafter\pgfplotspointonorientedsurfaceabtolinespec@b\pgfplotsretval\relax#2%
}%
\def\pgfplotspointonorientedsurfaceabtolinespec@a#1a#2\relax#3{\edef\pgfplotsretval{#1#3#2}}
\def\pgfplotspointonorientedsurfaceabtolinespec@b#1b#2\relax#3{\edef\pgfplotsretval{#1#3#2}}
% Assuming that an oriented surface has been initialised, say 'a0b',
% we have the following possible axis lines which can be drawn:
% - b=0: 'v00'
% - b=1: 'v01'
% - b=2: 'v02'
%
% To check which of them should be drawn, this macro here converts 'a'
% to 'v' and 'b' to '#1'. The remaining possible character will be
% copied as-is.
%
% The resulting three-character-string is written into '#2'.
%
% #1 : the replacement value which will be inserted instead of 'b' in
% the currently active oriented surface.
% #2 : the macro which will contain the output axis line specification
% (three-char-string).
%
% Example:
% \pgfplotspointonorientedsurfaceabsetupfor xyz
% \pgfplotspointonorientedsurfaceabsetupforsetz{}{0}
% -> the oriented surface is 'ab0'
% ...
% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{0}\pgfplotsretval
% -> \pgfplotsretval = 'v00'
% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{1}\pgfplotsretval
% -> \pgfplotsretval = 'v10'
% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{2}\pgfplotsretval
% -> \pgfplotsretval = 'v20'
\def\pgfplotspointonorientedsurfaceabgetcontainedaxisline#1#2{%
\expandafter\pgfplotspointonorientedsurfaceabgetcontainedaxisline@\pgfplotspointonorientedsurfacespec\relax{#1}%
\let#2=\pgfplots@loc@TMPa
}%
% writes into \pgfplots@loc@TMPa:
\def\pgfplotspointonorientedsurfaceabgetcontainedaxisline@#1#2#3\relax#4{%
\pgfplotspointonorientedsurfaceabgetcontainedaxisline@single{#1}{#4}\to\pgfplots@loc@TMPa
\pgfplotspointonorientedsurfaceabgetcontainedaxisline@single{#2}{#4}\to\pgfplots@loc@TMPb
\pgfplotspointonorientedsurfaceabgetcontainedaxisline@single{#3}{#4}\to\pgfplots@loc@TMPc
\edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa\pgfplots@loc@TMPb\pgfplots@loc@TMPc}%
}%
\def\pgfplotspointonorientedsurfaceabgetcontainedaxisline@single#1#2\to#3{%
\if#1a%
\def#3{v}%
\else
\if#1b%
\def#3{#2}%
\else
\def#3{#1}%
\fi
\fi
}%
% Finds the two surfaces which are adjacent to an axis line encoded as
% three-character-string.
%
% There are the following possibilities:
% #1 = 'v**' where '*' is not 'v'.
% -> #2 = 'vv*' and #3 = 'v*v'
%
% #1 = '*v*'
% -> #2 = 'vv*' and #3 = '*vv'
%
% #1 = '**v'
% -> #2 = 'v*v' and #3 = '*vv'
\def\pgfplotsgetadjacentsurfsforaxisline#1\to#2#3{%
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotsgetadjacentsurfsforaxisline@\pgfplots@loc@TMPa\relax{#2}{#3}%
}%
\def\pgfplotsgetadjacentsurfsforaxisline@#1#2#3\relax#4#5{%
\if#1v%
\def#4{vv#3}%
\def#5{v#2v}%
\else
\if#2v%
\def#4{vv#3}%
\def#5{#1vv}%
\else
\def#4{v#2v}%
\def#5{#1vv}%
\fi
\fi
}%
% Executes code '#2' if the axis surface denoted by the
% three-character-string '#1' is a foreground surface and code '#3' if
% the surface '#1' is a background surface.
%
% #1: a three-char-string with the keys
% 'v' = 'varying',
% '0' = 'lower axis limit',
% '1' = 'upper axis limit'.
% The string 'v0v' means that x and z are varying in that surface
% and 'y' is fixed to the lower axis limit.
% #2: code to execute if '#1' is foreground.
% #3: code to execute if '#1' is background.
\def\pgfplotsifaxissurfaceisforeground#1#2#3{%
\pgfutil@ifundefined{pgfplots@surfviewdepth@#1}{%
\pgfplots@error{\string\pgfplotsifaxissurfaceisforeground{#1}: undefined three-character-string '#1' provided.}%
#3%
}{%
\if f\csname pgfplots@surfviewdepth@#1\endcsname #2\else #3\fi
}%
}%
% As \pgfplotsifaxissurfaceisforeground, but for axis lines.
%
% #1: a three-character string with the same keys as in
% \pgfplotsifaxissurfaceisforeground. However, there should be only
% one varying direction as we are dealing with an axis line.
% #2: code to execute if '#1' is foreground.
% #3: code to execute if '#1' is background.
%
\def\pgfplotsifaxislineisforeground#1#2#3{%
\pgfplotsgetadjacentsurfsforaxisline#1\to\pgfplots@loc@TMPb\pgfplots@loc@TMPc
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPb}{%
#2%
}{%
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPc}{%
#2%
}{%
#3%
}%
}%
}%
% Executes code '#2' if the axis surface denoted by the
% three-char-string '#1' is on the convex hull of the projected axis
% cube or code '#3' if that is not the case.
%
% The arguments are the same as for \pgfplotsifaxislineisforeground:
% #1: a three-character string with the same keys as in
% \pgfplotsifaxissurfaceisforeground. However, there should be only
% one varying direction as we are dealing with an axis line.
% #2: code to execute if '#1' is foreground.
% #3: code to execute if '#1' is background.
\def\pgfplotsifaxislineisonconvexhull#1#2#3{%
\pgfplotsgetadjacentsurfsforaxisline#1\to\pgfplots@loc@TMPb\pgfplots@loc@TMPc
% '#1' is on the convex hull if ONE of the adjacent surfs is
% foreground and the other one is background.
\pgfplots@loc@tmpfalse
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPb}{%
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPc}{%
}{%
\pgfplots@loc@tmptrue
}%
}{%
}%
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPb}{%
}{%
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPc}{%
\pgfplots@loc@tmptrue
}{%
}%
}%
\ifpgfplots@loc@tmp #2\else #3\fi
}%
% Executes code '#2' if the axis line with 'b=#1' on the current
% oriented surface shall be drawn.
% If that is not the case, the code '#3' will be executed.
%
% Example:
% Let's assume the current oriented surface is 'b0a'.
% Then,
% \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn{0}{draw it!}{\relax}
% will check whether the line '00v' shall be drawn while
% \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn{1}{draw it!}{\relax}
% will check whether the line '10v' shall be drawn.
%
% The check is based on
% 1. foreground/background flags
% 2. the current configuration of the axis lines key(s)
%
% @see \pgfplotspointonorientedsurfaceabgetcontainedaxisline
\def\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn#1#2#3{%
\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@{#1}{%
\edef\pgfplots@loc@TMPe{\csname pgfplots@\pgfplotspointonorientedsurfaceA axislinesnum\endcsname}%
\if0\pgfplots@loc@TMPe
% boxed axis lines
#2%
\else
\if2\pgfplots@loc@TMPe
% centered axis lines
#2%
\else
% either the 'left' or 'right' positioned cases.
% These have exactly one line which is the one where
% tick labels will be placed. And this, in turn, is
% already known, even for 3D. Check if we have it:
\pgfplotspointonorientedsurfaceabtolinespec v#1%
\edef\pgfplots@loc@TMPe{\csname pgfplots@\pgfplotspointonorientedsurfaceA ticklabelaxisspec\endcsname}%
\ifx\pgfplots@loc@TMPe\pgfplotsretval
#2%
\else
#3%
\fi
\fi
\fi
}{%
#3%
}%
}%
\def\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@allaxislinevariations#1#2#3{%
\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@{#1}{%
#2%
}{%
#3%
}%
}%
% A sub-part of \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn
% which is /only/ based on foreground/background flags.
%
% @ATTENTION : this command will be always true for the 2D case. (it
% will be overwritten, see \pgfplots@decide@which@figure@surfaces@are@drawn)
\def\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@#1#2#3{%
\pgfplotspointonorientedsurfaceabgetcontainedaxisline#1\pgfplots@loc@TMPc
\pgfplotsgetadjacentsurfsforaxisline\pgfplots@loc@TMPc\to\pgfplots@loc@TMPb\pgfplots@loc@TMPc
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPb}{%
\pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPc}{%
#3%
}{%
#2%
}%
}{%
#2%
}%
}%
% Similar to \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn,
% this thing here execute '#1' if grid lines on the currently
% initialised oriented surfaces shall be drawn and '#2' if not.
%
% This does only handle foreground/background issues; it has NOTHING
% to do with the actual checks if grid lines are active or not.
\def\pgfplots@ifgridlines@onorientedsurf@should@be@drawn#1#2{%
% grid lines shall be drawn
% if and only if BOTH adjacent axis lines shall be drawn:
\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@allaxislinevariations{0}{%
% remark: this is ALWAYS true for 2D plots.
\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@allaxislinevariations{1}{%
#1%
}{%
#2%
}%
}{%
#2%
}%
}%
% Checks whether the line specified by a three-character-string '#1'
% is inside of the currently set-up oriented surface.
%
% The return value is encoded as integer into the macro #2 as
% described below.
%
% #1 : a three-character string uniquely identifing an axis line.
% Each of the three characters can be 'v', '0' or '1'.
% The value '0' denotes the lower axis range while '1' denotes
% the upper axis range. The character 'v' stands for 'varying'
% and indicates the direction in which the line varies. The first
% character contains the values for the 'x' axis, the second
% character for the 'y' axis and the third character for the 'z'
% axis.
% Example:
% 'v01' is the axis line with 'y=lower y limit' and 'z=upper z limit'
% '10v' is the axis line with 'x=upper x limit' and 'y=lower y limit'
% The 'v' character indicates the varying component. There may be
% only one 'v'.
% #2 : a macro name. It will be empty if the line is NOT on the
% current surface. If will be non-empty if it IS on the current
% surface.
% To be more precise, If the line IS on the current surface, '#2' will be set to
% the character in '#1' which belongs to the second oriented
% surface axis (which is called the 'b' axis).
% Thus, the following values for '#2' can be expected:
% - '' (empty) if the line is not on the surface,
% - 'v' if the line IS on the surface, and '#1' contains a 'v'
% in direction of the surface's 'b' axis.
% - '0' if the line IS on the surface and '#1' contains a '0' in
% direction of the surface's 'b' axis,
% - '1' if the line IS on the surface and '#1' contains a '1' in
% direction of the surface's 'b' axis.
% No other values are possible.
%
% Example:
% \pgfplotspointonorientedsurfaceabsetupforsetz{\zmax}{1}
% \pgfplotspointonorientedsurfaceabsetupfor yxz
% \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result}
% -> \result will be 'v' because 'x=v' in '{v01}
%
% \pgfplotspointonorientedsurfaceabsetupforsety{\ymin}{0}
% \pgfplotspointonorientedsurfaceabsetupfor xzy
% \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result}
% -> \result will be '1' because 'z=1' in '{v01}
%
% \pgfplotspointonorientedsurfaceabsetupforsety{\ymax}{1}
% \pgfplotspointonorientedsurfaceabsetupfor xzy
% \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result}
% -> \result will be empty because 'y=0' in '{v01}
%
% \pgfplotspointonorientedsurfaceabsetupforsetx{\xmax}{1}
% \pgfplotspointonorientedsurfaceabsetupfor yzx
% \pgfplotspointonorientedsurfaceabmatchaxisline{10v}{\result}
% -> \result will be 'v' because 'z=v' in '{10v}
\def\pgfplotspointonorientedsurfaceabmatchaxisline#1#2{%
\pgfplotsmatchcubeparts{#1}{\pgfplotspointonorientedsurfacespec}{#2}%
}%
% Checks whether the line or surface specified by a three-character-string '#1'
% is inside of the surface designated by the three-character-string '#2'.
%
%
% Arguments:
% #1 a cube-part (axis line or surface) encoded as three character
% string. Can be '0v1' or 'vv0' or so (see above).
% #2 a surface, also encoded as three character string. Maybe
% oriented.
% #3 The return value is encoded as char into the macro #3 as
% described in \pgfplotspointonorientedsurfaceabmatchaxisline:
% '#3' will be EMPTY if '#1' is NOT in '#2'.
% '#3' will be NON-EMPTY if '#1' IS in '#2'.
\def\pgfplotsmatchcubeparts#1#2#3{%
\edef\pgfplots@loc@TMPa{#1:#2}%
\expandafter\pgfplotspointonorientedsurfaceabmatchaxisline@\pgfplots@loc@TMPa\pgfplots@EOI
\let#3=\pgfplots@loc@TMPa
}%
% IMPLEMENTATION:
% The return value is 'yes, #1#2#3 is on the oriented surface #4#5#6'
% if and only if for all three character pairs, the following single
% relations hold.
% Input char oriented surface char
% 'v' : is either a or b or v
% '0' : is either 0, a, b, v or 2 (i.e. NOT 1) FIXME : is the '2' correct here!?
% '1' : is either 1, a, b, v or 2 (i.e. NOT 0)
% '2' : is either 2, a, b, v (i.e. NOT 0 or 1)
% That's all.
%
% If the 'oriented surface char' is 'v', then we actually don't have
% an oriented surface but just a surface.
% So, 'a0b' is the same surface as 'v0v', but the first choice has
% designated orientations.
%
% @POST \pgfplots@loc@TMPa contains the return value macro.
% More precisely, \pgfplots@loc@TMPa will be EMPTY is #1#2#3 is NOT
% on #4#5#6 . It will contain the value on the surface if it IS on
% the surface
\def\pgfplotspointonorientedsurfaceabmatchaxisline@#1#2#3:#4#5#6\pgfplots@EOI{%
% Search for the 'b' character:
\if#4b%
\def\pgfplots@loc@TMPa{#1}%
\else
\if#5b%
\def\pgfplots@loc@TMPa{#2}%
\else
\if#6b%
\def\pgfplots@loc@TMPa{#3}%
\else
\def\pgfplots@loc@TMPa{v}% FALLBACK solution.
\fi
\fi
\fi
% Now, check whether we need to clear the return value (i.e.
% return false)
\pgfplotspointonorientedsurfaceabmatchaxisline@single{#1}{#4}%
\pgfplotspointonorientedsurfaceabmatchaxisline@single{#2}{#5}%
\pgfplotspointonorientedsurfaceabmatchaxisline@single{#3}{#6}%
%\message{\string\pgfplotspointonorientedsurfaceabmatchaxisline@#1#2#3:#4#5#6 = '\pgfplots@loc@TMPa'.^^J}%
}
\def\pgfplotspointonorientedsurfaceabmatchaxisline@single#1#2{%
\if#1v%
\if#2a%
\else
\if#2b%
\else
\if#2v%
\else
\let\pgfplots@loc@TMPa=\pgfutil@empty
\fi
\fi
\fi
\else
\if0#1%
\if1#2%
\let\pgfplots@loc@TMPa=\pgfutil@empty
\fi
\else
\if1#1%
\if0#2%
\let\pgfplots@loc@TMPa=\pgfutil@empty
\fi
\else
\if2#1%
\if0#2%
\let\pgfplots@loc@TMPa=\pgfutil@empty
\fi
\if1#2%
\let\pgfplots@loc@TMPa=\pgfutil@empty
\fi
\else
% return TRUE.
% I admit I am not sure at all if this works in all
% cases
\pgfplotspointonorientedsurfaceabmatchaxisline@warn{#1}%
\fi
\fi
\fi
\fi
}%
\def\pgfplotspointonorientedsurfaceabmatchaxisline@warn#1{%
\pgfplots@warning{The internal implementation is suspicious that something is wrong: \string\pgfplotspointonorientedsurfaceabmatchaxisline@warn: the character '#1' in a three-character axis line or surface description might not be fully supported...}%
}%
% Provides a point on an arbitrary axis (identified by a
% three-character-string) which can take any value on that axis and
% which is shifted in the direction of the outer normal vector.
%
% #1: a three-character-string denoting the desired axis
% #2: the coordinate on that axis (the coordinate for the 'v'
% direction in '#1'). It needs to be given as it would be supplied to
% an \addplot or 'axis cs' coordinate; any logs or data
% transformations will be applied.
% #3: the distance (a dimension) describing how much we should move
% away from that axis. This points to the outside normal vector of the
% axis cube.
%
% @see \pgfplotsqpointoutsideofticklabelaxis
%
% If, in addition, the boolean \ifpgfslopedattime is true, the same
% transformations which would have been applied by
% \pgftransformlineattime will be applied, that means the 'sloped'
% feature of tikz is applied. FIXME : is that up-to-date!?
%
% @see \pgftransformlineattime -- it is quite similar.
\def\pgfplotsqpointoutsideofaxis#1#2#3{%
\begingroup
\def\pgfplotspointoutsideofaxis@plug@trafo##1##2{\csname pgfplotstransformcoordinate##1\endcsname{##2}}%
\let\pgfplotspointoutsideofaxis@plug@getlimit=\pgfplotspointoutsideofaxis@getlimit@
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotspointoutsideofaxis@\pgfplots@loc@TMPa\relax{#2}{#3}%
}%
% A variant of \pgfplotsqpointoutsideofaxis with relative values for
% #2.
% That means
% '#2 = 0' === lower axis limit
% and
% '#2 = 1' === upper axis limit.
\def\pgfplotsqpointoutsideofaxisrel#1#2#3{%
\begingroup
\def\pgfplotspointoutsideofaxis@plug@trafo##1##2{%
\begingroup
% compute ##1min + ##2 * (##1max - ##1min) :
%
\afterassignment\pgfplots@gobble@until@relax
\pgf@xa=##2pt\relax
\edef\pgfplots@loc@TMPa{\pgf@sys@tonumber\pgf@xa}%
%
\pgf@xa=\csname pgfplots@##1min\endcsname pt %
\pgf@xb=\csname pgfplots@##1max\endcsname pt %
\pgf@xc=\pgf@xb
\ifpgfplots@allow@reversal@of@rel@axis@cs
\if\pgfkeysvalueof{/pgfplots/##1 dir/value}r%
% reverse: exchange min and max.
\pgf@xb=\pgf@xa
\pgf@xa=\pgf@xc
\pgf@xc=\pgf@xb
\fi
\fi
\advance\pgf@xc by-\pgf@xa
\pgf@xc=\pgfplots@loc@TMPa\pgf@xc
\advance\pgf@xc by\pgf@xa
\edef\pgfmathresult{\pgf@sys@tonumber\pgf@xc}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}%
\let\pgfplotspointoutsideofaxis@plug@getlimit=\pgfplotspointoutsideofaxis@getlimit@
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotspointoutsideofaxis@\pgfplots@loc@TMPa\relax{#2}{#3}%
}%
% A variant of \pgfplotsqpointoutsideofaxis which accepts transformed
% values for '#2' (i.e. any data transformations and logs are already
% applied).
\def\pgfplotsqpointoutsideofaxistransformed#1#2#3{%
\begingroup
\def\pgfplotspointoutsideofaxis@plug@trafo##1##2{\def\pgfmathresult{##2}}%
\let\pgfplotspointoutsideofaxis@plug@getlimit=\pgfplotspointoutsideofaxis@getlimit@
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotspointoutsideofaxis@\pgfplots@loc@TMPa\relax{#2}{#3}%
}%
% Computes the unit outer normal vector of the axis identified by a
% three-character-string '#1'.
%
% This is the same normal vector which is used inside of
% \pgfplotsqpointoutsideofaxis and its variants.
%
% The output of this command will be cached and re-used during the
% lifetime of an axis.
%
% The returned normal vector has length 1 (computed with
% \pgfpointnormalised).
%
% NOTE: some specialized axis types support non-linear axes (for
% example, polar axes). In that case, the outer normal vector *varies*
% along the `v' direction (of the three-character-string `#1').
% The value of `v' can be set using
% \pgfplotspointouternormalvectorofaxissetv{}{}
\def\pgfplotspointouternormalvectorofaxis#1{%
\pgfplotspointouternormalvectorofaxis@ifdependson@v{#1}{%
\expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname\relax
}{%
}%
\expandafter\ifx\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname\relax
\begingroup
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotspointouternormalvectorofaxis@\pgfplots@loc@TMPa\relax%
% \endgroup in \pgfplotspointouternormalvectorofaxis@.
\expandafter\xdef\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
\else
\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname
\fi
}%
% Fixes the "v" value for successive calls to
% \pgfplotspointouternormalvectorofaxis{#1}.
%
% #1 the three-character-string of an axis or the empty string.
% If #1 is empty, the actual configuration of oriented surfaces may be
% used to check which normal vector is intented.
%
% #2 the "v" value to store. It should be a transformed coordinate.
\def\pgfplotspointouternormalvectorofaxissetv#1#2{%
\edef\pgfplots@loc@TMPa{#1}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\expandafter\edef\csname pgfplotspointouternormalvectorofaxis@v@\pgfplotspointonorientedsurfaceA\endcsname{#2}%
\else
\expandafter\edef\csname pgfplotspointouternormalvectorofaxis@v@#1\endcsname{#2}%
\fi
}%
% Defines \pgfplotsretval to contain the 'v' value for an outer normal
% vector (if there is one known). If there is no such value,
% \pgfplotsretval will be empty.
% #1 a three-character-string
%
% see \pgfplotspointouternormalvectorofaxissetv
\def\pgfplotspointouternormalvectorofaxisgetv#1{%
\edef\pgfplots@loc@TMPa{#1}%
\expandafter\pgfplotspointouternormalvectorofaxisgetv@\pgfplots@loc@TMPa\relax\relax\relax\relax
}
\def\pgfplotspointouternormalvectorofaxisgetv@#1#2#3\relax{%
\pgfutil@ifundefined{pgfplotspointouternormalvectorofaxis@v@#1#2#3}{%
% no value found so far.
\if#1v%
\def\pgfplotsretval{x}%
\else
\if#2v%
\def\pgfplotsretval{y}%
\else
\def\pgfplotsretval{z}%
\fi
\fi
\pgfutil@ifundefined{pgfplotspointouternormalvectorofaxis@v@\pgfplotsretval}{%
\let\pgfplotsretval\pgfutil@empty
}{%
\edef\pgfplotsretval{\csname pgfplotspointouternormalvectorofaxis@v@\pgfplotsretval\endcsname}%
}%
}{%
\edef\pgfplotsretval{\csname pgfplotspointouternormalvectorofaxis@v@#1#2#3\endcsname}%
}%
}%
% invokes #2 if the outer normal for the axis #1 (identified by a
% three-character-string) depends on a coordinate on that axis and #3
% otherwise.
%
% Overwrite in subclasses if necessary.
\def\pgfplotspointouternormalvectorofaxis@ifdependson@v#1#2#3{#3}
\def\pgfplotspointouternormalvectorofaxis@#1#2#3\relax{%
\if v#1%
\def\pgfplots@loc@point@orthogonal@to@v##1##2{%
\pgfplotsqpointxyz{0}{##1}{##2}%
}%
\def\pgfplots@loc@char@for@baxis{#2}%
\def\pgfplots@loc@char@for@naxis{#3}%
\def\pgfplots@loc@vaxis{x}%
\def\pgfplots@loc@baxis{y}%
\def\pgfplots@loc@naxis{z}%
\else
\if v#2%
\def\pgfplots@loc@point@orthogonal@to@v##1##2{%
\pgfplotsqpointxyz{##1}{0}{##2}%
}%
\def\pgfplots@loc@char@for@baxis{#1}%
\def\pgfplots@loc@char@for@naxis{#3}%
\def\pgfplots@loc@vaxis{y}%
\def\pgfplots@loc@baxis{x}%
\def\pgfplots@loc@naxis{z}%
\else
\def\pgfplots@loc@point@orthogonal@to@v##1##2{%
\pgfplotsqpointxyz{##1}{##2}{0}%
}%
\def\pgfplots@loc@char@for@baxis{#1}%
\def\pgfplots@loc@char@for@naxis{#2}%
\def\pgfplots@loc@vaxis{z}%
\def\pgfplots@loc@baxis{x}%
\def\pgfplots@loc@naxis{y}%
\fi
\fi
%
\pgfplotspointouternormalvectorofaxis@get@otheraxis@sign{\pgfplots@loc@vaxis}{\pgfplots@loc@baxis}{\pgfplots@loc@char@for@baxis}%
\let\pgfplots@loc@baxissign=\pgfplotsretval
%
\pgfplotspointouternormalvectorofaxis@get@otheraxis@sign{\pgfplots@loc@vaxis}{\pgfplots@loc@naxis}{\pgfplots@loc@char@for@naxis}%
\let\pgfplots@loc@naxissign=\pgfplotsretval
%
%
% ok, compute vector scales:
\pgfplotsmath@ifzero{\csname pgfplots@\pgfplots@loc@baxis @veclength\endcsname}{%
\def\pgfplots@loc@baxissign{0}%
\def\pgfplots@loc@baxisscale{0}%
}{%
\edef\pgfplots@loc@baxisscale{\pgfplots@loc@baxissign\csname pgfplots@\pgfplots@loc@baxis @inverseveclength\endcsname}%
}%
\pgfplotsmath@ifzero{\csname pgfplots@\pgfplots@loc@naxis @veclength\endcsname}{%
\def\pgfplots@loc@naxissign{0}%
\def\pgfplots@loc@naxisscale{0}%
}{%
\edef\pgfplots@loc@naxisscale{\pgfplots@loc@naxissign\csname pgfplots@\pgfplots@loc@naxis @inverseveclength\endcsname}%
}%
%
% Ok, compute and normalize the vector:
\pgf@process{%
\pgfpointnormalised
{\pgfplots@loc@point@orthogonal@to@v{\pgfplots@loc@baxisscale}{\pgfplots@loc@naxisscale}}%
}%
\endgroup
}%
% #1: the axis for which we want the "outer normal".
% #2: the "other axis" for which we seek the sign.
% #3: the entry in the three-char-identifier which corresponds to
% "other axis".
\def\pgfplotspointouternormalvectorofaxis@get@otheraxis@sign#1#2#3{%
\ifcase#3\relax%
% case 0:
% this means : the '##1' direction of the surface
% orthogonal to the 'v' vector is on the lower axis
% limit. Since I need a vector pointing to the OUTSIDE of
% the axis, I need sign = -1
\def\pgfplotsretval{-}%
\or
% case 1:
% in this case, the OUTSIDE area requires a plus sign - the b
% axis already points to the inside.
\def\pgfplotsretval{+}%
\or
% case 2: we have the 'axis lines=centered' case.
%
% This case is complicated. The problem is that we do not know
% if we are at the top or bottom limit.
%
% BUT: we know what we would have done if this would be a
% normal boxed axis!
%
% The idea is to return the same normal vector as if this would be a boxed axis.
% To this end, we have to access the "ticklabel axis spec"
% which would have been used in this case.
%
% We computed it at startup. Might be a hack ... :-(
\edef\pgfplots@loc@TMPb{\csname pgfplots@#1ticklabelaxisspec@box\endcsname}%
%
% decode it: we have to replace '#3' by the value that it has
% in that boxed ticklabel axis spec!
\def\pgfplots@loc@TMPa##1##2##3{%
% search for the correct entry.
\if x#2\def\pgfplotsretval{##1}\fi
\if y#2\def\pgfplotsretval{##2}\fi
\if z#2\def\pgfplotsretval{##3}\fi
}%
\expandafter\pgfplots@loc@TMPa\pgfplots@loc@TMPb
%
\if 2\pgfplotsretval
\pgfplots@error{internal assertion failed.}%
\fi
%
% invoke it again!
\pgfplotspointouternormalvectorofaxis@get@otheraxis@sign{#1}{#2}{\pgfplotsretval}%
\fi
}
% very-low-level internal routine. Never invoke it directly.
% @PRECONDITION:
% an \begingroup has been opened.
% @POSTCONDITION
% an \endgroup has been closed and \pgf@x and \pgf@y are assigned.
%
% This grouping stuff has the intention to keep the "plug" things
% local.
%
% #1#2#3 are the three characters for the line, delimited by \relax.
% #4: the argument supplied as coordinate on that axis.
% #5: the shift along the outer unit normal.
\def\pgfplotspointoutsideofaxis@#1#2#3\relax#4#5{%
%
\def\pgfplotspointoutsideofaxis@lineshift{}%
%
\if v#1%
\pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPa=\pgfmathresult
\pgfplotspointonorientedsurfaceabsetupforsety{\pgfplots@loc@TMPa}{#2}%
\def\pgfplotspointoutsideofaxis@lineshift{x}%
%
\pgfplotspointonorientedsurfaceabsetupfor xzy%
\pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@A=\pgfmathresult
\ifpgfplots@threedim
\pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@B=\pgfmathresult
\else
\def\pgfplots@loc@B{0}%
\fi
\else
\if v#2%
\ifpgfplots@threedim
\pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPa=\pgfmathresult
\else
\def\pgfplots@loc@TMPa{0}%
\fi
\pgfplotspointonorientedsurfaceabsetupforsetz{\pgfplots@loc@TMPa}{#3}%
%
\pgfplotspointonorientedsurfaceabsetupfor yxz%
\pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@A=\pgfmathresult
\pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@B=\pgfmathresult
\def\pgfplotspointoutsideofaxis@lineshift{y}%
\else
\pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPa=\pgfmathresult
\pgfplotspointonorientedsurfaceabsetupforsetx{\pgfplots@loc@TMPa}{#1}%
%
\pgfplotspointonorientedsurfaceabsetupfor zyx%
\ifpgfplots@threedim
\pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@A=\pgfmathresult
\else
\def\pgfplots@loc@A{0}%
\fi
\pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@B=\pgfmathresult
\def\pgfplotspointoutsideofaxis@lineshift{z}%
\fi
\fi
%
% read dimen argument #5:
\afterassignment\pgfplots@gobble@until@relax
\pgf@xa=#5pt\relax
%
\pgfkeysgetvalue{/pgfplots/axis \pgfplotspointoutsideofaxis@lineshift\space line shift}\pgfmathresult
\ifx\pgfmathresult\pgfutil@empty
\else
\advance\pgf@xa by \pgfmathresult pt %
\fi
%
\edef\pgfplots@loc@distalong@normal{\pgf@sys@tonumber\pgf@xa}%
%
%\message{pgfplotspointoutsideofaxis{#1#2#3}{#4}{#5}: A = \pgfplots@loc@A, B = \pgfplots@loc@B.^^J}%
%
\pgf@process{%
\pgfpointadd
{\pgfplotspointonorientedsurfaceab{\pgfplots@loc@A}{\pgfplots@loc@B}}
{%
\pgfplotspointouternormalvectorofaxissetv{#1#2#3}{\pgfplots@loc@A}%
\pgfqpointscale
{\pgfplots@loc@distalong@normal}%
{\pgfplotspointouternormalvectorofaxis{#1#2#3}}%
}%
}%
\endgroup
}%
%--------------------------------------------------
% \def\pgfplotspointoutsideofaxis@#1#2#3\relax#4#5{%
% \if v#1%
% \def\pgfplots@loc@point@orthogonal@to@v{%
% \pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult
% \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPb=\pgfmathresult
% \ifpgfplots@threedim
% \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult
% \else
% \def\pgfplots@loc@TMPc{0}%
% \fi
% \pgfplotsqpointxyz{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}%
% }%
% \else
% \if v#2%
% \def\pgfplots@loc@point@orthogonal@to@v{%
% \pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult
% \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult
% \ifpgfplots@threedim
% \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult
% \else
% \def\pgfplots@loc@TMPc{0}%
% \fi
% \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPc}%
% }%
% \else
% \def\pgfplots@loc@point@orthogonal@to@v{%
% \ifpgfplots@threedim
% \pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult
% \else
% \def\pgfplots@loc@TMPa{0}%
% \fi
% \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult
% \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPc=\pgfmathresult
% \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}{\pgfplots@loc@TMPa}%
% }%
% \fi
% \fi
% %
% % read dimen argument #5:
% \afterassignment\pgfplots@gobble@until@relax
% \pgf@xa=#5pt\relax
% \edef\pgfplots@loc@distalong@normal{\pgf@sys@tonumber\pgf@xa}%
% %
% %
% \pgf@process{%
% \pgfpointadd
% {\pgfplots@loc@point@orthogonal@to@v}
% {%
% \pgfqpointscale
% {\pgfplots@loc@distalong@normal}%
% {\pgfplotspointouternormalvectorofaxis{#1#2#3}}%
% }%
% }%
% \endgroup
% }%
%--------------------------------------------------
% Helper method for \pgfplotsqpointoutsideofaxis and its variants.
% #1: an axis (x,y or z)
% #2: o(\pgfplots@loc@TMPa - \pgfplots@loc@TMPb) ne of '0', '1' or '2' where
% 0 == add lower #1 axis limit,
% 1 == add upper #1 axis limit,
% 2 == add nothing.
% #3: the value to add.
\def\pgfplotspointoutsideofaxis@getlimit@#1#2{%
\if#20%
\expandafter\let\expandafter\pgfmathresult\csname pgfplots@#1min\endcsname
\else
\if#21%
\expandafter\let\expandafter\pgfmathresult\csname pgfplots@#1max\endcsname
\else
\expandafter\let\expandafter\pgfmathresult\csname pgfplots@logical@ZERO@#1\endcsname
\fi
\fi
}%
\newif\ifpgfplots@sloped
\pgfplots@slopedtrue % its only purpose is to *DEACTIVATE* the sloped transformation after it has been activated.
\newif\ifpgfplots@sloped@resets@nontranslations
\newif\ifpgfplots@sloped@allowupsidedown
\pgfkeys{
/pgfplots/sloped/true/.code={\pgfplots@slopedtrue},
/pgfplots/sloped/false/.code={\pgfplots@slopedfalse},
/pgfplots/sloped/allow upside down/.is if=pgfplots@sloped@allowupsidedown,
/pgfplots/sloped/allow upside down/.default=true,
/pgfplots/sloped/execute for upside down/.initial=,
/pgfplots/sloped/reset nontranslations/.is if=pgfplots@sloped@resets@nontranslations,
/pgfplots/sloped/reset nontranslations/.default=true,
%
% only used by polar axes at the time of this writing:
/pgfplots/sloped/at position/.initial=,
}
% Installs a rotation transformation matrix such that labels or
% whatever are aligned precisely in direction of one of the two/three
% coordinate directions.
%
% \pgfplotstransformtoaxisdirection[]{}
%
% : the coordinate direction (one of x,y or z)
%
% The code is pretty much the same as \pgftransformlineattime, except
% that the computation is considerably simpler as axis directions are
% a well known quantity.
%
% This command uses \ifpgfplots@sloped@allowupsidedown (=false) and
% \ifpgfplots@sloped@resets@nontranslations (= true). The default
% setting is reinitialised before options are processed
\def\pgfplotstransformtoaxisdirection{%
\pgfutil@ifnextchar[{\pgfplotstransformtoaxisdirection@}{\pgfplotstransformtoaxisdirection@[]}%
}%
\def\pgfplotstransformtoaxisdirection@[#1]#2{%
\pgfplots@sloped@allowupsidedownfalse
\pgfplots@sloped@resets@nontranslationstrue
%
\def\pgfplots@loc@TMPa{#1}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
\pgfqkeys{/pgfplots/sloped}{#1}%
\fi
\ifpgfplots@sloped
%
\ifpgfplots@sloped@resets@nontranslations
\pgftransformresetnontranslations
\fi
%
% compute unit length vector pointing into the direction of
% '#1#2#3':
\pgfqpointscale{\csname pgfplotsunit#2invlength\endcsname}{\csname pgfplotspointunit#2\endcsname}%
%
\ifdim\pgf@x<0pt%
% oh. upside down.
\pgfkeysvalueof{/pgfplots/sloped/execute for upside down}%
\ifpgfplots@sloped@allowupsidedown
\else
% do not allow upside down labels:
\global\pgf@x=-\pgf@x%
\global\pgf@y=-\pgf@y%
\fi
\fi%
%
\pgf@ya=-\pgf@y%
% set up rotation matrix
% [ cos(alpha) sin(alpha);
% -sin(alpha) cos(alpha) ]
% where cos(alpha) = n_x and sin(alpha) = n_y:
\pgftransformcm%
{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}%
{\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}%
\fi
}
% Adds a further, temporary anchor to every node which will be
% processed. The anchor will be named '#3'. It is placed such that
% 1. the node's center is on a line in direction of the inwards normal
% vector of the axis line denoted by '#2' and the 'at' position of the node,
% 2. the node does not intrude the axis.
%
% #1: either x,y or z the direction which varies
% #2: a three-char-string uniquely identifying the axis line.
% The parameter '#1' is redundand: it is the same as the 'v'
% character in '#2'.
% #3: the newly defined achor name.
%
% @see \pgfplotsdeclareborderanchorforticklabelaxis
\def\pgfplotsdeclareborderanchorforaxis#1#2#3{%
%
%
\pgfdeclaregenericanchor{#3}{\pgfplots@borderanchor@for@axis{#1}{#2}{##1}}%
\pgfdeclaregenericanchor{#3 opposite}{\pgfplots@borderanchor@for@axis@{#1}{#2}{##1}{+1}}%
%
% This variant will ALWAYS be placed on the boundary of the node.
% It is deprecated, I am keeping it for some time....
\pgfdeclaregenericanchor{#3*}{%
\csname pgf@anchor@##1@border\endcsname{%
\pgf@process{%
%
% I want to rotate the node FIRST, then
% I'd like to get the boundary anchor!
%
% My idea: apply the INVERSE transformation
% matrix, then compute the boundary anchor.
%
% As soon as pgf draws the node, the
% transformation matrix will be applied and
% everything is fine.
\pgfutil@ifundefined{pgfreferencednodename}{%
% use given transformation matrix.
}{%
\ifx\pgfreferencednodename\pgfutil@empty
% just use the given transformation matrix - we are
% typesetting an unlabeled node.
\else
\pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}%
\fi
}%
\pgftransforminvert
%
% This here is the anchor as such.
\pgfqpointscale{-1}{\pgfplotspointouternormalvectorofaxis{#2}}%
%
\pgf@pos@transform\pgf@x\pgf@y
}%
}%
}%
}%
% this does the work for \pgfplotsdeclareborderanchorforaxis.
%
% It depends on \pgfplotspointunit[xyz] and
% \pgfplotspointouternormalvectorofaxis
%
% #1: either x,y or z the direction which varies
% #2: a three-char-string uniquely identifying the axis line.
% The parameter '#1' is redundand: it is the same as the 'v'
% character in '#2'.
% #3: the shape, provided as argument by the pgf routine invoking the
% anchor.
\def\pgfplots@borderanchor@for@axis#1#2#3{%
\pgfplots@borderanchor@for@axis@{#1}{#2}{#3}{-1}%
}
% same as \pgfplots@borderanchor@for@axis{#1}{#2}{3} except that #4 is
% the SIGN for the outer normal.
%
% #4: the sign for the outer normal. #4=-1 means "use inner normal"
% and +1 means "use outer normal"
\def\pgfplots@borderanchor@for@axis@#1#2#3#4{%
\begingroup
\pgfutil@ifundefined{pgfreferencednodename}{%
% use given transformation matrix.
}{%
\ifx\pgfreferencednodename\pgfutil@empty
% just use the given transformation matrix - we are
% typesetting an unlabeled node.
\else
\pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}%
\fi
}%
% I only need to apply the trafo matrix to direction vectors. Eliminate
% shifts.
\pgf@pt@x=0pt %
\pgf@pt@y=0pt %
%
% I'll apply the inverse transformation matrix to direction
% vectors. To ensure the relative position of these vectors
% and the anchors of the node, I have to invert the matrix:
\pgftransforminvert
%
\pgfplotspointouternormalvectorofaxisgetv{#2}%
\ifx\pgfplotsretval\pgfutil@empty
\pgfkeysgetvalue{/pgfplots/near ticklabel at}\pgfplotsretval
\ifx\pgfplotsretval\pgfutil@empty
\else
% ah - we have one!
\csname pgfplotstransformcoordinate#1\endcsname{\pgfplotsretval}%
\pgfplotspointouternormalvectorofaxissetv{#2}{\pgfmathresult}%
\fi
\fi
%
% This here is the normal direction (points to the axis)
\pgfqpointscale{#4}{\pgfplotspointouternormalvectorofaxis{#2}}%
%
% we apply the inverse CM onto it here:
\pgf@pos@transform\pgf@x\pgf@y
\edef\pgfplots@tmp@normaldir{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
%
\pgfplots@borderanchor@snap@to@nearest@anchor{}% takes \pgf@x and \pgf@y
\let\pgfplots@anchor=\pgfplotsretval
%
% Now, I'd like the 'center' of the node on one line with the
% 'at={}' coordinate at which it shall be placed!
% This can be done as follows:
%
% Compute two lines:
% 1. a line parallel to the #1 axis which goes
% through our recently identified anchor,
% { x = x_a + r_1 * (#1 axis direction)
% 2. a line from center in direction of the normal,
% { x = x_c + r_2 n, r in R }
%
% Calculate the intersection point and return it! This
% involves a lot of arithmetics :-(
%
% UPDATE: I realized that using the 'center' anchor might be too
% restrictive. See the 'near ticklabel align' key.
%
% Note that this is actually too much work for the 2d case - I
% guess it would be more efficient without it. But for 3d, it
% really rocks.
%
% compute (unit#1 - normal):
\pgfplots@tmp@normaldir
\pgf@xb=\pgf@x
\pgf@yb=\pgf@y
%
% and the axis direction (in fact, I use -axis dir. But that
% doesn't matter for the intersection of two lines).
% Scale unit vector to length 1 to improve conditioning:
\pgfqpointscale
{\csname pgfplotsunit#1invlength\endcsname}
{\csname pgfplotspointunit#1\endcsname}%
% FIXME : shouldn't the values be copied AFTER the CM!?
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@pos@transform\pgf@xa\pgf@ya
%
\ifcase\pgfplots@borderanchor@align\relax
% near ticklabel align=inside:
% make sure that we are close to the beginning of the axis
% direction vector.
\pgfplots@borderanchor@snap@to@nearest@anchor{%
\if\pgfkeysvalueof{/pgfplots/#1 dir/value}n%
% simply take \pgf@x and \pgf@y as-is.
\else
\global\pgf@x=-\pgf@x
\global\pgf@y=-\pgf@y
\fi
}%
\or
% near ticklabel align=center:
\def\pgfplotsretval{center}% Ah. simple.
\or
% near ticklabel align=outside:
% make sure that we are far away from the beginning of the
% axis direction vector.
\pgfplots@borderanchor@snap@to@nearest@anchor{%
\if\pgfkeysvalueof{/pgfplots/#1 dir/value}n%
\global\pgf@x=-\pgf@x
\global\pgf@y=-\pgf@y
\else
% simply take \pgf@x and \pgf@y as-is.
\fi
}%
\fi
\let\pgfplots@anchor@inner=\pgfplotsretval
%
%
% verify that |n^T d |
\pgf@xc=\pgf@sys@tonumber\pgf@xa\pgf@xb
\advance\pgf@xc by\pgf@sys@tonumber\pgf@ya\pgf@yb
\ifdim\pgf@xc<0pt \pgf@xc=-\pgf@xc \fi
\ifdim\pgf@xc<0.8pt
% ok. 'n' and 'd' are not parallel.
%
\edef\pgfplots@LEQ{%
% solve linear system
% a11 a12
% a21 a22
{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xa}%
{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@ya}%
}%
%
% This here controls the anchor! Changing it might be more
% useful than I thought in the first place...
\pgf@sh@reanchor{#3}{\pgfplots@anchor@inner}%
\edef\pgfplots@loc@center{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}%
%
% apply inverse matrix to right-hand-side (and compute RHS):
\pgfpointdiff% {}{} -> computes -
{\pgfplots@loc@center}%
{\pgf@sh@reanchor{#3}{\pgfplots@anchor}}%
\edef\pgfplots@RHS{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}%
%
\pgfutilsolvetwotwoleq{\pgfplots@LEQ}{\pgfplots@RHS}%
\def\pgfplots@extract##1##2{%
\def\pgfplots@r{##1}%
}%
\expandafter\pgfplots@extract\pgfmathresult
% GOT IT!
%
% compute x_c + r*n:
\pgfpointadd
{\pgfplots@loc@center}%
{\pgfqpointscale{\pgfplots@r}{\pgfplots@tmp@normaldir}}%
\else
\pgfplotswarning{ticklabel anchor undetermined}{#1}{\the\pgf@xb,\the\pgf@yb}{\the\pgf@xa,\the\pgf@ya}{\the\pgf@xc}\pgfeov
% Something went awry: normal and unit#1 are almost parallel!?
% just use the determined anchor.
\def\pgfplots@r{0}%
\pgf@sh@reanchor{#3}{\pgfplots@anchor}%
\fi
%\message{==========>>>>>>>>>> I got finally (\the\pgf@x,\the\pgf@y). <<<<<<<<<===================}%
\pgf@process{}% <- transport outside of group
\endgroup
}%
% #1: a direction vector.
%
% assigns the resulting anchor to \pgfplotsretval
\def\pgfplots@borderanchor@snap@to@nearest@anchor#1{%
\begingroup
#1%
% Now:
% auto-determine the canonical (north, north east etc) anchor
% at which the node touches the axis (remember: the axis is to
% be found in direction of the normal vector).
%
% This is kind of a snap-to-nearest-existing-anchor feature. But
% it tends to move the node too far away. It is used as starting
% point; we will refine it in the next step.
%
% This is a heuristicial procedure.
%
% Note that it does not hurt if there are "multiple best matches"
% (for example because they lie on the same line).
% The code below will move the final anchor point.
%
\def\pgfplots@thresh{0.17pt }% 80 degrees
%\def\pgfplots@thresh{0.3pt }%
%\def\pgfplots@thresh{0.707pt }% 45 degrees
\ifdim\pgf@y>0pt
\ifdim\pgf@y>\pgfplots@thresh
% only north anchor
\def\pgfplots@ycomp{north}%
\else
\def\pgfplots@ycomp{}%
\fi
\else
\ifdim\pgf@y<-\pgfplots@thresh
\def\pgfplots@ycomp{south}%
% south anchor
\else
\def\pgfplots@ycomp{}%
\fi
\fi
\ifdim\pgf@x>0pt
\ifdim\pgf@x>\pgfplots@thresh
\def\pgfplots@xcomp{east}%
\else
\def\pgfplots@xcomp{}%
\fi
\else
\ifdim\pgf@x<-\pgfplots@thresh
\def\pgfplots@xcomp{west}%
\else
\def\pgfplots@xcomp{}%
\fi
\fi
\edef\pgfplotsretval{%
\pgfplots@ycomp
\ifx\pgfplots@ycomp\pgfutil@empty
\else
\ifx\pgfplots@xcomp\pgfutil@empty
\else
\space
\fi
\fi
\pgfplots@xcomp
}%
\pgfmath@smuggleone\pgfplotsretval
\endgroup
}
\def\pgfplotspointviewdir{%
%\pgfplotsmathvectordatascaletrafoinverse{\pgfplots@view@dir@threedim}{default}%
\let\pgfplotsretval=\pgfplots@view@dir@threedim
\pgfplotspointfromcsvvector{\pgfplotsretval}{default}%
}%
\def\message@pgfplots@units{%
\begingroup
\pgfmathparse{veclen(\pgf@zx,\pgf@zy)}\let\Z=\pgfmathresult
\ifdim\Z pt=0pt
\def\Z{1}%
\fi
\pgfmathparse{veclen(\pgf@xx,\pgf@xy)/\Z}\let\X=\pgfmathresult
\pgfmathparse{veclen(\pgf@yx,\pgf@yy)/\Z}\let\Y=\pgfmathresult
\expandafter\ifx\csname pgfplots@view@dir@threedim\endcsname\relax
\def\normal{view = (---),^^J}%
\else
\pgfplotsmathvectortostring{\pgfplots@view@dir@threedim}{default}%
\edef\normal{view = (\pgfplotsretval),^^J}%
\fi
\message{^^J
x = (\the\pgf@xx,\the\pgf@xy),^^J
y =(\the\pgf@yx,\the\pgf@yy),^^J
z = (\the\pgf@zx,\the\pgf@zy),^^J
\normal
unit vector ratio=[\X\space\Y\space 1],^^J}%
\endgroup
}%
% ==================================================================================
%
% COORDINATE MATH.
%
% ==================================================================================
% Declares a new "subclass" to perform coordinate math.
%
% Coordinate math usually needs a more powerful number format than the pgf
% basic layer, or at least a powerful mapping into the pgf basic
% layer. Both cases are realized by the coordinate math class.
%
% Different coordinates can use different instances, and it is also
% possible to use yet a further instance for point meta (or whatever).
%
% Coordinate math is used to compute axis limits and to map the range
% into the pgf number format.
%
% It is *not* necessarily used for \pgfmathparse, since switching
% the number format of \pgfmathparse is quite involved (at the time of
% this writing). Instead, it is used for *single* operations (like
% max, min, multiply, add).
%
% #1: the name of the coord math class
% #2: methods to override the default.
%
% The available methods are documented and shown below in the
% \pgfqkeys listing.
%
% @see the predefined examples, also shown below.
\def\pgfplotsdeclarecoordmath#1#2{%
\edef\pgfplotsdeclarecoordmath@{@#1@}%
\pgfqkeys{/pgfplots/@declare coord math}{%
initialise=,
parse=\edef\pgfmathresult{##1}\expandafter\pgfmathparse\expandafter{\pgfmathresult},
parse int={%
\begingroup
\pgfplotscoordmath{\pgfplotscoordmathid}{parse}{##1}%
\pgfplotscoordmath{\pgfplotscoordmathid}{tofixed}{\pgfmathresult}%
\afterassignment\pgfplots@gobble@until@relax
\c@pgf@countd=\pgfmathresult\relax
\edef\pgfmathresult{\the\c@pgf@countd}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
},
parsenumber=\pgfmathfloatparsenumber{##1}\pgfmathfloattofixed{##1},%
zero= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{0},
one= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{1},
-one= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{-1},
log e= \pgfmathlog@{##1},%
log to display log=\pgfmath@basic@multiply@{##1}{2.3025851},% * log(10)
log from display log=\pgfmath@basic@multiply@{##1}{0.434294},% / log(10)
log unsigned int={%
\edef\pgfmathresult{%
\ifcase##1
\or0
\or0.693147
\or1.098612
\or1.386294
\or1.60943791
\or1.7917594
\or1.94591014
\or2.07944154
\or2.197224
\fi
}%
},
set log basis=\edef\pgfmathresult{{#1}{##1}}\expandafter\pgfplotscoordmath@log@set@basis\pgfmathresult,
exp e={%
% make sure the exponential can be represented, i.e. use
% 'float' in the default repr:
\pgfmathfloatparsenumber{##1}%
\pgfmathfloatexp@\pgfmathresult%
\pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{\pgfmathresult}%
},
tofixed= \edef\pgfmathresult{##1},%
tostring= \edef\pgfmathresult{##1},%
max= \pgfplotsmathmax{##1}{##2},%
min= \pgfplotsmathmin{##1}{##2},%
min limit= \def\pgfmathresult{-16300},%
max limit= \def\pgfmathresult{16300},%
if less than= {\pgfplotsmathlessthan{##1}{##2}\ifpgfmathfloatcomparison ##3\else ##4\fi},
if is= {%
\if##20%
\ifdim##1pt=0pt ##3\else ##4\fi
\else
\if##2+\ifdim##1pt>0pt ##3\else ##4\fi
\else
\if##2-\ifdim##1pt<0pt ##3\else ##4\fi
\else
\def\pgfplots@loc@TMPd{##1}\ifx\pgfplots@loc@TMPd\pgfutil@empty ##3\else ##4\fi
\fi
\fi
\fi
},%
if is bounded=\edef\pgfplotsretval{##1}\ifx\pgfplotsretval\pgfutil@empty ##3\else ##2\fi,
suffix= #1,%
datascaletrafo set params=,
datascaletrafo get params= \def\pgfmathresult{{0}{0}}\def\pgfplotsretval{0}\def\pgfplotsretvalb{0},
datascaletrafo= \edef\pgfmathresult{##1},
datascaletrafo inverse= \edef\pgfmathresult{##1},
datascaletrafo noshift inverse= \edef\pgfmathresult{##1},
datascaletrafo inverse to fixed= \edef\pgfmathresult{##1},
datascaletrafo noshift inverse to fixed= \edef\pgfmathresult{##1},
datascaletrafo noshift= \edef\pgfmathresult{##1},
datascaletrafo undo shift= \edef\pgfmathresult{##1},
datascaletrafo redo shift= \edef\pgfmathresult{##1},
#2%
}%
\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ op\endcsname##1##2{%
\noexpand\edef\noexpand\pgfplotscoordmath@{##2}%
\noexpand\expandafter\noexpand\expandafter\noexpand\csname pgfmath\csname pgfpmth@#1@suffix\endcsname ##1@\noexpand\endcsname\noexpand\pgfplotscoordmath@
}%
%
%
% these log function depend on the first argument of
% \pgfplotscoordmath{}, which is available as
% \pgfplotscoordmathid.
\pgfplotsutilforeachcommasep{%
exp,%
log,%
log to display log,%
log from display log,%
log to log 10,%
log unsigned int}\as\pgfplots@loc@TMPa
{%
\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@\pgfplots@loc@TMPa\endcsname{%
% invoke \pgfpmth@#1@@@
% for example
% \pgfpmth@pgfbasic@@y@log
\noexpand\csname pgfpmth\pgfplotsdeclarecoordmath@ @\noexpand\pgfplotscoordmathid @\pgfplots@loc@TMPa\noexpand\endcsname
}%
}%
%
\pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log}{%
\pgfutil@namelet
{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log}
{pgfpmth\pgfplotsdeclarecoordmath@ log e}%
}{}%
\pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp}{%
\pgfutil@namelet
{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp}
{pgfpmth\pgfplotsdeclarecoordmath@ exp e}%
}{}%
\pgfplotscoordmath@def@log@to@log@ten{#1}{}{tmpl}% empty arg
%
}%
\pgfqkeys{/pgfplots/@declare coord math}{%
initialise/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ initialise\endcsname{#1%
\pgfplotscoordmath@initialise@logs
}},%
% takes a number literal as input and defines \pgfmathresult to be
% the parsed result.
parsenumber/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parsenumber\endcsname##1{#1}},%
%
zero/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ zero\endcsname{#1}},%
one/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ one\endcsname{#1}},%
-one/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ -one\endcsname{#1}},%
%
% Calls pgfmathparse. Note that this might need to switch to the
% required math library (which is not necessarily cheap)
parse/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parse\endcsname##1{#1}},%
parse int/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parse int\endcsname##1{#1}},%
%
% takes a parsed number and returns a fixed point number:
tofixed/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tofixed\endcsname##1{#1}},%
%
% chooses a human readable string (which can be processed by parsenumber):
tostring/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tostring\endcsname##1{#1}},%
%
% defines a max routine which returns the max of *exactly* two numbers:
max/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max\endcsname##1##2{#1}},%
%
% counterpart for max:
min/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min\endcsname##1##2{#1}},%
%
% defines \pgfmathresult to be the largest supported number.
max limit/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max limit\endcsname{#1}},%
%
% defines \pgfmathresult to be the smallest supported number.
min limit/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min limit\endcsname{#1}},%
%
% computes ##1 < ##2 and invokes ##3 in the true case and ##4 in
% the false case.
if less than/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if less than\endcsname##1##2##3##4{#1}},%
% checks if ##1 is 0, positive, negative or unbounded
% ##1: the number to check
% ##2: either 0 or + or - or u (u = unbounded)
% ##3: true code
% ##4: false code
if is/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is\endcsname##1##2##3##4{#1}},%
%
% Checks if the argument ##1 is bounded and invokes ##2 in that
% case. IF the argument is unbounded, it invokes #3.
if is bounded/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is bounded\endcsname##1##2##3{#1}},%
%
% applies the natural logarithm. If the log is not defined, the
% argument is "unbounded", see 'if is bounded'
%
% 'log' is special in that it accepts a number literal which may
% be OUTSIDE of the accepted number format. The result, however, is
% then in the accepted number format.
log e/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ log e\endcsname##1{#1}},%
%
% Similar, but the log basis can be set with 'set log basis'.
% This allows \pgfplotscoordmath{x}{log}{} to use a different log
% basis thatn \pgfplotscoordmath{y}{log}{} (with special handling)
log/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log\endcsname##1{#1}},%
% applies a *scale* from the actual log basis to the actual
% *display* log basis. The display log basis is usually 10, unless
% the log basis has been changed.
log to display log/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to display log\endcsname##1{#1}},%
% applies a *scale* from the displau log basis to the actual
% log basis (the inverse of `log to display log').
log from display log/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log from display log\endcsname##1{#1}},%
log to log 10/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to log 10\endcsname##1{#1}},%
% returns log(i) where i \in {1,2,3,...,basis-1}
% currently, it is only invoked for log basis 10
log unsigned int/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log unsigned int\endcsname##1{#1}},%
% sets (changes) the actual log basis.
set log basis/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ set log basis\endcsname##1{#1}},%
%
% The inverse to 'log e '.
exp e/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ exp e\endcsname##1{#1}},%
%
% The inverse to 'log'. It also uses the correct log basis.
exp/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp\endcsname##1{#1}},%
%
% A macro taking two parameters:
% #1: the EXPONENT (as integer)
% #2: the SHIFT (as fixed point number)
%
% After any change, \pgfplotscoordmathnotifydatascalesetfor{} will be
% invoked where is the argument to
% \pgfplotscoordmath{}...
datascaletrafo set params/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo set params\endcsname##1##2{%
#1\relax\pgfplotscoordmathnotifydatascalesetfor{\pgfplotscoordmathid}%
}},%
datascaletrafo set shift/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo set shift\endcsname##1{%
#1\relax\pgfplotscoordmathnotifydatascalesetfor{\pgfplotscoordmathid}%
}},%
%
% Defines \pgfmathresult to contain the two parameters in the form
% {#1}{#2} required for 'datascaletrafo set params':
% #1: the EXPONENT (as integer)
% #2: the SHIFT (as fixed point number)
% AND \pgfplotsretval as the EXPONENT and \pgfplotsretvalb as the SHIFT
datascaletrafo get params/.code={%
\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo get params\endcsname{#1}%
},%
datascaletrafo/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo\endcsname##1{#1}},%
datascaletrafo inverse/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo inverse\endcsname##1{#1}},%
datascaletrafo noshift inverse/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift inverse\endcsname##1{#1}},%
datascaletrafo inverse to fixed/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo inverse to fixed\endcsname##1{#1}},%
datascaletrafo noshift inverse to fixed/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift inverse to fixed\endcsname##1{#1}},%
datascaletrafo noshift/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift\endcsname##1{#1}},%
datascaletrafo noshift/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift\endcsname##1{#1}},%
datascaletrafo undo shift/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo undo shift\endcsname##1{#1}},%
datascaletrafo redo shift/.code=
{\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo redo shift\endcsname##1{#1}},%
%
% defines a suffix such that
% \csname pgfmath@\endcsname
% exists. Example: =float --> \pgfmathfloatmultiply@ for =multiply
suffix/.code=
{\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ suffix\endcsname{#1}},%
}%
\def\pgfplotscoordmath@initialise@logs{%
\edef\pgfplotsdeclarecoordmath@{@\pgfplotscoordmathclassfor{\pgfplotscoordmathid}@}%
\pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log}{%
\pgfplotsutilforeachcommasep{%
exp,%
log,%
log to display log,%
log from display log,%
log to log 10,%
log unsigned int}\as\pgfplots@loc@TMPa
{%
\pgfutil@namelet
{pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @\pgfplots@loc@TMPa}
{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@\pgfplots@loc@TMPa}%
}%
}{}%
}%
% shared implementation for 'set log basis' It works for every
% subclass.
\def\pgfplotscoordmath@log@set@basis#1#2{%
\edef\pgfplotsdeclarecoordmath@{@#1@}%
%
\pgfplotscoordmath{\pgfplotscoordmathid}{log e}{#2}%
\let\pgfplots@loc@TMPa=\pgfmathresult% TMPa = log_e(#2)
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{reciprocal}{{\pgfmathresult}}%
\let\pgfplots@loc@TMPb=\pgfmathresult% TMPb = 1/log_e(#2)
%
% log_a(x) = log_e(x) / log_e(a)
\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log\endcsname##1{%
\noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{log e}{##1}%
\noexpand\ifx\noexpand\pgfmathresult\noexpand\pgfutil@empty
\noexpand\else
\noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{%
{\noexpand\pgfmathresult}%
{\pgfplots@loc@TMPb}%
}%
\noexpand\fi
}%
%
% a^x = exp(log_e(a^x)) = exp(x*log_e(a))
\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @exp\endcsname##1{%
\noexpand\edef\noexpand\pgfmathresult{##1}%
\noexpand\ifx\noexpand\pgfmathresult\noexpand\pgfutil@empty
\noexpand\else
\noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{%
{\noexpand\pgfmathresult}%
{\pgfplots@loc@TMPa}%
}%
\noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{exp e}{\noexpand\pgfmathresult}%
\noexpand\fi
}%
\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log to display log\endcsname##1{\edef\pgfmathresult{##1}}%
\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log from display log\endcsname##1{\edef\pgfmathresult{##1}}%
%
% compute 'log unsigned int' for the new basis.
%
% Idea: re-scale the old implementation (of basis e for i = 1,...,9)
% and re-compute i>=10 :
\begingroup
\expandafter\let\expandafter\logi\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log unsigned int\endcsname
\let\logscale=\pgfplots@loc@TMPb
%
\logi{1}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@1\endcsname=\pgfmathresult
%
\logi{2}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@2\endcsname=\pgfmathresult
%
\logi{3}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@3\endcsname=\pgfmathresult
%
\logi{4}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@4\endcsname=\pgfmathresult
%
\logi{5}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@5\endcsname=\pgfmathresult
%
\logi{6}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@6\endcsname=\pgfmathresult
%
\logi{7}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@7\endcsname=\pgfmathresult
%
\logi{8}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@8\endcsname=\pgfmathresult
%
\logi{9}%
\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}%
\expandafter\let\csname logi@@9\endcsname=\pgfmathresult
%
\xdef\pgfplots@glob@TMPa##1{%
\noexpand\ifcase##1
\noexpand\def\noexpand\pgfmathresult{}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@1\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@2\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@3\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@4\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@5\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@6\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@7\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@8\endcsname}%
\noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@9\endcsname}%
\noexpand\else
\noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{log}{##1}%
\noexpand\fi
}%
\endgroup
\expandafter\let\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log unsigned int\endcsname=\pgfplots@glob@TMPa
\pgfplotscoordmath@def@log@to@log@ten{#1}\pgfplots@loc@TMPa{\pgfplotscoordmathid}%
%
\pgfutil@namelet
{pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log to log 10}
{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to log 10}%
}%
% #1: the coord math class
% #2: either empty (basis e) or 1/ln(basis)
% #3: either 'tmpl' or '\pgfplotscoordmathid. It defines the target
% macro name (see the source code)
\def\pgfplotscoordmath@def@log@to@log@ten#1#2#3{%
\csname pgfpmth@#1@parsenumber\endcsname{0.434294}%
\edef\pgfplots@loc@TMPa{#2}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
% log basis e ---> log basis 10
% log_10 x = log x / log(10)
\else
% log basis a ---> log basis 10
%
% log_a x = log x / log a
% log_10 x = log_a x * log a / log(10) = log x / log(10) [OK]
\csname pgfpmth@#1@op\endcsname{multiply}{{#2}{\pgfmathresult}}%
\fi
\expandafter\edef\csname pgfpmth@#1@#3@log to log 10\endcsname##1{%
\noexpand\pgfplotscoordmath{\noexpand\pgfplotscoordmathid}{op}{multiply}{{##1}{\pgfmathresult}}%
}%
}%
% Assumes that #2 is a macro, parses it as number with "coord math choice" #1, and overwrites it with the result.
\def\pgfplotscoordmathparsemacro#1#2{%
\pgfplotscoordmath{#1}{parsenumber}{#2}\let#2=\pgfmathresult
}%
\pgfplotsdeclarecoordmath{pgfbasic}{%
parsenumber={%
\pgfmathfloatparsenumber{#1}%
\expandafter\pgfmathfloatgetflagstomacro\expandafter{\pgfmathresult}\pgfplotsretval
\ifnum\pgfplotsretval>2
\let\pgfmathresult=\pgfutil@empty
\else
\pgfmathfloattofixed\pgfmathresult
\fi
},
suffix=@basic@,
zero=\def\pgfmathresult{0},
one=\def\pgfmathresult{1},
-one=\def\pgfmathresult{-1},
}
\pgfplotsdeclarecoordmath{float}{%
initialise=
\pgfutil@ifundefined{pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid}{%
\expandafter\edef\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname{0}%
\expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{0}%
}{},
parsenumber=\pgfmathfloatparsenumber{#1},
parse={%
\begingroup
\pgfkeys{/pgf/fpu,%
/pgf/fpu/output format=float,%
}%
\edef\pgfmathresult{#1}%
\expandafter\pgfmathparse\expandafter{\pgfmathresult}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
},
zero=\pgfmathfloatcreate{0}{0.0}{0},%
one=\pgfmathfloatcreate{1}{1.0}{0},%
-one=\pgfmathfloatcreate{2}{1.0}{0},%
tofixed=\pgfmathfloattofixed{#1},
tostring=\pgfmathfloattosci{#1},
max=\pgfplotsmathfloatmax{#1}{#2},%
min=\pgfplotsmathfloatmin{#1}{#2},%
max limit=\pgfmathfloatcreate{1}{1.0}{2147483645},%
min limit=\pgfmathfloatcreate{2}{1.0}{2147483645},%
log e=\pgfmathfloatparsenumber{#1}\pgfmathfloatln@{\pgfmathresult},%
if less than=\pgfmathfloatlessthan@{#1}{#2}\ifpgfmathfloatcomparison #3\else #4\fi,
if is bounded=%
\expandafter\pgfmathfloatgetflagstomacro\expandafter{#1}\pgfplotsretval
\ifnum\pgfplotsretval>2 #3\else #2\fi,
if is=%
\pgfmathfloatifflags{#1}{#2}{#3}{#4},
log=\pgfmathlog@float{#1},%
datascaletrafo set params={%
\expandafter\edef\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname{#1}%
\expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{#2}%
},%
datascaletrafo set shift={%
\expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{#1}%
},%
datascaletrafo get params={%
\edef\pgfplotsretval{\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
\edef\pgfplotsretvalb{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}%
\edef\pgfmathresult{%
{\pgfplotsretval}%
{\pgfplotsretvalb}%
}%
},%
datascaletrafo={%
\edef\pgfmathresult{#1}%
\pgfmathfloatshift@\pgfmathresult{\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
\pgfmathfloattofixed\pgfmathresult
\expandafter\pgfmath@basic@subtract@\expandafter{\pgfmathresult}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}%
},%
datascaletrafo noshift={%
\edef\pgfmathresult{#1}%
\pgfmathfloatshift@\pgfmathresult{\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
\pgfmathfloattofixed{\pgfmathresult}%
},%
datascaletrafo undo shift=
\pgfmath@basic@subtract@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname},%
datascaletrafo redo shift=\pgfmath@basic@add@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname},%
datascaletrafo inverse={%
\pgfplotscoordmath@float@datascaletrafo@inverse{#1}%
},%
datascaletrafo inverse to fixed={%
\pgfplotscoordmath@float@datascaletrafo@inverse{#1}%
\pgfmathfloattofixed\pgfmathresult
},%
datascaletrafo noshift inverse={%
\pgfmathfloatparsenumber{#1}%
\pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
},%
datascaletrafo noshift inverse to fixed={%
\pgfmathfloatparsenumber{#1}%
\pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
\pgfmathfloattofixed\pgfmathresult
},%
}
\def\pgfplotscoordmath@float@datascaletrafo@inverse#1{%
\pgfmath@basic@add@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}%
\let\pgfplots@inverse@datascaletrafo@@shifted=\pgfmathresult
\pgfmathapproxequalto@{\pgfplots@inverse@datascaletrafo@@shifted}{0.0}%
\ifpgfmathcomparison
\pgfmathfloatcreate{0}{0.0}{0}%
\else
\pgfmathfloatparsenumber{\pgfplots@inverse@datascaletrafo@@shifted}%
\pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}%
\fi
}%
% Invokes a coordinate math routine.
%
% #1: the axis (x,y or z)
% #2: a method name declared by \pgfplotsdeclarecoordmath (one of
% 'op', 'parsenumber', 'tofixed' etc)
% #3-#9: any further arguments required to perform the call to '#2'.
%
% \pgfplotscoordmath {x}{op}{multiply}{{}{}}
% \pgfplotscoordmath {x}{parsenumber}{}
\def\pgfplotscoordmath#1#2{%
\edef\pgfplotscoordmathid{#1}%
\csname pgfpmth@\csname pgfcrdmth@#1\endcsname @#2\endcsname}%
\def\pgfplotscoordmathclassfor#1{\csname pgfcrdmth@#1\endcsname}%
\def\pgfplotscoordmathnotifydatascalesetfor#1{}%
% Enables a particular coordinate math class for the label `#1'.
%
% #1 a label (usually x,y or z)
% #2 the coordinate math class (one prepare by
% \pgfplotsdeclarecoordmath)
%
% From this point on, any call to \pgfplotscoordmath{#1}{...}
% will use the selected math class.
\def\pgfplotssetcoordmathfor#1#2{%
\pgfutil@ifundefined{pgfpmth@#2@initialise}{%
\pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, \string\pgfplotssetcoordmathfor{#1}{#2} failed since `#2' is unknown. Maybe you misspelled it?}\pgfeov%
}{%
\expandafter\edef\csname pgfcrdmth@#1\endcsname{#2}%
\pgfplotscoordmath{#1}{initialise}%
}%
}%
% Defines \pgfplotsretval to be the coordmath id for #1
\def\pgfplotsgetcoordmathfor#1{%
\pgfutil@ifundefined{pgfcrdmth@#1}{%
\pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, \string\pgfplotsgetcoordmathfor{#1} failed since `#1' is unknown. Maybe you misspelled it?}\pgfeov%
}{%
\pgfutil@namelet{pgfplotsretval}{pgfcrdmth@#1}%
}%
}%
\pgfplotssetcoordmathfor{pgfbasic}{pgfbasic}%
\pgfplotssetcoordmathfor{float}{float}%
\pgfplotssetcoordmathfor{meta}{float}%
\pgfplotssetcoordmathfor{default}{float}%
% ==================================================================================
% #1 the name of an input method for point meta. It must have been
% declared by \pgfplotsdeclarepointmetasource first.
% #2 any arguments supplied by the user (maybe empty).
\def\pgfplotssetpointmetainput#1#2{%
\csname pgfpmeta@#1@initfor\endcsname{#2}%
%
\edef\pgfplotspointmetainputhandler{#1}%
}%
% Expands to the current value of 'point meta'.
\def\pgfplotspointmetainputhandler{}
\def\pgfplotsaxisifhaspointmeta#1#2{%
\ifx\pgfplotspointmetainputhandler\pgfutil@empty #2\else #1\fi
}%
\newif\ifpgfplots@perpointmeta@expand
% Executes code '#2' if the point meta data #1 is bounded
% and '#3' otherwise
%
% If the point meta is symbolic, it will always return true if and
% only if the input is non-empty.
\def\pgfplotsifpointmetaisbounded#1#2#3{%
\ifpgfplots@perpointmeta@expand
\edef\pgfplots@loc@TMPc{#1}%
\else
% symbolic point meta may have expansion issues -- but support one
% level as we usually invoke it with a macro name:
\expandafter\def\expandafter\pgfplots@loc@TMPc\expandafter{#1}%
\fi
\ifx\pgfplots@loc@TMPc\pgfutil@empty
% an empty meta data is _never_ bounded.
#3\relax
\else
\if1\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname
% a (non-empty, see above) symbolic meta data is "bounded"
#2\relax
\else
% check the number:
\pgfplotscoordmath{meta}{if is bounded}{\pgfplots@loc@TMPc}{#2}{#3}%
\fi
\fi
}%
% Invokes '#1' if the axis contains the coordinate designated by
% \pgfplots@current@point@[xyz] and '#2' if not.
\def\pgfplotsaxisifcontainspoint#1#2{%
\pgf@xa=\pgfplots@current@point@x pt % FIXME : SCOPE REGISTERS!?
\pgf@ya=\pgfplots@current@point@y pt %
\ifpgfplots@curplot@threedim
\pgf@yb=\pgfplots@current@point@z pt %
\fi
\def\pgfplots@loc@TMPa{#2}%
%
% I assume that \pgfplots@[xyz]min@reg and min@reg are registers
% containing the limits.
\ifdim\pgf@xa<\pgfplots@xmin@reg
\else
\ifdim\pgf@xa>\pgfplots@xmax@reg
\else
\ifdim\pgf@ya<\pgfplots@ymin@reg
\else
\ifdim\pgf@ya>\pgfplots@ymax@reg
\else
\ifpgfplots@curplot@threedim
\ifdim\pgf@yb<\pgfplots@zmin@reg
\else
\ifdim\pgf@yb>\pgfplots@zmax@reg
\else
\def\pgfplots@loc@TMPa{#1}%
\fi
\fi
\else
\def\pgfplots@loc@TMPa{#1}%
\fi
\fi
\fi
\fi
\fi
\pgfplots@loc@TMPa%
}
% Declares a routine which can be used to get point meta input.
%
% Such a routine is invoked in a context where point coordinates are
% processed, i.e. during 'plot coordinates', 'plot table' or the like.
%
% The routine is called `#1'. It consists of several methods, which
% are described below, in the key definitions.
%
% #1: the name of the input routine.
% #2: a sequence of key-value pairs which can be used to overwrite
% 'assign', 'initfor' or the other components.
% See the definitions below for examples.
\def\pgfplotsdeclarepointmetasource#1#2{%
\expandafter\def\csname pgfpmeta@#1@assign\endcsname{\let\pgfplots@current@point@meta=\pgfutil@empty}%
\expandafter\def\csname pgfpmeta@#1@initfor\endcsname##1{%
\pgfplots@pointmeta@set@expand{#1}%
}%
\expandafter\def\csname pgfpmeta@#1@issymbolic\endcsname{0}%
\expandafter\def\csname pgfpmeta@#1@explicitinput\endcsname{0}%
\expandafter\def\csname pgfpmeta@#1@activate\endcsname{}%
\expandafter\def\csname pgfpmeta@#1@LUA class\endcsname{}%
\expandafter\def\csname pgfpmeta@#1@tostring\endcsname{#1}%
\edef\pgfplotsdeclarepointmetasource@{#1}%
\pgfqkeys{/pgfplots/@declare point meta src}{#2}%
}%
\def\pgfplots@pointmeta@set@expand#1{%
\if1\csname pgfpmeta@#1@explicitinput\endcsname
\pgfplots@perpointmeta@expandfalse
\else
\pgfplots@perpointmeta@expandtrue
\fi
}%
\pgfqkeys{/pgfplots/@declare point meta src}{%
%
% a macro used to initialise the point meta source when it is
% selected.
% This macro body is invoked by pgfplots when someone types
% 'point meta=x' -> will invoke 'pgfpmeta@x@initfor{}'.
% The first argument to initfor can be supplied by the user.
% PRECONDITION for 'initfor':
% - it will be invoked just before
% '\pgfplotspointmetainputhandler' will be changed.
% Default is to do nothing.
initfor/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @initfor\endcsname##1{#1}},%
%
% Called during the survey phase before the first 'assign' call.
% It is usually empty.
activate/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @activate\endcsname{#1}},%
%
% During the survey phase, this macro is expected to assign
% \pgfplots@current@point@meta
% if it is a numeric input method, it should return a
% floating point number.
% It is allowed to return an empty string to say "there is no point
% meta".
% PRECONDITION for '@assign':
% - the coordinate input method has already assigned its
% '\pgfplots@current@point@meta' (probably as raw input string).
% - the other input coordinates are already read.
% POSTCONDITION for '@assign':
% - \pgfplots@current@point@meta is ready for use:
% - EITHER a parsed floating point number
% - OR an empty string,
% - OR a symbolic string (if the issymbolic boolean is true)
% The default implementation is
% \let\pgfplots@current@point@meta=\pgfutil@empty
%
assign/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @assign\endcsname{#1}},%
%
% expands to either '1' or '0'
% A numeric source will be processed numerically in float
% arithmetics. Thus, the output of the @assign routine should be
% a macro \pgfplots@current@point@meta in float format.
%
% The output of a numeric point meta source will result in meta
% limit updates and the final map to [0,1000] will be
% initialised automatically.
%
% A symbolic input routine won't be processed.
% Default is '0'
%
issymbolic/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @issymbolic\endcsname{#1}},%
%
% expands to either
% '1' or '0'. In case '1', it expects explicit input from the
% coordinate input routines. For example, 'plot file' will look for
% further input after the x,y,z coordinates.
% Default is '0'
%
explicitinput/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @explicitinput\endcsname{#1}},%
%
% the associated LUA class name (if any). Use an empty string if
% there is none.
LUA class/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @LUA class\endcsname{#1}},%
%
tostring/.code=
{\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @tostring\endcsname{#1}},%
}%
% An empty one. This is simple to check with
% \ifx\pgfplotspointmetainputhandler\pgfutil@empty:
\pgfplotsdeclarepointmetasource{}{}
\pgfplotsdeclarepointmetasource{x}{assign={%
\let\pgfplots@current@point@meta=\pgfplots@current@point@x
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}%
\let\pgfplots@current@point@meta=\pgfmathresult
},
LUA class=pgfplots.XcoordAssignmentPointMetaHandler}
\pgfplotsdeclarepointmetasource{y}{assign={%
\let\pgfplots@current@point@meta=\pgfplots@current@point@y
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}%
\let\pgfplots@current@point@meta=\pgfmathresult
},
LUA class=pgfplots.YcoordAssignmentPointMetaHandler}
\pgfplotsdeclarepointmetasource{z}{assign={%
\let\pgfplots@current@point@meta=\pgfplots@current@point@z
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}%
\let\pgfplots@current@point@meta=\pgfmathresult
},
LUA class=pgfplots.ZcoordAssignmentPointMetaHandler}
\pgfplotsdeclarepointmetasource{explicit}{%
assign={%
\ifx\pgfplots@current@point@meta\pgfutil@empty
\else
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}%
\let\pgfplots@current@point@meta=\pgfmathresult
\fi
},
explicitinput=1,%
LUA class=pgfplots.ExplicitPointMetaHandler.new(),
}%
\pgfplotsdeclarepointmetasource{explicit symbolic}{%
assign={},% no math, simply collect.
explicitinput=1,%
issymbolic=1%
}%
\pgfplotsdeclarepointmetasource{expr}{%
assign={%
\csname pgfpmeta@\pgfpmeta@expr@origchoice @assign\endcsname
%
\pgfkeysgetvalue{/pgfplots/point meta/expr}\pgfplots@loc@TMPa
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
\pgfmathparse{\pgfplots@loc@TMPa}%
\pgfplotscoordmath{meta}{parsenumber}{\pgfmathresult}%
\let\pgfplots@current@point@meta=\pgfmathresult
\fi
},%
initfor={%
\pgfkeyssetvalue{/pgfplots/point meta/expr}{#1}%
\def\pgfplots@loc@TMPa{expr}%
\ifx\pgfplots@loc@TMPa\pgfplotspointmetainputhandler
\else
\let\pgfpmeta@expr@origchoice\pgfplotspointmetainputhandler
\fi
\ifx\pgfpmeta@expr@origchoice\pgfplots@loc@TMPa
\let\pgfpmeta@expr@origchoice\pgfutil@empty
\fi
%
\pgfplotsutilifcontainsmacro{#1}{%
% oh. The point meta expression contains a backslash - it
% depends on a macro. This means: it depends on \thisrow
% or similar TeX stuff - which must be evaluated by TeX.
%
% LUA cannot be used for this point meta handler.
\let\pgfpmeta@expr@LUA@class\pgfutil@empty
}{%
\def\pgfpmeta@expr@LUA@class{pgfplots.ExpressionPointMetaHandler.new("#1")}%
}%
\pgfplots@perpointmeta@expandtrue
},
LUA class=\pgfpmeta@expr@LUA@class,
}%
\pgfkeyssetvalue{/pgfplots/point meta/expr}{}%
\pgfplotsdeclarepointmetasource{f(x)}{%
activate={%
\ifpgfplots@curplot@threedim
\def\pgfplotspointmetainputhandler{z}%
\else
\def\pgfplotspointmetainputhandler{y}%
\fi
\csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname
},
}%
\pgfplotsdeclarepointmetasource{TeX code}{%
assign={%
\begingroup
\let\pgfplotspointmeta=\pgfutil@empty
\pgfplots@invoke@pgfkeyscode{/pgfplots/point meta/code/.@cmd}{}%
\pgfplotscoordmath{meta}{parsenumber}{\pgfplotspointmeta}%
\let\pgfplots@current@point@meta=\pgfmathresult
\pgfmath@smuggleone\pgfplots@current@point@meta
\endgroup
},%
initfor={%
\pgfkeysdef{/pgfplots/point meta/code}{#1}%
\pgfplots@perpointmeta@expandtrue
},
}%
\pgfplotsdeclarepointmetasource{TeX code symbolic}{%
assign={%
\begingroup
\let\pgfplotspointmeta=\pgfutil@empty
\pgfplots@invoke@pgfkeyscode{/pgfplots/point meta/code/.@cmd}{}%
\let\pgfplots@current@point@meta=\pgfplotspointmeta
\pgfmath@smuggleone\pgfplots@current@point@meta
\endgroup
},%
initfor={%
\pgfkeysdef{/pgfplots/point meta/code}{#1}%
\pgfplots@perpointmeta@expandfalse
},
issymbolic=1%
}%
\pgfkeysdef{/pgfplots/point meta/code}{}%
% Internal stream methods.
%
% Please overwrite
% - \pgfplots@coord@stream@start@,
% - \pgfplots@coord@stream@end@ and
% - \pgfplots@coord@stream@coord@
% if you implement streams.
%
% REMARK:
% - the stream methods automatically collect first and last
% coordinates.
% - I have experimented with global \addplot accumulation to reduce
% copy operations. That experiment was not successfull (it was not
% faster :-( ). However, the streaming methods still assign their
% things globally...
\def\pgfplots@coord@stream@start{%
\let\pgfplots@current@point@x=\pgfutil@empty
\let\pgfplots@current@point@y=\pgfutil@empty
\let\pgfplots@current@point@z=\pgfutil@empty
\let\pgfplots@current@point@meta=\pgfutil@empty
\let\pgfplots@current@point@error@x@plus=\pgfutil@empty
\let\pgfplots@current@point@error@x@minus=\pgfutil@empty
\let\pgfplots@current@point@error@y@plus=\pgfutil@empty
\let\pgfplots@current@point@error@y@minus=\pgfutil@empty
\let\pgfplots@current@point@error@z@plus=\pgfutil@empty
\let\pgfplots@current@point@error@z@minus=\pgfutil@empty
\pgfplots@coord@stream@start@}%
\def\pgfplots@coord@stream@end{\pgfplots@coord@stream@end@}
% Will be invoked for every point coordinate.
%
% It invokes \pgfplots@coord@stream@coord@.
%
% Arguments:
% \pgfplots@current@point@[xyz]
% \pgfplots@current@point@[xyz]@error (if in argument list)
% \pgfplots@current@point@meta
\def\pgfplots@coord@stream@coord{%
\pgfplots@coord@stream@coord@%
}%
\def\pgfplotscoordstream@firstlast@init{%
\global\let\pgfplots@currentplot@firstcoord@x=\pgfutil@empty
\global\let\pgfplots@currentplot@firstcoord@y=\pgfutil@empty
\global\let\pgfplots@currentplot@firstcoord@z=\pgfutil@empty
\global\let\pgfplots@currentplot@lastcoord@x=\pgfutil@empty
\global\let\pgfplots@currentplot@lastcoord@y=\pgfutil@empty
\global\let\pgfplots@currentplot@lastcoord@z=\pgfutil@empty
}%
\def\pgfplotscoordstream@firstlast@update{%
\ifx\pgfplots@current@point@x\pgfutil@empty
% only one \if is enough as ONE empty coordinate causes all
% others to be reset as well.
\else
\ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty
\global\let\pgfplots@currentplot@firstcoord@x=\pgfplots@current@point@x
\global\let\pgfplots@currentplot@firstcoord@y=\pgfplots@current@point@y
\global\let\pgfplots@currentplot@firstcoord@z=\pgfplots@current@point@z
\fi
\global\let\pgfplots@currentplot@lastcoord@x=\pgfplots@current@point@x
\global\let\pgfplots@currentplot@lastcoord@y=\pgfplots@current@point@y
\global\let\pgfplots@currentplot@lastcoord@z=\pgfplots@current@point@z
\fi
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Scanline management. The idea is to handle complete sequences of
% input coordinates, which are usually separated by a blank line.
%
% This allows a simple syntax to provide matrix input - by means of scanlines.
% Furthermore, 2d plots can use it to interrupt the display.
%
% An empty line in 'addplot coordinates {}' indicates the end of a
% scan line. Similarly, an empty line in 'addplot file' or 'table'
% also indicates the end of a scan line.
%
% The steps taken whenever a scan line is complete depend on the
% configuration of the /pgfplots/empty line choice key (queried in
% \pgfplotsscanlinelengthinitzero).
%
%
% The following methods constitute the scanline interface.
%
% Usage:
%
% \pgfplotsscanlinelengthinitzero
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinecomplete
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinecomplete
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinelengthincrease
%
% \pgfplotsscanlinecomplete
%
% \pgfplotsscanlinelengthcleanup
%
% In other words, the \pgfplotsscanlinelengthincrease routine is
% invoked *before* the point is processed. That's important.
%
% Now, \pgfplotsscanlinelength expands to either
% a) a negative number in which case there is no
% unique scanline length.
% More precisely, -1 means "there was no end-of-scanline marker"
% -2 means "there where end-of-scanline markers, but the scanlines
% had different lengths.
% b) the scanline length.
\def\pgfplotsscanlinelengthinitzero{%
\def\pgfplotsscanlinelength{-1}%
\pgfkeysgetvalue{/pgfplots/empty line}\pgfplots@loc@TMPa%
\edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa}%
\def\pgfplots@loc@TMPb{auto}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
\pgfplotsdetermineemptylinehandler
\pgfkeysgetvalue{/pgfplots/empty line}\pgfplots@loc@TMPa%
\fi
\def\pgfplots@loc@TMPb{jump}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
\def\pgfplots@loc@TMPa{nan}% alias for jump
\fi
\def\pgfplots@loc@TMPb{no op}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
\def\pgfplots@loc@TMPa{none}% alias for no op
\fi
\pgfutil@ifundefined{pgfplotsscanlinelength@\pgfplots@loc@TMPa @initzero}{%
\pgfplots@error{Sorry, the choice `empty line=\pgfkeysvalueof{/pgfplots/empty line}' is unknown. Maybe you misspelled it}%
}{}%
\expandafter\let\expandafter\pgfplotsscanlinelength@initzero \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @initzero\endcsname
\expandafter\let\expandafter\pgfplotsscanlinelengthincrease \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @increase\endcsname
\edef\pgfplotsscanlinecomplete{%
\expandafter\noexpand\csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @complete\endcsname
}%
\expandafter\let\expandafter\pgfplotsscanlinelengthcleanup \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @cleanup\endcsname
\pgfplotsscanlinelength@initzero
}%
\newif\ifpgfplots@emptyline@compat
% Invoked for 'empty line=auto'.
%
% @POSTCONDITION: '/pgfplots/empty line' is set to something useful
% (not auto)
\def\pgfplotsdetermineemptylinehandler{%
\if n\pgfplots@meshmode
% no mesh/surf plot:
\pgfkeyssetvalue{/pgfplots/empty line}{jump}%
\ifpgfplots@emptyline@compat
\pgfkeyssetvalue{/pgfplots/empty line}{none}% do nothing for backwards compatibility with 2D processing.
\fi
\else
% it is a mesh or surf plot; use scanline:
\pgfkeyssetvalue{/pgfplots/empty line}{scanline}%
\fi
}%
\def\pgfplotsscanlinedisablechanges{%
\let\pgfplotsscanlinecomplete=\relax
\let\pgfplotsscanlinelengthincrease=\relax
\let\pgfplotsscanlinelengthcleanup=\relax
\let\pgfplotsscanlinelengthinitzero=\relax
\let\pgfplotsscanlineendofinput=\relax
}%
% -------------------------------------------------------------------------------
% empty line=scanline
% class:
\def\pgfplotsscanlinelength@scanline@initzero{%
\c@pgfplots@scanlineindex=0 % the index _inside_ of the current scanline
\def\pgfplotsscanlinecurrentlength{\the\c@pgfplots@scanlineindex}%
\def\pgfplotsscanlineindex{0}% 0 is the first scanline, 1 the second, and so on
\def\pgfplots@scanlinelength{-1}%
}
\def\pgfplotsscanlinelength@scanline@increase{%
\advance\c@pgfplots@scanlineindex by1
}
\def\pgfplotsscanlinelength@scanline@complete{%
\ifnum\pgfplots@scanlinelength>0
\ifnum\c@pgfplots@scanlineindex=0
%
% \pgfplotsscanlinecomplete
% \pgfplotsscanlinecomplete
% \pgfplotsscanlinecomplete
% should have the same effect as a single statement. Do
% nothing here.
\else
\ifnum\pgfplots@scanlinelength=\c@pgfplots@scanlineindex\relax
\else
%\message{Found inconsistent scan line length: \pgfplots@scanlinelength\space vs. \the\c@pgfplots@scanlineindex\space near line \pgfplotstablelineno.}%
% special marker which means 'inconsistent scan line length found'
\def\pgfplots@scanlinelength{-2}%
\fi
\pgfplotsplothandlernotifyscanlinecomplete
\fi
\else
\ifnum\pgfplots@scanlinelength=-2
\else
\edef\pgfplots@scanlinelength{\the\c@pgfplots@scanlineindex}%
\fi
%
\ifnum\c@pgfplots@scanlineindex>0
\pgfplotsplothandlernotifyscanlinecomplete
\fi
\fi
\c@pgfplots@scanlineindex=0
\pgfplotsutil@advancestringcounter\pgfplotsscanlineindex%
}
\def\pgfplotsscanlinelength@scanline@cleanup{%
\ifnum\c@pgfplots@scanlineindex=0
% I assume the last scan line is already complete.
\else
\pgfplotsscanlinecomplete
\fi
\let\pgfplotsscanlinelength=\pgfplots@scanlinelength
}
% -------------------------------------------------------------------------------
%
% empty line=none class:
%
\let\pgfplotsscanlinelength@none@initzero=\pgfutil@empty
\let\pgfplotsscanlinelength@none@increase=\relax
\let\pgfplotsscanlinelength@none@complete=\relax
\let\pgfplotsscanlinelength@none@cleanup=\relax
% -------------------------------------------------------------------------------
%
% empty line=nan class:
\def\pgfplotsscanlinelength@nan@initzero{%
\def\pgfplotsscanlinelength@nan@isfirst{1}%
\let\pgfplotsscanlinelength@nan@pendingwork=\relax
\pgfplotsifinaxis{}{\let\pgfplotsaxisserializedatapoint=\relax}%
}%
\def\pgfplotsscanlinelength@nan@increase{%
\def\pgfplotsscanlinelength@nan@isfirst{0}%
\pgfplotsscanlinelength@nan@pendingwork
}%
\def\pgfplotsscanlinelength@nan@complete{%
\if1\pgfplotsscanlinelength@nan@isfirst
\else
\def\pgfplotsscanlinelength@nan@pendingwork{%
\ifpgfplots@LUA@backend@supported
\pgfplotsutil@directlua{pgfplots.texSurveyAddJump()}%
\else
% this will be executed when the next point has been
% found.
\def\pgfplots@current@point@x{}%
\def\pgfplots@current@point@y{}%
\def\pgfplots@current@point@z{}%
% simply serialize an empty point. That works -- the
% visualization phase checks if the coordinates are empty and
% visualizes them as "jump"
%
% Note that \pgfplotsplothandlersurveypoint is not a good
% choice here unless one employs its 'unbounded coords=jump'
% feature
\def\pgfplotsaxisplothasjumps{1}%
\pgfplotsaxisserializedatapoint
\fi
%
\let\pgfplotsscanlinelength@nan@pendingwork=\relax
}%
\fi
\def\pgfplotsscanlinelength@nan@isfirst{1}%
}%
\let\pgfplotsscanlinelength@nan@cleanup=\relax
%
% -------------------------------------------------------------------------------
\def\pgfplotsaxisfilteredcoordsaway{0}%
\def\pgfplotsaxisplothasjumps{0}%
\def\pgfplotsaxisplothasunboundedpointmeta{0}%
\newif\ifpgfplotsaxisparsecoordinateok
% Initialises
% \pgfplots@coord@stream@start
% \pgfplots@coord@stream@coord
% \pgfplots@coord@stream@end
% such that a following coordinate stream is processed properly. The
% following coordinate stream may come from different input methods.
%
% This coordinate stream is the first time a coordinate will be
% reported and processed by pgfplots. The task of this first pass is
% to
% - compute and update any axis limits,
% - collect and prepare ranges for color data,
% - handle stacked plots and error bars,
% - store the complete state of the plot's preprocessing in an
% internal datastructure for later completion.
% This involves a serialization of all processed points (i.e. the
% generation of a long coordinate list)
%
% Any \addplot command should issue \pgfplots@PREPARE@COORD@STREAM
% eventually.
%
% Arguments:
% #1: any trailing path commands after the 'plot' command as such,
% for example \addplot plot coordinates {...} -- (0,0);
% would yield #1 =' -- (0,0)'
%
% PRECONDITION:
% - needs to be called inside of \addplot.
% - \pgfplots@addplot@survey@@optionlist contains the
% provided to \addplot (all of them, including automatically
% determined ones)
%
% REMARK:
% The following code is permissable:
% \pgfplots@PREPARE@COORD@STREAM{...}
% \pgfplots@coord@stream@start
% ...
% \pgfplots@coord@stream@coord
% ..
% \pgfplots@coord@stream@coord
% ..
% \pgfplots@coord@stream@end
% -> All need to be the SAME LEVEL OF SCOPING! The '@coord' commands
% may not be scoped deeper than 'begin' and 'end'!
% - I had a version which allowed that. it was actually slower!
% - For now, the following things are global / local:
% - point coordinate list: local
% - meta data limits: global,
% - what about stacked plot stuff: appears to be a combination
% of local/global.
% - all that will be serialized and written into
% \pgfplots@stored@plotlist in \pgfplots@coord@stream@end.
% This list is global, so, if I am not mistaken, the scoping
% level of the complete stream operation from setup to @end can
% be as deep as necessary - as long as all operations have the
% same level of scoping.
%
% @see the detailed documentation in pgfplotsplothandlers.code.tex
\long\def\pgfplots@PREPARE@COORD@STREAM#1{%
\ifpgfplots@curplot@threedim
\global\pgfplots@threedimtrue
\fi
\def\pgfplotsaxisfilteredcoordsaway{0}%
\def\pgfplotsaxisplothasjumps{0}%
\def\pgfplotsaxisplothasunboundedpointmeta{0}%
%
% FIXME : these macros should not be redefined! They are defined
% in \pgfplots@prepare@axis@API right during \begin{axis}... they
% probably shouldn't be changed.
\ifpgfplots@curplot@threedim
\let\pgfplotsaxisupdatelimitsforcoordinate=\pgfplotsaxisupdatelimitsforcoordinatethreedim
\let\pgfplotsaxisparsecoordinate=\pgfplotsaxisparsecoordinatethreedim
\else
\let\pgfplotsaxisupdatelimitsforcoordinate=\pgfplotsaxisupdatelimitsforcoordinatetwodim
\let\pgfplotsaxisparsecoordinate=\pgfplotsaxisparsecoordinatetwodim
\fi
\begingroup
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\let\E=\noexpand
%
%\message{Assembled update-limits \ifpgfplots@curplot@threedim 3D\else 2D\fi macro to {\meaning\pgfplotsaxisupdatelimitsforcoordinate}}%
\ifpgfplots@bb@isactive
\else
% we are inside of
% \pgfplotsinterruptdatabb
% ..
% \endpgfinterruptboundingbox
% -> don't change data limits!
\gdef\pgfplotsaxisupdatelimitsforcoordinate##1##2##3{}%
\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% Takes a coordinate which is already parsed and applies steps
% such that it becomes its final values.
%
% This implements the stacked plot feature currently.
%
% PRECONDITION:
% \pgfplotsaxisparsecoordinate has already been called.
%
% POSTCONDITION:
% the point has its final coordinates; the axis won't change it
% anymore.
\xdef\pgfplotsaxispreparecoordinate{%
\E\ifpgfplotsaxisparsecoordinateok
% All following routines (limit updating/stacking/error
% bars) will use float numerics if necessary (controlled
% by ifs).
\E\pgfplotsaxistransformfromdatacs
\ifpgfplots@stackedmode
\E\pgfplots@stacked@preparepoint@inmacro%
\fi
\E\fi
}%
%
% A macro which should be called once for every data point during the
% survey phase.
%
% The caller is the plot handler's point survey routine.
%
% A data point might be a complicated thing which contains
% multiple coordinates. You need to invoke
% \pgfplotsaxisparsecoordinate and
% \pgfplotsaxispreparecoordinate for each of them. But
% \pgfplotsaxisdatapointsurveyed is invoked once for the complete
% set.
%
% @PRECONDITION
% - \pgfplots@current@point@[xyz] contain final coordinates
% (i.e. output of \pgfplotsaxispreparecoordinate)
%
% @POSTCONDITION
% - stacked plot things,
% - error bars,
% - xtick=data
% are all processed.
%
\xdef\pgfplotsaxisdatapointsurveyed{%
\E\ifpgfplotsaxisparsecoordinateok
% All following routines (limit updating/stacking/error
% bars) will use float numerics if necessary (controlled
% by ifs).
%
% Prepare \pgfplots@current@point@meta (see the preparation
% routine above):
\E\pgfplotsaxissurveysetpointmeta
%
\ifpgfplots@errorbars@enabled
\E\pgfplots@errorbars@survey@point
\fi
%
\ifpgfplots@collect@firstplot@astick
\ifnum\pgfplots@numplots=0
\E\ifx\E\pgfplots@firstplot@coords@x\E\pgfutil@empty
\E\t@pgfplots@tokc={}%
\E\else
\E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@x,}%
\E\fi
\E\xdef\E\pgfplots@firstplot@coords@x{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@x}%
\E\ifx\E\pgfplots@firstplot@coords@y\E\pgfutil@empty
\E\t@pgfplots@tokc={}%
\E\else
\E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@y,}%
\E\fi
\E\xdef\E\pgfplots@firstplot@coords@y{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@y}%
%
\ifpgfplots@curplot@threedim
\E\ifx\E\pgfplots@firstplot@coords@z\E\pgfutil@empty
\E\t@pgfplots@tokc={}%
\E\else
\E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@z,}%
\E\fi
\E\xdef\E\pgfplots@firstplot@coords@z{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@z}%
\fi
\fi
\fi
\E\pgfplotscoordstream@firstlast@update
\E\pgfplotsaxisserializedatapoint
\E\else
% COORDINATE HAS BEEN FILTERED AWAY:
%
% make ALL empty to simplify special case checking:
\E\let\E\pgfplots@current@point@x=\E\pgfutil@empty
\E\let\E\pgfplots@current@point@y=\E\pgfutil@empty
\E\let\E\pgfplots@current@point@z=\E\pgfutil@empty
% check whether we have UNBOUNDED or just unfiltered
% coords:
\if\pgfplots@unbounded@handler d% unbounded coords=discard
\E\def\E\pgfplotsaxisfilteredcoordsaway{1}%
\ifpgfplots@warn@for@filter@discards
\E\pgfplots@message{%
NOTE: coordinate (\E\pgfplots@current@point@x@unfiltered,\E\pgfplots@current@point@y@unfiltered\ifpgfplots@curplot@threedim,\E\pgfplots@current@point@z@unfiltered\fi)
has been dropped because
\E\ifx\E\pgfplots@unbounded@dir\E\pgfutil@empty
of a coordinate filter.
\E\else
it is unbounded (in \E\pgfplots@unbounded@dir).
\E\fi
(see also unbounded coords=jump).
}%
\fi
\else
% unbounded coords=jump
\E\ifx\E\pgfplots@unbounded@dir\E\pgfutil@empty
\E\def\E\pgfplotsaxisfilteredcoordsaway{1}%
\ifpgfplots@warn@for@filter@discards
\E\pgfplots@message{%
NOTE: coordinate (\E\pgfplots@current@point@x@unfiltered,\E\pgfplots@current@point@y@unfiltered\ifpgfplots@curplot@threedim,\E\pgfplots@current@point@z@unfiltered\fi)
has been dropped because of a coordinate filter.
}%
\fi
\E\else
\E\def\E\pgfplotsaxisplothasjumps{1}%
\E\pgfplotsaxisserializedatapoint
\E\fi
\fi
\E\fi
%
% increase \pgfplots@current@point@coordindex:
\E\advance\E\c@pgfplots@coordindex by1
}%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endgroup
%
\def\pgfplotsaxissurveysetpointmeta{%
\pgfplotsplothandlersurveybeforesetpointmeta
\pgfplots@set@perpointmeta
\pgfplotsplothandlersurveyaftersetpointmeta
}%
%
%\message{Prepared macro \string\pgfplots@update@limits@for@one@point: {\meaning\pgfplotsaxisupdatelimitsforcoordinate}}%
%\message{Prepared macro \string\pgfplots@process@one@point: {\meaning\pgfplots@process@one@point}}%
%
\let\pgfplots@coord@stream@start@=\pgfplots@PREPARE@COORD@STREAM@start@
\def\pgfplots@coord@stream@coord@{%
\def\pgfplots@set@perpointmeta@done{0}%
% NOTE: this might call LUA (if supported):
\pgfplotsplothandlersurveypoint
}%
\def\pgfplots@coord@stream@end@{\pgfplots@PREPARE@COORD@STREAM@end@{#1}}%
}%
% The \pgfplots@coord@stream@start@ routine used inside of
% \pgfplots@PREPARE@COORD@STREAM.
%
% It prepares everything for the first pass through all input
% coordinates.
\def\pgfplots@PREPARE@COORD@STREAM@start@{%
% The current implementation of pgfplots stores the preprocessed
% coordinate stream into a long list of coordinates.
% Since macro append is an expensive operation, it uses the highly
% optimized 'applistXX' structure:
\pgfplotsapplistXXnewempty
%
\edef\plotnumofactualtype{\numplotsofactualtype}%
\csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname
\pgfplots@LUA@survey@start
\pgfplotsplothandlersurveystart
\pgfplotscoordstream@firstlast@init
%
\pgfkeyssetvalue{/data point/x}{\pgfplots@current@point@x}%
\pgfkeyssetvalue{/data point/y}{\pgfplots@current@point@y}%
\pgfkeyssetvalue{/data point/z}{\pgfplots@current@point@z}%
\pgfkeyssetvalue{/data point/meta}{\pgfplots@current@point@meta}%
%
\ifpgfplots@stackedmode
\pgfplots@stacked@beginplot
\fi
\ifpgfplots@errorbars@enabled
% prepare error bar processing.
\pgfplots@errorbars@survey@begin
\fi
%
%
\pgfplots@prepare@visualization@dependencies
%
% Inside of math expressions, 'x', 'y' and 'z' expand to the
% current x,y and z coords respectively. Introduce these (and some
% more) shortcuts:
% FIXME : defining the resulting x/y coordinates as 'x' and 'y' constants was a really really bad idea in the first place :-(
\pgfplotsmathdeclarepseudoconstant{x}{\let\pgfmathresult=\pgfplots@current@point@x}%
\pgfplotsmathdeclarepseudoconstant{y}{\let\pgfmathresult=\pgfplots@current@point@y}%
\pgfplotsmathdeclarepseudoconstant{z}{\let\pgfmathresult=\pgfplots@current@point@z}%
\pgfplotsmathdeclarepseudoconstant{rawx}{\let\pgfmathresult=\pgfplots@current@point@x@unfiltered}%
\pgfplotsmathdeclarepseudoconstant{rawy}{\let\pgfmathresult=\pgfplots@current@point@y@unfiltered}%
\pgfplotsmathdeclarepseudoconstant{rawz}{\let\pgfmathresult=\pgfplots@current@point@z@unfiltered}%
\pgfplotsmathdeclarepseudoconstant{meta}{%
\let\pgfmathresult=\pgfplots@current@point@meta
\ifx\pgfmathresult\pgfutil@empty
\pgfplotscoordmath{meta}{parsenumber}{0}%
\fi
}%
%
% %%%%%%%%%%%%%%
%
% Define \pgfplots@set@perpointmeta properly:
\def\pgfplots@set@perpointmeta{%
\if0\pgfplots@set@perpointmeta@done
\csname pgfpmeta@\pgfplotspointmetainputhandler @assign\endcsname
\def\pgfplots@set@perpointmeta@done{1}%
\pgfplots@set@perpointmeta@limits
\fi
}%
% append limit updating to \pgfplots@set@perpointmeta :
\if0\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname
% We need to work with per point meta data.
% So, also compute the data range on a per-plot basis!
% These limits are important later.
\pgfkeysgetvalue{/pgfplots/point meta min}\pgfplots@metamin
\t@pgfplots@tokb={}%
\ifx\pgfplots@metamin\pgfutil@empty
\global\let\pgfplots@metamin=\pgfplots@invalidrange@metamin
\t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb
\pgfplotscoordmath{meta}{min}{\pgfplots@metamin}{\pgfplots@current@point@meta}%
\global\let\pgfplots@metamin=\pgfmathresult
}%
\else
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamin}%
\global\let\pgfplots@metamin=\pgfmathresult
\fi
\pgfkeysgetvalue{/pgfplots/point meta max}\pgfplots@metamax
\ifx\pgfplots@metamax\pgfutil@empty
\global\let\pgfplots@metamax=\pgfplots@invalidrange@metamax
\t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb
\pgfplotscoordmath{meta}{max}{\pgfplots@metamax}{\pgfplots@current@point@meta}%
\global\let\pgfplots@metamax=\pgfmathresult
}%
\else
\pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamax}%
\global\let\pgfplots@metamax=\pgfmathresult
\fi
%
\edef\pgfplots@set@perpointmeta@limits{%
\noexpand\pgfplotsifpointmetaisbounded{\noexpand\pgfplots@current@point@meta}{%
\the\t@pgfplots@tokb
}{%
\noexpand\def\noexpand\pgfplotsaxisplothasunboundedpointmeta{1}%
}%
}%
\else
% there is no point meta:
\global\let\pgfplots@metamin=\pgfutil@empty
\global\let\pgfplots@metamax=\pgfutil@empty
\def\pgfplots@set@perpointmeta@limits{%
\pgfplotsifpointmetaisbounded{\pgfplots@current@point@meta}{%
}{%
\def\pgfplotsaxisplothasunboundedpointmeta{1}%
}%
}%
\fi
}%
\def\pgfplotsaxisupdatelimitsforpointmeta#1{%
\begingroup
\def\pgfplots@current@point@meta{#1}%
\pgfplots@set@perpointmeta@limits
\endgroup
}%
% This is the \pgfplots@coord@stream@end@ routine which is invoked by
% \pgfplots@PREPARE@COORD@STREAM.
%
% It finalizes the first pass through the input coordinates and
% remembers the preprocessed \addplot command.
%
% Technical note: The parameters provided to
% \pgfplots@PREPARE@COORD@STREAM
% are needed here. This doesn't fit directly into the framework of
% coordinate streams, see \pgfplots@PREPARE@COORD@STREAM how this
% invocation works.
%
% #1,#2: see \pgfplots@PREPARE@COORD@STREAM
\def\pgfplots@PREPARE@COORD@STREAM@end@#1{%
\pgfkeysvalueof{/pgfplots/execute at end survey}%
\ifpgfplots@LUA@backend@supported
\pgfplots@LUA@survey@end
\fi
% FIXME : move this the \pgfplotsplothandlersurveyend of mesh plot
% handler:
\pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfplots@current@point@coordindex}%
%
\pgfplotsplothandlersurveyend
\ifx\pgfplots@metamin\pgfutil@empty
\else
\if\pgfplots@axiswide@metamin@autocompute1%
\pgfplotscoordmath{meta}{min}{\pgfplots@axiswide@metamin}{\pgfplots@metamin}%
\global\let\pgfplots@axiswide@metamin=\pgfmathresult
\fi
\if\pgfplots@axiswide@metamax@autocompute1%
\pgfplotscoordmath{meta}{max}{\pgfplots@axiswide@metamax}{\pgfplots@metamax}%
\global\let\pgfplots@axiswide@metamax=\pgfmathresult
\fi
\fi
\if1\pgfplots@colorbar@set@src% this 0|1 switch is set in \pgfplots@start@plot@with@behavioroptions
\ifx\pgfplots@metamin\pgfutil@empty
\pgfplotsthrow{no such element}{\pgfplots@loc@TMPa}{Sorry, `colorbar source' can't be processed: the current \string\addplot\space command doesn't have point meta. Ignoring it.}\pgfeov%
\else
\global\let\pgfplots@colorbar@src@metamin=\pgfplots@metamin
\global\let\pgfplots@colorbar@src@metamax=\pgfplots@metamax
\fi
\fi
\ifpgfplots@autocompute@all@limits
\global\let\pgfplots@data@xmin=\pgfplots@xmin
\global\let\pgfplots@data@xmax=\pgfplots@xmax
\global\let\pgfplots@data@ymin=\pgfplots@ymin
\global\let\pgfplots@data@ymax=\pgfplots@ymax
\global\let\pgfplots@data@zmin=\pgfplots@zmin
\global\let\pgfplots@data@zmax=\pgfplots@zmax
\fi
\ifpgfplots@errorbars@enabled
\pgfplots@errorbars@survey@end
\fi
\ifpgfplots@stackedmode
\pgfplots@stacked@survey@endplot
\fi
\ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty
\pgfplotswarning{plot without coordinates}\pgfeov%
\else
% Idea: use
% \scope[plot specification]
%
% \endscope
% \draw plot coordinates {...};
% to share plot specifications between error bars and plot
% coordinates. Unfortunately, it is NOT sufficient to use
% \tikzset
%
%% FIXME : why is this here and not in the mesh plot handler!?
\pgfplotspreparemeshkeydefaults%
\pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting x%
\pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting y%
%
\pgfplots@remember@survey@option@list
%
% warning: rememberplotspec calls list macros which
% overwrite \t@pgfplots@toka
\t@pgfplots@toka=\expandafter{\pgfplots@addplot@survey@@optionlist}%
% ATTENTION: do NOT call list macros from here on!
%
\pgfplotsplothandlerserializestateto\pgfplots@loc@TMPa
\t@pgfplots@tokb=\expandafter{\pgfplots@loc@TMPa}%
%
\pgfplots@markers@survey@set@visphasename
\let\pgfplots@markers@visphase@name=\pgfplotsretval
%
\pgfplotssurveyphase@set@visphase@names{#1}%
\let\pgfplots@visphase@names=\pgfplotsretval
%
\t@pgfplots@tokc={#1}%
%
% SERIALIZE RESULT:
%
% everything which has been accumulated so far (including the
% preprocessed coordinates) will be serialized into the
% structure \pgfplots@stored@plotlist (globally).
%
% assemble a \pgfplots@addplot@enqueue@coords command ...
% BEGIN HERE ...
% vvvvvvvvvv
\xdef\pgfplots@glob@TMPa{%
\noexpand\pgfplots@addplot@enqueue@coords
{% precommand(s):
\expandafter\noexpand\csname pgfplots@curplot@threedim\ifpgfplots@curplot@threedim true\else false\fi\endcsname
%
% Did we prepare the data within LUA? remember that!
\ifpgfplots@LUA@backend@supported
\noexpand\pgfplots@LUA@backend@supportedtrue
\pgfplots@LUA@backend@serialized@commands
\else
\noexpand\pgfplots@LUA@backend@supportedfalse
\fi
\noexpand\def\noexpand\plotnum{\the\pgfplots@numplots}%
%
% store \plotnumofactualtype
\noexpand\def\noexpand\plotnumofactualtype{\plotnumofactualtype}%
% ... and make sure that it
% remains the same type even if some plot handler uses
% other plot handlers internally:
\noexpand\def\noexpand\pgfplotsplothandlername@actual{\pgfplotsplothandlername@actual}%
\noexpand\let\noexpand\numplotsofactualtype\noexpand\pgfplots@numplotsofactualtype@duringplot
%
\noexpand\def\noexpand\numcoords{\pgfplots@current@point@coordindex}%
% \pgfplots@current@point@coordindex will always contain the current index.
% Maybe overwritten if not provided using \c@pgfplots@coordindex.
\noexpand\def\noexpand\pgfplots@current@point@coordindex{\noexpand\the\noexpand\c@pgfplots@coordindex}%
\noexpand\def\noexpand\coordindex{\noexpand\pgfplots@current@point@coordindex}% valid inside of \addplot
%
\ifpgfplots@stackedmode
\pgfplots@stacked@serialized@commands
\fi
%
% save the possibly prepare/adjusted plot
% variables [FIXME: move after \pgfplots@define@currentplotstyle@as ?]:
\noexpand\pgfkeyssetvalue{/pgfplots/samples}{\pgfplots@plot@samples}%
\noexpand\pgfkeyssetvalue{/pgfplots/domain}{\pgfplots@plot@domain}%
\noexpand\pgfkeyssetvalue{/pgfplots/samples at}{\pgfplots@plot@samples@at}%
\noexpand\pgfkeyssetvalue{/pgfplots/mesh/rows}{\pgfkeysvalueof{/pgfplots/mesh/rows}}%
\noexpand\pgfkeyssetvalue{/pgfplots/mesh/cols}{\pgfkeysvalueof{/pgfplots/mesh/cols}}%
\noexpand\pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfkeysvalueof{/pgfplots/mesh/num points}}%
% either '+' or '-' :
\noexpand\pgfkeyssetvalue{/pgfplots/x coord sorting}{\pgfkeysvalueof{/pgfplots/x coord sorting}}%
\noexpand\pgfkeyssetvalue{/pgfplots/y coord sorting}{\pgfkeysvalueof{/pgfplots/y coord sorting}}%
%
% remember 'current plot style':
\noexpand\pgfplots@define@currentplotstyle@as{%
\the\t@pgfplots@toka
}%
% per-point meta data ranges which apply only to
% this plot:
\noexpand\xdef\noexpand\pgfplots@metamin{\pgfplots@metamin}%
\noexpand\xdef\noexpand\pgfplots@metamax{\pgfplots@metamax}%
\noexpand\def\noexpand\pgfplotspointmetainputhandler{\pgfplotspointmetainputhandler}%
\noexpand\def\noexpand\pgfplots@serialized@state@plothandler{\the\t@pgfplots@tokb}%
\noexpand\def\noexpand\pgfplots@markers@visphase@name{\pgfplots@markers@visphase@name}%
\noexpand\def\noexpand\pgfplots@visphase@names{\pgfplots@visphase@names}%
\noexpand\def\noexpand\pgfplotsaxisfilteredcoordsaway{\pgfplotsaxisfilteredcoordsaway}%
\noexpand\def\noexpand\pgfplotsaxisplothasjumps{\pgfplotsaxisplothasjumps}%
\noexpand\def\noexpand\pgfplotsaxisplothasunboundedpointmeta{\pgfplotsaxisplothasunboundedpointmeta}%
\noexpand\pgfkeyssetvalue{/pgfplots/on layer}{\pgfkeysvalueof{/pgfplots/on layer}}%
\noexpand\def\noexpand\pgfplots@serialized@afterpath{\the\t@pgfplots@tokc}%
\noexpand\def\noexpand\pgfplots@addplot@point@meta@description@of@explicit@value{\pgfplots@addplot@point@meta@description@of@explicit@value}%
}%
{% draw command:
\noexpand\path%
}%
}%
\pgfplotsapplistXXlet\pgfplots@coord@stream@recorded
\pgfplotsapplistXXclear
\t@pgfplots@tokc=\expandafter{\pgfplots@coord@stream@recorded}%
\t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPa}%
\xdef\pgfplots@glob@TMPa{%
\the\t@pgfplots@toka
{% coordinates which need to be processed in \endaxis.
% See
% \pgfplots@coord@stream@finalize@storedcoords@START
% (will become available as \pgfplots@stored@current@data)
\the\t@pgfplots@tokc
}%
}%
%
\pgfplots@glob@TMPa
{%
% Post commands are empty here.
}%
%^^^^^^^^^^^^ ... END of \pgfplots@addplot@enqueue@coords HERE
\fi
\pgfplots@end@plot
}%
\def\pgfplots@remember@survey@option@list{%
\t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,%
/pgfplots/.cd,/pgfplots/every axis plot post}%
\edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}%
\edef\pgfplots@loc@TMPa{/pgfplots/every axis plot except legend/.code=,\the\t@pgfplots@tokc}%
\ifpgfplots@curplot@isirrelevant
% for \label commands:
\expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}%
\else
\expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@loc@TMPa}%
\fi
}%
\def\pgfplots@LUA@survey@log@deactivation#1{%
\pgfplots@log{\pgfplots@LUA@loglevel@info}{Using 'lua backend=false' for plot \the\pgfplots@numplots\space (type '\pgfplotsplothandlername'): #1.}%
\pgfplots@LUA@backend@failed
}%
\def\pgfplots@LUA@survey@get@filter#1{%
\begingroup
\pgfkeysgetvalue{/pgfplots/#1 filter/.@cmd}\pgfplots@loc@TMPc
\ifx\pgfplots@loc@TMPc\pgfplots@empty@command@key
\let\pgfplotsretval=\pgfutil@empty
\else
\pgfplots@ifisfilterexpression{#1 filter}{%
\pgfkeysgetvalue{/pgfplots/#1 filter/@expressionvalue}\pgfplotsretval
\expandafter\pgfplotsutilifcontainsmacro\expandafter{\pgfplotsretval}{%
\aftergroup\pgfplots@LUA@backend@supportedfalse
\pgfplots@command@to@string\pgfplotsretval\pgfplots@loc@TMPa
\pgfplots@LUA@survey@log@deactivation{#1 filter/.expression='\pgfplots@loc@TMPa' contains a TeX macro}%
\let\pgfplotsretval=\pgfutil@empty
}{%
}%
}{%
\aftergroup\pgfplots@LUA@backend@supportedfalse
\pgfplots@LUA@survey@log@deactivation{LUA does not support #1 filter (yet)}%
\let\pgfplotsretval=\pgfutil@empty
}%
\fi
\pgfmath@smuggleone\pgfplotsretval
\endgroup
}%
\def\pgfplots@LUA@survey@start{%
\ifpgfplots@LUA@backend@supported
\ifx\pgfplotsplothandlerLUAfactory\pgfutil@empty
\pgfplots@LUA@survey@log@deactivation{plot handler does not support LUA}%
\pgfplots@LUA@backend@supportedfalse
\fi
%
\ifx\pgfplotspointmetainputhandler\pgfutil@empty
\def\pgfplots@loc@TMPa{nil}%
\else
\edef\pgfplots@loc@TMPa{%
\csname pgfpmeta@\pgfplotspointmetainputhandler @LUA class\endcsname}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\pgfplots@LUA@survey@log@deactivation{point meta choice does not support LUA}%
\pgfplots@LUA@backend@supportedfalse
\fi
\fi
\ifpgfplots@stackedmode
\pgfplots@LUA@survey@log@deactivation{LUA does not support stacked plots (yet)}%
\pgfplots@LUA@backend@supportedfalse
\fi
\ifpgfplots@errorbars@enabled
\pgfplots@LUA@survey@log@deactivation{LUA does not support error bars (yet)}%
\pgfplots@LUA@backend@supportedfalse
\fi
\ifpgfplots@collect@firstplot@astick
\pgfplots@LUA@survey@log@deactivation{LUA does not support xtick=data (yet)}%
\pgfplots@LUA@backend@supportedfalse
\fi
\pgfkeysgetvalue{/pgfplots/pre filter/.@cmd}\pgfplots@loc@TMPc\ifx\pgfplots@loc@TMPc\pgfplots@empty@command@key\else \pgfplots@LUA@backend@supportedfalse\pgfplots@LUA@survey@log@deactivation{LUA does not support filter (yet)}\fi
\pgfplots@LUA@survey@get@filter x%
\let\pgfplots@loc@filter@x=\pgfplotsretval
\pgfplots@LUA@survey@get@filter y%
\let\pgfplots@loc@filter@y=\pgfplotsretval
\pgfplots@LUA@survey@get@filter z%
\let\pgfplots@loc@filter@z=\pgfplotsretval
\pgfkeysgetvalue{/pgfplots/filter point/.@cmd}\pgfplots@loc@TMPc\ifx\pgfplots@loc@TMPc\pgfplots@empty@command@key\else \pgfplots@LUA@backend@supportedfalse\pgfplots@LUA@survey@log@deactivation{LUA does not support filter (yet)}\fi
%
\pgfkeysgetvalue{/pgfplots/execute for finished point}\pgfplots@loc@TMPc\ifx\pgfplots@loc@TMPc\pgfutil@empty\else \pgfplots@LUA@backend@supportedfalse\fi
%
\pgfkeysgetvalue{/pgfplots/visualization depends on/list}\pgfplots@loc@TMPc \ifx\pgfplots@loc@TMPc\pgfutil@empty\else \pgfplots@LUA@backend@supportedfalse\pgfplots@LUA@survey@log@deactivation{LUA does not support 'visualization depends on' (yet)} \fi
%
%
\edef\pgfplots@loc@TMPc{\pgfkeysvalueof{/pgfplots/data cs}}%
\edef\pgfplots@loc@TMPd{\pgfkeysvalueof{/pgfplots/@expected axis cs}}%
\ifx\pgfplots@loc@TMPc\pgfplots@loc@TMPd\else\pgfplots@LUA@backend@supportedfalse\pgfplots@LUA@survey@log@deactivation{LUA does not support 'data cs' (yet)}\fi
%
% hm. There are various cases which are supported during a
% SURVEY -- but not during a visualization. Check that here:
\if m\pgfplots@colormap@access
\else
\if c\pgfplots@colormap@access
\pgfplots@LUA@survey@log@deactivation{color map access=piecewise constant not supported (yet)}%
\else
\pgfplots@LUA@survey@log@deactivation{color map access=direct not supported (yet)}%
\fi
\pgfplots@LUA@backend@supportedfalse
\fi
\pgfplotscolormapifisuniform{\pgfkeysvalueof{/pgfplots/colormap name}}{%
}{%
% FIXME : implement LUA for non-uniform colormaps
\pgfplots@LUA@survey@log@deactivation{non-uniform color maps unsupported currently}%
\pgfplots@LUA@backend@supportedfalse
}%
%
\ifpgfplots@LUA@backend@supported
\edef\pgfplots@LUA@backend@plotnum{\pgfutil@directlua{tex.sprint(\pgfplotsHASH pgfplots.gca.plothandlers)}}%
\begingroup
\pgfkeysgetvalue{/pgfplots/point meta min}\pgfplots@loc@metamin
\pgfkeysgetvalue{/pgfplots/point meta max}\pgfplots@loc@metamax
\pgfplots@log{\pgfplots@LUA@loglevel@debug}{lua backend=true: Activating LUA backend for plot \the\pgfplots@numplots\space (lua \pgfplots@LUA@backend@plotnum, type '\pgfplotsplothandlername').}%
\edef\pgfplots@loc@TMPa{%
local gca = pgfplots.gca;^^J%
gca.min = {^^J%
pgfplots.pgftonumber("\pgfplots@xmin"), ^^J%
pgfplots.pgftonumber("\pgfplots@ymin"), ^^J%
pgfplots.pgftonumber("\pgfplots@zmin")}; ^^J%
gca.max = {^^J%
pgfplots.pgftonumber("\pgfplots@xmax"), ^^J%
pgfplots.pgftonumber("\pgfplots@ymax"), ^^J%
pgfplots.pgftonumber("\pgfplots@zmax")}; ^^J%
% FIXME : what about datamin/datamax!?
local plothandlerFactory = \pgfplotsplothandlerLUAfactory; ^^J%
local plothandler = plothandlerFactory(gca, \pgfplots@loc@TMPa);^^J% second arg: point meta handler
\ifx\pgfplots@loc@metamin\pgfutil@empty
\else
plothandler.autocomputeMetaMin = false;^^J%
plothandler.metamin = pgfplots.pgftonumber("\pgfplots@loc@metamin");^^J%
\fi
\ifx\pgfplots@loc@metamax\pgfutil@empty
\else
plothandler.autocomputeMetaMax = false;^^J%
plothandler.metamax = pgfplots.pgftonumber("\pgfplots@loc@metamax");^^J%
\fi
local config = plothandler.config;^^J%
config.unboundedCoords = "\pgfplots@unbounded@handler";^^J%
config.warnForfilterDiscards = \pgfplots@boolval{pgfplots@warn@for@filter@discards};^^J%
config.pointmetarel = \pgfplots@perpointmeta@rel@choice;^^J%
config.updateLimits = \ifpgfplots@bb@isactive true\else false\fi;^^J%
config.filterExpressionByDir = {^^J%
"\pgfplots@loc@filter@x",^^J%
"\pgfplots@loc@filter@y",^^J%
"\pgfplots@loc@filter@z"};^^J%
gca.plothandlers[\pgfplots@LUA@backend@plotnum+1]= plothandler;^^J%
gca.currentPlotHandler = plothandler;^^J%
plothandler:surveystart();^^J%
}%
%\message{Executing ^^J\pgfplots@loc@TMPa^^J^^J}%
\pgfplotsutil@directlua{\pgfplots@loc@TMPa}%
\endgroup
\def\pgfplots@LUA@backend@serialized@commands{%
\noexpand\def\noexpand\pgfplots@LUA@backend@plotnum{\pgfplots@LUA@backend@plotnum}%
}%
\def\pgfplotsapplistXXpushback##1{%
\pgfplots@error{Illegal internal state encountered: lua backend should have been invoked at this point}%
}%
\fi
\fi
}%
\let\pgfplotsapplistXXpushback@orig=\pgfplotsapplistXXpushback
\def\pgfplots@LUA@survey@point{%
\edef\pgfplots@loc@TMPa{pgfplots.texSurveyPoint("\pgfplots@current@point@x","\pgfplots@current@point@y","\pgfplots@current@point@z","\pgfplots@current@point@meta")}%
\pgfplotsutil@directlua{\pgfplots@loc@TMPa}%
% increase \pgfplots@current@point@coordindex:
\advance\c@pgfplots@coordindex by1
}%
\def\pgfplots@LUA@survey@end{%
% LUA defines a couple of TeX macros here...
\pgfplotsutil@directlua{pgfplots.texSurveyEnd()}%
%
\let\pgfplotsapplistXXpushback=\pgfplotsapplistXXpushback@orig
\pgfplotsapplistXXpushback{--- acquire from LUA! --}%
}%
% this appears to be necessary for the mesh legend...
\def\b@pgfplots@LUA@visualization@enabled{0}%
% PRECONDITION : \pgfplots@LUA@visualization@init has already been
% executed.
\def\pgfplots@LUA@visualization@of@current@plot{%
\def\b@pgfplots@LUA@visualization@enabled{0}%
\ifpgfplots@LUA@backend@supported
\pgfkeysgetvalue{/pgfplots/axis type}\pgfplots@loc@TMPa
\def\pgfplots@loc@TMPb{rectangle}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
\else
% disable visualizer - we cannot do this right now.
\pgfplots@LUA@backend@failed
\let\pgfplotsplothandlerLUAvisualizerfactory=\pgfutil@empty
\fi
%
\ifx\pgfplotsplothandlerLUAvisualizerfactory\pgfutil@empty
% hm. This plot cannot be visualized in LUA - BUT it has a
% LUA survey! Ok, then: acquire the survey results.
% Otherwise we would have nothing here.
% FIXME : what about \pgfplots@LUA@backend@failed in this context!?
\pgfplots@log{\pgfplots@LUA@loglevel@info}{Using 'lua backend=false' for visualization of plot \the\pgfplots@numplots\space (type '\pgfplotsplothandlername'): it has no LUA visualizer.}%
\expandafter\def\expandafter\pgfplots@stored@current@data\expandafter{%
\pgfplotsutil@directlua{pgfplots.texGetSurveyedCoordsToPgfplots()}%
}%
\else
% visualize using LUA! ... and acquire the coordinates.
\expandafter\def\expandafter\pgfplots@stored@current@data\expandafter{%
\pgfplotsutil@directlua{pgfplots.texVisualizePlot(\pgfplotsplothandlerLUAvisualizerfactory)}%
}%
%\message{plot \plotnum: LUA backend returned \pgfplots@stored@current@data^^J}%
%
% ... and ensure that the resulting
% \pgfplots@stored@current@data can be deserialized. It
% contains the fully mapped X/Y coordinates as first item.
\let\pgfplotsaxisdeserializedatapointfrom@private@nonLUA=\pgfplotsaxisdeserializedatapointfrom@private
\def\pgfplotsaxisdeserializedatapointfrom@private##1{%
\pgfplotsaxisdeserializedatapointfrom@private@LUA##1%
}%
\def\pgfplotsaxisdeserializedatapointfrom@private@LUA##1##2##3{%
\global\pgf@x=##1pt %
\global\pgf@y=##2pt %
\pgfplotsaxisdeserializedatapointfrom@private@nonLUA{##3}%
}%
% FIXME : do I need to adopt the serializer as well!?
%
\def\b@pgfplots@LUA@visualization@enabled{1}%
\fi
\fi
}%
% Defines \pgfplotsretval to contain a comma-separated-list of
% visualization phase names. May be empty.
%
% These names will be stored as \pgfplots@visphase@names during the
% visualization phase.
%
% The role of "visualization phases" is to call the plot
% handler, and perhaps further visualization phases.
%
% This is entirely *independent* of plot marks which have their own,
% very special visualization phase.
%
% It is allowed if a plot has an empty list of visualization phases
% (common for 'only marks').
%
% #1: any tikz path instructions after the \addplot command but before
% the semicolon.
\def\pgfplotssurveyphase@set@visphase@names#1{%
% 1. check if we need the 'default' visualization phase:
\pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler
\ifx\pgfplots@basiclevel@plothandler\pgfplothandlerdiscard
% Ah - "only marks". In this case, we rely on the (special)
% marker visualization phase - there is no need for a further
% phase.
\pgfplotsutil@trim{#1}%
\ifx\pgfplotsretval\pgfutil@empty
% OK, we do not have after-path instructions.
% No need for this phase.
\let\pgfplotsretval=\pgfutil@empty
\else
% Hm. We found after-path instructions! These *need* to be
% done during the standard visualization phase. Ok, then
% do it, even if it has no uses otherwise!
\let\pgfplotsretval=\pgfplotsaxis@visphase@name@default
\fi
\else
\let\pgfplotsretval=\pgfplotsaxis@visphase@name@default
\fi
%
% 2. error bar phase:
\ifpgfplots@errorbars@enabled
\ifx\pgfplotsretval\pgfutil@empty
\else
\edef\pgfplotsretval{\pgfplotsretval,}%
\fi
%
\edef\pgfplotsretval{\pgfplotsretval \pgfplotsaxis@visphase@name@errorbars}%
\fi
%
% markers have the special phase \pgfplots@markers@visphase@name .
}%
\def\pgfplotsaxis@visphase@name@default{default}
\def\pgfplotsaxis@visphase@name@markers{markers}
% This defines \pgfplots@visphase@default:
\expandafter\def\csname pgfplots@visphase@\pgfplotsaxis@visphase@name@default\endcsname{%
\pgfplots@coord@stream@finalize@storedcoords@START
}%
% A routine which transforms the current set of
% \pgfplots@current@point@[xyz] values to the coordinate system
% accepted by the actual axis.
\def\pgfplotsaxistransformfromdatacs{%
\pgfkeyslet{/data point/x}\pgfplots@current@point@x
\pgfkeyslet{/data point/y}\pgfplots@current@point@y
\pgfkeyslet{/data point/z}\pgfplots@current@point@z
\pgfplotsaxistransformcs
{\pgfkeysvalueof{/pgfplots/data cs}}
{\pgfkeysvalueof{/pgfplots/@expected axis cs}}%
\pgfkeysgetvalue{/data point/x}\pgfplots@current@point@x
\pgfkeysgetvalue{/data point/y}\pgfplots@current@point@y
\pgfkeysgetvalue{/data point/z}\pgfplots@current@point@z
}%
% Changes '/data point/[xyz]' to the new coordinate system
% (cs) designated by '#2'.
%
% #1: the actual coordinate system's name
% #2: the desired coordinate system's name
%
% PRECONDITION: '/data point/[xyz]' contain the current
% point's coordinates in the '#1' system. The z coordinate is ignored for 2d plots (or
% for coordinate systems which are inherently two-dimensional).
%
% POSTCONDITION: 'data point/[xyz]' contain same point as
% before, but represented in the '#2' system.
%
% The coordinate system transformations must be defined,
% see \pgfplotsdefinecstransform.
%
% Example:
% \pgfkeyssetvalue{/data point/x}{90}
% \pgfkeyssetvalue{/data point/y}{1}
% \pgfplotsaxistransformcs{polar}{cart}
% -->
% \pgfkeysvalueof{/data point/x}= 0
% \pgfkeysvalueof{/data point/y}= 1
\def\pgfplotsaxistransformcs#1#2{%
\edef\pgfplots@loc@TMPa{#1}%
\edef\pgfplots@loc@TMPb{#2}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
% nothing to do
\else
\pgfutil@ifundefined{pgfp@transform@\pgfplots@loc@TMPa @to@\pgfplots@loc@TMPb}{%
\pgfutil@ifundefined{pgfp@transform@\pgfplots@loc@TMPa @to@cart}{%
\pgfplotsaxistransformcs@error
}{%
\pgfplotsaxistransformcs{#1}{cart}%
\pgfplotsaxistransformcs{cart}{#2}%
}%
}{%
\csname pgfp@transform@\pgfplots@loc@TMPa @to@\pgfplots@loc@TMPb\endcsname
}%
\fi
}%
% Defines a new coordinate transformation for use in
% \pgfplotsaxistransformcs.
% #1: the source coordinate system
% #2: the target coordinate system
% #3: the transformation code.
%
% @see \pgfplotsaxistransformcs for what #3 should do.
%
% This does also declare a coordinate system for use in 'data cs'.
% The minimal requirements are to define the transformations from and
% to "cart" (cartesian coordinates).
%
\def\pgfplotsdefinecstransform#1#2#3{%
\expandafter\def\csname pgfp@transform@#1@to@#2\endcsname{#3}%
}%
\pgfplotsdefinecstransform{polar}{cart}{%
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}%
\let\pgfplots@current@point@x=\pgfmathresult
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/y}}%
\let\pgfplots@current@point@y=\pgfmathresult
\pgfplotsmathpoltocart\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@x@\pgfplots@current@point@y@
\pgfplotscoordmath{x}{parsenumber}{\pgfplots@current@point@x@}%
\pgfkeyslet{/data point/x}\pgfmathresult
\pgfplotscoordmath{y}{parsenumber}{\pgfplots@current@point@y@}%
\pgfkeyslet{/data point/y}\pgfmathresult
}%
\pgfplotsdefinecstransform{cart}{polar}{%
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}%
\let\pgfplots@current@point@x=\pgfmathresult
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/y}}%
\let\pgfplots@current@point@y=\pgfmathresult
\pgfplotsmathcarttopol\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@x@\pgfplots@current@point@y@
\pgfplotscoordmath{x}{parsenumber}{\pgfplots@current@point@x@}%
\pgfkeyslet{/data point/x}\pgfmathresult
\pgfplotscoordmath{y}{parsenumber}{\pgfplots@current@point@y@}%
\pgfkeyslet{/data point/y}\pgfmathresult
}%
\pgfplotsdefinecstransform{polarrad}{polar}{%
\pgfplotsgetcoordmathfor{default}\let\pgfplots@coordmath@id=\pgfplotsretval
\pgfutil@ifundefined{pgfp@polarradscale@\pgfplots@coordmath@id}{%
\pgfplotscoordmath{default}{parsenumber}{57.2957795130823}%
\expandafter\global\expandafter\let\csname pgfp@polarradscale@\pgfplots@coordmath@id\endcsname=\pgfmathresult
}{}%
%
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}%
\pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\csname pgfp@polarradscale@\pgfplots@coordmath@id\endcsname}}%
\pgfkeyslet{/data point/x}\pgfmathresult
}%
\pgfplotsdefinecstransform{polar}{polarrad}{%
\pgfplotsgetcoordmathfor{default}\let\pgfplots@coordmath@id=\pgfplotsretval
\pgfutil@ifundefined{pgfp@polarradiscale@\pgfplots@coordmath@id}{%
\pgfplotscoordmath{default}{parsenumber}{0.0174532925199433}%
\expandafter\global\expandafter\let\csname pgfp@polarradiscale@\pgfplots@coordmath@id\endcsname=\pgfmathresult
}{}%
%
\pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}%
\pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\csname pgfp@polarradiscale@\pgfplots@coordmath@id\endcsname}}%
}%
\pgfplotsdefinecstransform{polarrad}{cart}{%
\pgfplotsaxistransformcs{polarrad}{polar}%
\pgfplotsaxistransformcs{polar}{cart}%
}%
\pgfplotsdefinecstransform{cart}{polarrad}{%
\pgfplotsaxistransformcs{cart}{polar}%
\pgfplotsaxistransformcs{polar}{polarrad}%
}%
\def\pgfplotsaxistransformcs@error{%
\pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, I do not know how to transform the coordinate system '\pgfplots@loc@TMPa' to '\pgfplots@loc@TMPb'. Maybe you misspelled the 'data cs'? Or perhaps the feature is not yet implemented?}\pgfeov%
}%
% Takes the current point and serializes it into \pgfplotsretval.
%
% The serialization includes the coordinates (as returned by the
% current plot handler), the point meta, and any "visualization
% depends on" keys.
%
% See \pgfplotsaxisdeserializedatapointfrom
%
% POSTCONDITION:
% \pgfplotsretval contains everything that is needed to restore the
% current coordinate. This includes
% - the coordinate values for x,y, and z
% - any special coordinate values reported by the plot handler
% (like u,v,w for quiver plots)
% - the point meta
% - any 'visualization depends on' value
% - anything which is needed for other purposes (stacked plots have
% a plugin).
%
% The result has an EXTRA SET OF BRACES which needs to be dealt with.
%
% Example:
% \pgfplotsaxisserializedatapointtostring
%
% \expandafter\pgfplotsaxisdeserializedatapointfrom\pgfplotsretval
%
% -> note the absence of extra braces for the deserialization!
\def\pgfplotsaxisserializedatapointtostring{%
\pgfplotsplothandlerserializepointto\pgfplotsaxisserializedatapoint@val
\let\pgfplots@oldprotect=\protect
\let\protect=\noexpand
\pgfplotsaxisserializedatapoint@private
\let\protect=\pgfplots@oldprotect
\t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@val}%
\t@pgfplots@tokb=\expandafter{\pgfplotsretval}%
\edef\pgfplotsretval{{\the\t@pgfplots@tokb;\the\t@pgfplots@toka}}%
}%
\def\pgfplotsaxisserializedatapoint{%
\pgfplotsaxisserializedatapointtostring
\expandafter\pgfplotsapplistXXpushback\expandafter{\pgfplotsretval}%
}%
\def\pgfplotsaxisserializedatapoint@private{%
\let\pgfplotsretval=\pgfplots@current@point@meta
}%
\def\pgfplotsaxisdeserializedatapointfrom@private#1{%
\def\pgfplots@current@point@meta{#1}%
}%
% Restores the variables serialized in '#1'.
%
% As a side--effect, the macro
% \pgfplotsaxisdeserializedatapointfrom@private@lastvalue will contain
% the serialized part which is specific to pgfplots (i.e. the private
% parts which can be read with
% \pgfplotsaxisdeserializedatapointfrom@private)
\def\pgfplotsaxisdeserializedatapointfrom#1{%
\expandafter\pgfplotsaxisdeserializedatapointfrom@#1\pgfplots@EOI
}%
\def\pgfplotsaxisdeserializedatapointfrom@#1;#2\pgfplots@EOI{%
\def\pgfplotsaxisdeserializedatapointfrom@private@lastvalue{#1}%
\pgfplotsaxisdeserializedatapointfrom@private{#1}%
\pgfplotsplothandlerdeserializepointfrom{#2}%
}%
% Handle User-defined parts which should be serialized as well.
% This preparation tool should be called at the start of both, survey
% and visualization phase.
%
% @PRECONDITION
% - the macros
% \pgfplotsaxisserializedatapoint@private
% \pgfplotsaxisdeserializedatapointfrom@private
% are known and valid.
% - '/pgfplots/visualization depends on' contains its correct value.
%
% @POSTCONDITION
% Both,
% \pgfplotsaxisserializedatapoint@private
% and
% \pgfplotsaxisdeserializedatapointfrom@private
% have been patched to incorporate the '/pgfplots/visualization
% depends on' feature.
%
\def\pgfplots@prepare@visualization@dependencies{%
\pgfkeysgetvalue{/pgfplots/visualization depends on/list}\pgfplots@loc@TMPa
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
% SERIALIZATION format:
% visualization depends on={{value1}\as \macro1, {}\as \macro2,...}
% ->
% {}<\macro1>{}<\macro2>{}...<\macroN>{}
%
% prepare
% \t@pgfplots@tokb={<\macro1>{}<\macro2>{}...<\macroN>{}}
\t@pgfplots@tokb={}%
%
% prepare
% \t@pgfplots@tokc={<\macro1><\macro2><\macro3>...}
\t@pgfplots@tokc={}%
\expandafter\pgfplotsutilforeachcommasep\expandafter{\pgfplots@loc@TMPa}\as\pgfplots@loc@TMPa{%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
\expandafter\pgfplots@prepare@visualization@depends@on\pgfplots@loc@TMPa\pgfplots@EOI%
\fi
}%
% Step 1: modify the SERIALIZATION method:
\t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@private}%
\edef\pgfplotsaxisserializedatapoint@private{%
\the\t@pgfplots@tokc
\the\t@pgfplots@toka
% nothing is expanded here, only \t@pgfplots@tokb
\noexpand\t@pgfplots@toka=\noexpand\expandafter{\noexpand\pgfplotsretval}%
\noexpand\edef\noexpand\pgfplotsretval{{\noexpand\the\t@pgfplots@toka},\the\t@pgfplots@tokb}%
}%
% Step 2: modify the DESERIALIZATION method:
\let\pgfplotsaxisdeserializedatapointfrom@private@orig=\pgfplotsaxisdeserializedatapointfrom@private
\let\pgfplotsaxisdeserializedatapointfrom@private=\pgfplotsaxisdeserializedatapointfrom@private@withdeplist
\fi
%
\pgfkeysgetvalue{/pgfplots/execute for finished point}\pgfplots@loc@TMPa
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\else
\expandafter\def\expandafter\pgfplotsaxisserializedatapoint@private\expandafter{%
\pgfplotsaxisserializedatapoint@private
\pgfkeysvalueof{/pgfplots/execute for finished point}%
}%
\fi
}%
\def\pgfplots@prepare@visualization@depends@on#1\pgfplots@EOI{%
\pgfutil@in@\as{#1}%
\ifpgfutil@in@
% ok, we have the '\as<\macro>' syntax:
\pgfplots@prepare@visualization@depends@on@#1\pgfplots@EOI
\else
\pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value\pgfplots@EOI
\ifpgfutil@in@
% ok, then it should be 'value <\macro>'.
% extract the <\macro>:
\def\pgfplots@loc@TMPa value{\pgfplots@loc@TMPb}%
\def\pgfplots@loc@TMPb##1{\pgfplots@loc@TMPc ##1}% this step should remove leading white spaces
\def\pgfplots@loc@TMPc##1\pgfplots@EOI{%
% sanitize: check if ##1 is a defined macro:
\begingroup
\escapechar=-1
\xdef\pgfplots@glob@TMPa{\string##1}%
\endgroup
\pgfutil@ifundefined{\pgfplots@glob@TMPa}{%
\begingroup
\t@pgfplots@toka={##1}%
\pgfplotsthrow{invalid argument}
{\pgfplots@loc@TMPa}%
{Sorry, `visualization depends on=value <\string\macro>' expected a defined control sequence name instead of `\the\t@pgfplots@toka'. Please make sure `\the\t@pgfplots@toka' is a properly defined macro or use the `visualization depends on=value \string\as <\string\macro>' syntax instead}%
\pgfeov
\endgroup
}{%
\def\pgfplots@loc@TMPa{%
\pgfplots@prepare@visualization@depends@on@ value}%
\expandafter\pgfplots@loc@TMPa##1\as##1\pgfplots@EOI
}%
}%
\pgfplots@loc@TMPa#1\pgfplots@EOI
\else
% then, I expect '<\macro>'.
% sanitize: check if #1 is a defined macro:
\begingroup
\escapechar=-1
\xdef\pgfplots@glob@TMPa{\string#1}%
\endgroup
\pgfutil@ifundefined{\pgfplots@glob@TMPa}{%
\begingroup
\t@pgfplots@toka={#1}%
\pgfplotsthrow{invalid argument}
{\pgfplots@loc@TMPa}%
{Sorry, `visualization depends on' expected a defined control sequence name instead of `\the\t@pgfplots@toka'. Please make sure `\the\t@pgfplots@toka' is a properly defined macro or use the `visualization depends on= \string\as <\string\macro>' syntax instead}%
\pgfeov
\endgroup
}{%
\expandafter\pgfplots@prepare@visualization@depends@on@#1\as#1\pgfplots@EOI
}%
\fi
\fi
}%
\def\pgfplots@prepare@visualization@depends@on@#1\as#2\pgfplots@EOI{%
\pgfplots@prepare@visualization@depends@on@preparetype{#1}\as{#2}%
% prepare the serialization:
\t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb\noexpand#2{\csname\string#2@value\endcsname}}%
\t@pgfplots@tokc=\expandafter{\the\t@pgfplots@tokc\csname assign@\string#2\endcsname}%
}%
% task: define a macro '\csname assign@\string#2\endcsname' which, when executed,
% defines \csname\string#2@value\endcsname such that it expands
% to a the correct value.
\def\pgfplots@prepare@visualization@depends@on@preparetype#1\as#2{%
\pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value\pgfplots@EOI
\ifpgfutil@in@
\pgfplots@prepare@visualization@depends@on@preparetype@value#1\as{#2}% no braces here.
\else
\pgfplots@prepare@visualization@depends@on@preparetype@expr{#1}\as{#2}%
\fi
}%
\def\pgfplots@prepare@visualization@depends@on@preparetype@expr#1\as#2{%
\pgflibraryfpuifactive{%
\expandafter\def\csname assign@\string#2\endcsname{%
\pgfmathparse{#1}%
\pgfmathfloattofixed{\pgfmathresult}%
\expandafter\let\csname \string#2@value\endcsname=\pgfmathresult
}%
}{%
\expandafter\def\csname assign@\string#2\endcsname{%
\pgfmathparse{#1}%
\expandafter\let\csname \string#2@value\endcsname=\pgfmathresult
}%
}%
}
\def\pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value#2\pgfplots@EOI{%
\def\pgfplots@loc@TMPa{#1}%
\ifx\pgfplots@loc@TMPa\pgfutil@empty
\pgfutil@in@true
\else
\pgfutil@in@false
\fi
}%
\def\pgfplots@prepare@visualization@depends@on@preparetype@value value#1\as#2{%
% remove spaces from #1:
\pgfkeys@spdef\pgfplots@loc@TMPa{#1}%
%
% ok, prepare the value.
\def\pgfplots@loc@TMPb{#2}%
\ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb
% oh - a special case! We have value\macro\as\macro.
\expandafter\def\csname\string#2@value\endcsname{#2}%
%
% this is special; we do not need to EXECUTE assign@\string#2 to arrive at its value.
% But we need to define #2@value as that will be stored.
\expandafter\let\csname assign@\string#2\endcsname=\relax
\else
\begingroup
\t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}%
\t@pgfplots@tokb=\expandafter{\csname\string#2@value\endcsname}%
\xdef\pgfplots@glob@TMPa{%
\noexpand\def\the\t@pgfplots@tokb{\the\t@pgfplots@toka}%
}%
\endgroup
\expandafter\let\csname assign@\string#2\endcsname=\pgfplots@glob@TMPa
\fi
}
\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist#1{%
\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@#1\pgfplots@EOI
}%
\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@#1,{%
\pgfplotsaxisdeserializedatapointfrom@private@orig{#1}%
\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@
}%
\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@#1{%
\def\pgfplots@loc@TMPa{#1}%
\ifx\pgfplots@loc@TMPa\pgfplots@EOI
\else
\afterassignment\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@
\expandafter\def\expandafter#1%
\fi
}%
% PRECONDITION: must be called inside of
% \pgfplots@PREPARE@COORD@STREAM@end@.
%
% POSTCONDITION:
% assigns '/pgfplots/#1 coord sorting=[+-]'
% i.e. whether #1 (x or y or z) coordinates are in ascending (+) ordering or in
% descending order (-).
\def\pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting#1{%
\pgfplotscoordmath{#1}{if less than}
{\csname pgfplots@currentplot@firstcoord@#1\endcsname}%
{\csname pgfplots@currentplot@lastcoord@#1\endcsname}%
{\pgfkeyssetvalue{/pgfplots/#1 coord sorting}{+}}%
{\pgfkeyssetvalue{/pgfplots/#1 coord sorting}{-}}%
}%
% Defines the linear transformation macro \pgfplots@perpointmeta@trafo,
%
% phi : [meta_min,meta,max] -> [0,10^k]
%
% which operates on the per-point meta data (if any).
% The trafo will be skipped if there is no such data.
%
% The trafo is expected to prepare meta information before it is used
% as input to \pgfplotscolormapaccess (or
% \pgfplotscolormapdefinemappedcolor). Thus, the 10^k is chosen to be
% the same as \pgfplotscolormaprange (which is 1000 per default).
%
% If there is no data range (for example because meta information is
% not available or is not of numeric type), the trafo will simply
% copy the input argument symbolically.
%
% Note: it does not hurt to call it multiple times. It checks automatically whether it already is up-to-date.
\def\pgfplots@perpointmeta@preparetrafo{%
\def\pgfplotspointmetarangeexponent{1}% pre-fill
\pgfutil@ifundefined{pgfplots@perpointmeta@trafo}{%
\edef\pgfplots@loc@TMPa{\pgfplotscolormaprange}%
\ifnum\pgfplots@loc@TMPa=1000
\else
\pgfplots@error{LOGIC ERROR: sorry, I have hard-coded the assumption \string\pgfplotscolormaprange = 1000, but now it is \pgfplots@loc@TMPa.}%
\fi
%
\let\pgfplots@current@point@meta=\pgfutil@empty
\pgfutil@ifundefined{pgfplots@metamax}{\let\pgfplots@metamax=\pgfutil@empty}{}
\ifpgfplots@warn@for@filter@discards
\global\let\pgfplots@perpointmeta@unboundedwarning@stop=\relax
\def\pgfplots@perpointmeta@unboundedwarning##1{%
\ifx\pgfplots@perpointmeta@unboundedwarning@stop\relax
\begingroup
\pgfplotscoordmath{meta}{tostring}{##1}%
\pgfplotswarning{point meta unbounded}{\pgfmathresult}{##1}\pgfeov
\endgroup
\gdef\pgfplots@perpointmeta@unboundedwarning@stop{1}%
\fi
}%
\else
\def\pgfplots@perpointmeta@unboundedwarning##1{}%
\fi
\if d\pgfplots@colormap@access
% colormap access=direct
\def\pgfplots@perpointmeta@trafo##1{%
\pgfplotscoordmath{meta}{if is}{##1}{u}{%
\pgfplotscolorzero{\pgfplotscolormapcolorcompsof{\pgfkeysvalueof{/pgfplots/colormap name}}}%
\pgfplots@perpointmeta@unboundedwarning{##1}%
}{%
\pgfplotscoordmath{meta}{tofixed}{##1}%
\pgfplotscolormapgetindex{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/colormap name}}%
}%
}%
\def\pgfplots@perpointmeta@traforange{0:0}%
\edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}%
\else
% colormap access=map|piecewise constant
\ifx\pgfplots@metamax\pgfutil@empty
\def\pgfplots@perpointmeta@trafo##1{%
\pgfplotscoordmath{meta}{if is}{##1}{u}
{%
\def\pgfmathresult{0}%
\pgfplots@perpointmeta@unboundedwarning{##1}%
}{%
\pgfplotscoordmath{meta}{tofixed}{##1}%
}%
}%
\def\pgfplots@perpointmeta@traforange{0:1000}%
\edef\pgfplotspointmetarange{0:1000}%
\else
% The transformation is
%
% phi(m) = ( m- meta_min) * 1000/ (meta_max-meta_min).
%
% -> precompute the scaling factor!
\if\pgfplots@perpointmeta@rel@choice0%
% point meta rel=axis wide:
\pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@axiswide@}%
\else
\pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@}%
\fi
\fi
\fi
\edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}%
}{}%
}%
% Employs \csname #1metamin\endcsname and its metamax counterpart to
% initialize the trafo.
%
% This unifies the approaches for \pgfplots@axiswide@metamax and
% \pgfplots@metamax.
\def\pgfplots@perpointmeta@preparetrafo@initfrom#1{%
\edef\pgfplotspointmetarange{\csname #1metamin\endcsname:\csname #1metamax\endcsname}%
% Now, prepare the trafo as such.
% It assigns \pgfmathresult (in fixed point).
\ifpgfplots@LUA@backend@supported
\def\pgfplots@perpointmeta@trafo##1{%
\edef\pgfmathresult{%
\pgfplotsutil@directlua{%
pgfplots.texPerpointMetaTrafo("\pgfplots@current@point@meta")
}%
}%
}%
\else
\def\pgfplots@perpointmeta@trafo##1{%
\pgfplotscoordmath{meta}{if is}{##1}{u}{%
\def\pgfmathresult{0}%
\pgfplots@perpointmeta@unboundedwarning{##1}%
}{%
\pgfplotscoordmath{meta}{op}{subtract}{{##1}{\csname #1metamin\endcsname}}%
\pgfplotscoordmath{meta}{op}{multiply}{{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}}%
\pgfplots@perpointmeta@trafo@clipresult
\pgfplotscoordmath{meta}{tofixed}{\pgfmathresult}%
}%
}%
\pgfplotscoordmath{meta}{op}{subtract}{{\csname #1metamax\endcsname}{\csname #1metamin\endcsname}}%
\let\pgfplots@loc@TMPa=\pgfmathresult
\pgfplotscoordmath{meta}{zero}%
\let\pgfplots@perpointmeta@lowerrange=\pgfmathresult
\pgfplotscoordmath{meta}{parsenumber}{1000}%
\let\pgfplots@perpointmeta@upperrange=\pgfmathresult
\pgfplotscoordmath{meta}{op}{divide}{{\pgfmathresult}{\pgfplots@loc@TMPa}}%
\let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult
\fi
%
% Expands to the transformation range as 'a:b':
\def\pgfplots@perpointmeta@traforange{0:1000}%
%
\expandafter\let\expandafter\pgfplots@loc@TMPa\csname #1metamax\endcsname
\pgfplotscoordmath{meta}{tostring}{\pgfplots@loc@TMPa}%
\pgfmathfloatparsenumber\pgfmathresult
\pgfmathfloatgetexponent\pgfmathresult\c@pgf@countd
\edef\pgfplotspointmetarangeexponent{\the\c@pgf@countd}%
}
\def\pgfplots@perpointmeta@trafo@clipresult{%
\let\pgfplots@loc@TMPa=\pgfmathresult
\pgfplotscoordmath{meta}{if less than}{\pgfplots@loc@TMPa}{\pgfplots@perpointmeta@upperrange}{%
\pgfplotscoordmath{meta}{if less than}{\pgfplots@loc@TMPa}{\pgfplots@perpointmeta@lowerrange}{%
\let\pgfmathresult=\pgfplots@perpointmeta@lowerrange
}{%
\let\pgfmathresult=\pgfplots@loc@TMPa
}%
}{%
\let\pgfmathresult=\pgfplots@perpointmeta@upperrange
}%
}%
% define it globally - this simplifies some mesh plots.
\pgfplotscoordmath{meta}{one}%
\let\pgfplotspointmeta=\pgfmathresult
\def\pgfplotspointmetatransformed{1000}% use the maximum because it is usually divided by 1000
% A command which is readily available during the visualization phase of each plot.
%
% It takes existing point meta data and transforms it, i.e. it defines
% \pgfplotspointmetatransformed.
%
% The command won't be invoked automatically, it is task of a plot
% handler to decide if it is needed. It's application is relatively
% fast, however.
%
% PRECONDITION:
% - point meta has been set up during the survey phase (i.e. the
% /pgfplots/point meta!=none),
% - there *is* point meta data for the current data point.
%
% POSTCONDITION:
% - the macros \pgfplotspointmeta and \pgfplotspointmetatransformed
% are defined.
%
% @see also \pgfplotsaxisifhaspointmeta
\def\pgfplotsaxisvisphasetransformpointmeta{%
\if1\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname
% symbolic point meta may be empty.
\let\pgfplotspointmeta=\pgfplots@current@point@meta
\let\pgfplotspointmetatransformed=\pgfplotspointmeta
\else
% numeric point meta may NOT be empty.
\ifx\pgfplots@current@point@meta\pgfutil@empty%
\pgfplots@error{%
could not access the 'point meta=\csname pgfpmeta@\pgfplotspointmetainputhandler @tostring\endcsname' for coordinate \the\c@pgfplots@coordindex: %
its value is empty. %
\if1\csname pgfpmeta@\pgfplotspointmetainputhandler @explicitinput\endcsname%
\pgfplots@addplot@point@meta@description@of@explicit@value
\else
Please ensure that the value exists and is not empty
\fi
}%
\pgfplotscoordmath{meta}{one}%
\let\pgfplotspointmeta=\pgfmathresult
\def\pgfplotspointmetatransformed{1.0}%
\else
% prepare arguments:
\let\pgfplotspointmeta=\pgfplots@current@point@meta
\pgfplots@perpointmeta@trafo{\pgfplotspointmeta}%
\let\pgfplotspointmetatransformed=\pgfmathresult
\fi
\fi
}%
\def\pgfplots@addplot@point@meta@description@of@explicit@value{%
Please use an input stream which provides 'explicit point meta' like \string\addplot\space table or \string\addplot\space coordinates
}
\def\pgfplotsaxisvisphasetransformpointmetaifany{%
\pgfplotsaxisifhaspointmeta{\pgfplotsaxisvisphasetransformpointmeta}{}%
}
% A looping method which applies
% \pgfplots@coord@stream@start
% for each coordinate '(x,y)' or '(x,y) +- (ex,ey)',
% assign \pgfplots@current@point@[xyz]
% assign \pgfplots@current@point@[xyz]@error (if in argument list)
% assign \pgfplots@current@point@meta
% call \pgfplots@coord@stream@coord
% \pgfplots@coord@stream@end
%
% #1 a sequence of coordinates of the form
% '(x,y)' or '(x,y,z)'
% or
% '(x,y[,z]) +- (ex,ey)'
% or
% '(x,y[,z]) += (ex+,ey+) -= (ex-,ey-)'
% or
% '(x,y) [meta]'
% or
% '(x,y) +- (ex,ey) [meta]'
% separated by white-space.
%
\long\def\pgfplots@coord@stream@foreach#1{%
\pgfplots@coord@stream@start
\pgfplotsscanlinelengthinitzero
\pgfplots@foreach@plot@coord@ITERATE#1\pgfplots@EOI%
\pgfplotsscanlinelengthcleanup
\pgfplots@coord@stream@end
}%
\begingroup
\def\\{\global\let\pgfplots@let@space@token= } \\ % now, \pgfplots@let@space@token is a space token
\endgroup
% A looping command to loop through plot coordinates.
% For every point, \pgfplots@coord@stream@coord will be invoked.
%
% No scoping is used during this operation, so you can access outer
% variables.
\def\pgfplots@foreach@plot@coord@ITERATE{%
\futurelet\pgfplots@foreach@plot@coord@ITERATE@tok\pgfplots@foreach@plot@coord@ITERATE@
}%
\long\def\pgfplots@foreach@plot@coord@ITERATE@#1{%
\ifx\pgfplots@foreach@plot@coord@ITERATE@tok(%
\pgfplotsscanlinelengthincrease
\let\pgfplots@loop@next=\pgfplots@foreach@plot@coord@NEXT%
\else
\ifx\pgfplots@foreach@plot@coord@ITERATE@tok\pgfplots@let@space@token
\def\pgfplots@loop@next{\pgfplots@foreach@plot@coord@ITERATE#1}%
\else
\ifx\pgfplots@foreach@plot@coord@ITERATE@tok\pgfplots@EOI
% ok, do nothing more
\let\pgfplots@loop@next=\relax
\else
\ifx\pgfplots@foreach@plot@coord@ITERATE@tok\par
\pgfplotsscanlinecomplete
\let\pgfplots@loop@next=\pgfplots@foreach@plot@coord@ITERATE
\else
\if\noexpand\pgfplots@foreach@plot@coord@ITERATE@tok\noexpand\anymacro
% Ah. #1 has the same character (!) code as \anymacro,
% that means it is a macro! Expand it:
\def\pgfplots@loop@next{\expandafter\pgfplots@foreach@plot@coord@ITERATE#1}%
\else
\def\pgfplots@loop@next{\pgfplots@foreach@plot@coord@error#1}%
\fi
\fi
\fi
\fi
\fi
\pgfplots@loop@next
}
\long\def\pgfplots@foreach@plot@coord@error#1\pgfplots@EOI{%
\def\pgfplots@loc@TMPa{#1}%
\pgfplots@command@to@string\pgfplots@loc@TMPa\pgfplots@loc@TMPa
\pgfplots@error{Sorry, I could not read the plot coordinates near '\pgfplots@loc@TMPa'. Please check for format mistakes}%
}%
\def\pgfplots@foreach@plot@coord@NEXT#1,#2){%
\ifpgfplots@plot@coords@mathparser
\pgfmathparse{#1}\let\pgfplots@current@point@x=\pgfmathresult
\pgfmathparse{#2}\let\pgfplots@current@point@y=\pgfmathresult
\else
\def\pgfplots@current@point@x{#1}%
\def\pgfplots@current@point@y{#2}%
\fi
\let\pgfplots@current@point@error@x@plus=\pgfutil@empty
\let\pgfplots@current@point@error@x@minus=\pgfutil@empty
\let\pgfplots@current@point@error@y@plus=\pgfutil@empty
\let\pgfplots@current@point@error@y@minus=\pgfutil@empty
\let\pgfplots@current@point@meta=\pgfutil@empty
\pgfplots@foreach@plot@coord@NEXT@cont
}
\def\pgfplots@foreach@plot@coord@NEXT@cont{%
\pgfutil@ifnextchar+{%
\pgfplots@foreach@plot@coord@NEXT@plus%
}{%
\pgfutil@ifnextchar-{%
\pgfplots@foreach@plot@coord@NEXT@minus%
}{%
\pgfutil@ifnextchar[{%
\pgfplots@foreach@plot@coord@NEXT@meta
}{%
\pgfplots@coord@stream@coord
\pgfplots@foreach@plot@coord@ITERATE
}%
}%
}%
}
\def\pgfplots@foreach@plot@coord@NEXT@meta[#1]{%
\def\pgfplots@current@point@meta{#1}%
\pgfplots@coord@stream@coord
\pgfplots@foreach@plot@coord@ITERATE
}%
\def\pgfplots@foreach@plot@coord@NEXT@plus+{%
\pgfutil@ifnextchar={%
\pgfplots@foreach@plot@coord@NEXT@pluseq%
}{%
\pgfplots@foreach@plot@coord@NEXT@plusminus%
}%
}
\def\pgfplots@foreach@plot@coord@NEXT@minus-=#1({%
\def\pgfplots@foreach@plot@coord@state{-}%
\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@
}
\def\pgfplots@foreach@plot@coord@NEXT@pluseq=#1({%
\def\pgfplots@foreach@plot@coord@state{+}%
\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@
}
\def\pgfplots@foreach@plot@coord@NEXT@plusminus-#1({%
\def\pgfplots@foreach@plot@coord@state{B}%
\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@
}
% processing something like '(x,y) +- (error_x,error_y)'
\def\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@#1,#2){%
\ifpgfplots@plot@coords@mathparser
\pgfmathparse{#1}%
\let\pgfplots@loc@TMPb=\pgfmathresult
\pgfmathparse{#2}%
\let\pgfplots@loc@TMPc=\pgfmathresult
\else
\def\pgfplots@loc@TMPb{#1}%
\def\pgfplots@loc@TMPc{#2}%
\fi
%
\if +\pgfplots@foreach@plot@coord@state
% ah, it was a "+=" item:
\let\pgfplots@current@point@error@x@plus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@plus=\pgfplots@loc@TMPc
\else
\if -\pgfplots@foreach@plot@coord@state
% ah, it was a "-=" item:
\let\pgfplots@current@point@error@x@minus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@minus=\pgfplots@loc@TMPc
\else
% ah, it was a "+-" item:
\let\pgfplots@current@point@error@x@plus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@x@minus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@plus=\pgfplots@loc@TMPc
\let\pgfplots@current@point@error@y@minus=\pgfplots@loc@TMPc
\fi
\fi
%
\pgfplots@foreach@plot@coord@NEXT@cont
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
% The same for three dim coords:
\long\def\pgfplots@coord@stream@foreach@threedim#1{%
\pgfplots@coord@stream@start
\pgfplotsscanlinelengthinitzero
\pgfplots@foreach@plot@coord@threedim@ITERATE#1\pgfplots@EOI%
\pgfplotsscanlinelengthcleanup
\pgfplots@coord@stream@end
}%
\def\pgfplots@foreach@plot@coord@threedim@ITERATE{%
\futurelet\pgfplots@foreach@plot@coord@threedim@ITERATE@tok\pgfplots@foreach@plot@coord@threedim@ITERATE@
}%
\long\def\pgfplots@foreach@plot@coord@threedim@ITERATE@#1{%
\ifx\pgfplots@foreach@plot@coord@threedim@ITERATE@tok(%
\pgfplotsscanlinelengthincrease
\let\pgfplots@loop@next=\pgfplots@foreach@plot@coord@threedim@NEXT%
\else
\ifx\pgfplots@foreach@plot@coord@threedim@ITERATE@tok\pgfplots@let@space@token
\def\pgfplots@loop@next{\pgfplots@foreach@plot@coord@threedim@ITERATE#1}%
\else
\ifx\pgfplots@foreach@plot@coord@threedim@ITERATE@tok\pgfplots@EOI
% ok, do nothing more
\let\pgfplots@loop@next=\relax
\else
\ifx\pgfplots@foreach@plot@coord@threedim@ITERATE@tok\par
\pgfplotsscanlinecomplete
\let\pgfplots@loop@next=\pgfplots@foreach@plot@coord@threedim@ITERATE
\else
\if\noexpand\pgfplots@foreach@plot@coord@threedim@ITERATE@tok\noexpand\anymacro
% Ah. #1 has the same character (!) code as \anymacro,
% that means it is a macro! Expand it:
\def\pgfplots@loop@next{\expandafter\pgfplots@foreach@plot@coord@threedim@ITERATE#1}%
\else
\def\pgfplots@loop@next{\pgfplots@foreach@plot@coord@error#1}%
\fi
\fi
\fi
\fi
\fi
\pgfplots@loop@next
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT#1,#2,#3){
\ifpgfplots@plot@coords@mathparser
\pgfmathparse{#1}\let\pgfplots@current@point@x=\pgfmathresult
\pgfmathparse{#2}\let\pgfplots@current@point@y=\pgfmathresult
\pgfmathparse{#3}\let\pgfplots@current@point@z=\pgfmathresult
\else
\def\pgfplots@current@point@x{#1}%
\def\pgfplots@current@point@y{#2}%
\def\pgfplots@current@point@z{#3}%
\fi
\let\pgfplots@current@point@error@x@plus=\pgfutil@empty
\let\pgfplots@current@point@error@x@minus=\pgfutil@empty
\let\pgfplots@current@point@error@y@plus=\pgfutil@empty
\let\pgfplots@current@point@error@y@minus=\pgfutil@empty
\let\pgfplots@current@point@error@z@plus=\pgfutil@empty
\let\pgfplots@current@point@error@z@minus=\pgfutil@empty
%
\let\pgfplots@current@point@meta=\pgfutil@empty
%
\pgfplots@foreach@plot@coord@threedim@NEXT@cont
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT@cont{%
\pgfutil@ifnextchar+{%
\pgfplots@foreach@plot@coord@threedim@NEXT@plus%
}{%
\pgfutil@ifnextchar-{%
\pgfplots@foreach@plot@coord@threedim@NEXT@minus%
}{%
\pgfutil@ifnextchar[{%
\pgfplots@foreach@plot@coord@threedim@NEXT@meta
}{%
\pgfplots@coord@stream@coord
\pgfplots@foreach@plot@coord@threedim@ITERATE
}%
}%
}%
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT@meta[#1]{%
\def\pgfplots@current@point@meta{#1}%
\pgfplots@coord@stream@coord
\pgfplots@foreach@plot@coord@threedim@ITERATE
}%
\def\pgfplots@foreach@plot@coord@threedim@NEXT@plus+{%
\pgfutil@ifnextchar={%
\pgfplots@foreach@plot@coord@threedim@NEXT@pluseq%
}{%
\pgfplots@foreach@plot@coord@threedim@NEXT@plusminus%
}%
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT@minus-=#1({%
\def\pgfplots@foreach@plot@coord@state{-}%
\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT@pluseq=#1({%
\def\pgfplots@foreach@plot@coord@state{+}%
\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@
}
\def\pgfplots@foreach@plot@coord@threedim@NEXT@plusminus-#1({%
\def\pgfplots@foreach@plot@coord@state{B}%
\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@
}
% processing something like '(x,y) +- (error_x,error_y)'
\def\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@#1,#2,#3){%
\ifpgfplots@plot@coords@mathparser
\pgfmathparse{#1}\let\pgfplots@loc@TMPb=\pgfmathresult
\pgfmathparse{#2}\let\pgfplots@loc@TMPc=\pgfmathresult
\pgfmathparse{#3}\let\pgfplots@loc@TMPd=\pgfmathresult
\else
\def\pgfplots@loc@TMPb{#1}%
\def\pgfplots@loc@TMPc{#2}%
\def\pgfplots@loc@TMPd{#3}%
\fi
%
\if +\pgfplots@foreach@plot@coord@state
% ah, it was a "+=" item:
\let\pgfplots@current@point@error@x@plus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@plus=\pgfplots@loc@TMPc
\let\pgfplots@current@point@error@z@plus=\pgfplots@loc@TMPd
\else
\if -\pgfplots@foreach@plot@coord@state
% ah, it was a "-=" item:
\let\pgfplots@current@point@error@x@minus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@minus=\pgfplots@loc@TMPc
\let\pgfplots@current@point@error@z@minus=\pgfplots@loc@TMPd
\else
% ah, it was a "+-" item:
\let\pgfplots@current@point@error@x@plus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@x@minus=\pgfplots@loc@TMPb
\let\pgfplots@current@point@error@y@plus=\pgfplots@loc@TMPc
\let\pgfplots@current@point@error@y@minus=\pgfplots@loc@TMPc
\let\pgfplots@current@point@error@z@plus=\pgfplots@loc@TMPd
\let\pgfplots@current@point@error@z@minus=\pgfplots@loc@TMPd
\fi
\fi
%
\pgfplots@foreach@plot@coord@threedim@NEXT@cont
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%
% A coordinate stream which works like this:
%
% -------------
% \pgfplots@coord@stream@start
%
% foreach encoded coordinate:
% \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded{}%
% \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced{{}}% note the extra braces.
% \pgfplotsaxisdeserializedatapointfrom{}
% \pgfplots@coord@stream@coord
%
% \pgfplots@coord@stream@end
% -------------
%
% The format of #1 is
% {}{}...{}
% Each data point is decoded with
% \pgfplotsaxisserializedatapoint
% and then, \pgfplots@coord@stream@coord will be called.
\long\def\pgfplots@coord@stream@foreach@NORMALIZED#1{%
\pgfplots@coord@stream@start
\pgfplotscoordstream@firstlast@init
\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1\pgfplots@EOI%
\pgfplots@coord@stream@end
}%
% No scoping is used during this operation, so you can access outer
% variables.
\def\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1{%
\def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded{#1}%
\ifx\pgfplots@coord@stream@foreach@NORMALIZED@curencoded\pgfplots@EOI
\else
\def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced{{#1}}%
\pgfplotsaxisdeserializedatapointfrom{#1}%
\pgfplots@coord@stream@coord
\pgfplotsplothandlerifcurrentpointcanbefirstlast{%
\pgfplotscoordstream@firstlast@update
}{}%
\expandafter\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE
\fi
}
% A common routine which resets internal data structures for the
% survey phase, i.e. it is the shared implementation for all \addplot
% variations.
%
% It takes all options which are provided to \addplot, sets them (at
% least partially) and remembers them for the command serialization.
%
% #1: arguments to \addplot plot[#1]
% -> these are called 'behavior' options in the manual; they are set
% immediately.
%
% PRECONDITION:
% \pgfplots@addplotimpl@plot@withoptions has already been invoked
%
% POSTCONDITION:
% - internal datastructures are initialised (coordinate indexing, fpu)
% - all keys which are required for the current plot are determined
% (and set if necessary).
% They are stored into
% \pgfplots@addplot@survey@@optionlist.
%
\def\pgfplots@start@plot@with@behavioroptions#1{%
%\begingroup%<-- has been moved to \pgfplots@addplotimpl@plot@withoptions
\c@pgfplots@coordindex=0
\def\pgfplots@current@point@coordindex{\the\c@pgfplots@coordindex}% can be used inside of coordinate filters.
\def\coordindex{\pgfplots@current@point@coordindex}% valid inside of \addplot
\def\pgfplots@addplot@running{1}%
%
\def\pgfplots@colorbar@set@src{0}%
\pgfkeysdef{/pgfplots/colorbar source}{%
\pgfplotsutilifstringequal{##1}{true}{%
\def\pgfplots@colorbar@set@src{1}%
}{%
\pgfplotsutilifstringequal{##1}{false}{%
\def\pgfplots@colorbar@set@src{0}%
}{%
\pgfplots@error{Sorry, I don't know the value `colorbar source={##1}' and I am going to ignore it. Maybe you misspelled it?}%
}%
}%
}%
%
\pgfplots@start@plot@with@behavioroptions@setkeys{#1}%
%
% enable FPU after any \pgfplotsset operations. Otherwise things like
% linewidth=... which use the math parser might fail.
\ifpgfplots@usefpu
\pgfkeys{/pgf/fpu=true,%
/pgf/fpu/output format=float,%
}%
\fi
%
% make sure it is reset, just in case it is not supported by the
% input method.
\pgfplotsscanlinelengthinitzero
%
\pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler
\pgfplotsresetplothandler
\pgfplots@basiclevel@plothandler
%
\pgfplots@countplots@init
%
% hooks:
\pgfkeysvalueof{/pgfplots/execute at begin plot@@}%
\pgfkeysvalueof{/pgfplots/execute at begin plot}%
%
\if1\pgfplots@colorbar@set@src
\t@pgfplots@tokc={/pgfplots/point meta rel=per plot}%
\t@pgfplots@toka=\expandafter{\pgfplots@addplot@survey@@optionlist}%
\edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc,\the\t@pgfplots@toka}%
\fi
%
%
\pgfplots@validate@plot@domain@arguments
}
\def\pgfplots@disable@non@survey@keys{%
%
% this here would try to compute something. DON'T DO THIS DURING
% SURVEY!
\pgfkeysdef{/tikz/name intersections}{}%
\pgfkeysdef{/tikz/intersection segments}{}%
%
}%
\def\pgfplots@start@plot@with@behavioroptions@setkeys#1{%
% these styles may contain behavior options (error bars,
% samples,... ) activate them!
%
% As of february 20, 2009, #1 will contain BOTH, /pgfplots
% and /tikz options. The /tikz ones are primarily for drawing
% and are UNIMPORTANT at this stage of processing.
% In fact, transparency etc. will only confuse everything.
%
% So: ignore them and set only /pgfplots keys here:
% This may actually redefine styles, for example
% \addplot[every mark/.append style={}] will use
% /pgfplots/every mark/.append style.
% But that doesn't hurt here.
%
% there are some exceptions like /tikz/id etc. These
% exceptions need special styles in the /pgfplots root - or I
% need to change the .unknown handler. See the available
% compatibility styles!
%
% \pgfkeysdef{/pgfplots/.unknown}{%
%\message{In \string\addplot[#1]: I am silently ignoring key `\pgfkeyscurrentkeyRAW' during the preparation phase.}%
% }%
% ATTENTION:
% as of january 30, 2010, I will set /tikz keys as well. This won't hurt
% too much, I hope... there are no graphics operations anyway. But it *is*
% necessary since I *need* the plot handler for the new version. And the plot
% handler is, most likely, a /tikz key.
%
% it is possible that '#1' contains 'forget plot'. So, we need to
% set the options before checking \ifpgfplots@curplot@isirrelevant:
\pgfplots@disable@non@survey@keys
\pgfplotsset{/pgfplots/every axis plot,#1}%
%
\ifpgfplots@curplot@isirrelevant
\def\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every forget plot}%
\pgfplotsset{/pgfplots/every forget plot,/pgfplots/every axis plot post}%
\else
\edef\pgfplots@addplot@survey@@optionlist{%
/pgfplots/every axis plot,%
/pgfplots/every axis plot except legend,%
/pgfplots/every axis plot no \the\pgfplots@numplots/.try}%
\pgfplotsset{%
/pgfplots/every axis plot except legend,
/pgfplots/every axis plot no \the\pgfplots@numplots/.try,%
/pgfplots/every axis plot post}%
\fi
%
\t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1'
\edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}%
%
\pgfplots@set@trig@format@plots
}
\long\def\pgfplotssurveyphaseaddoptionsbeforesurveybegins#1{%
\pgfplotsset{%
/pgfplots/execute at end survey/.add={}{%
\t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1'
\edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}%
},%
#1%
}%
}%
\long\def\pgfplotsplothandlersurveyaddoptions#1{%
\t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1'
\edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}%
\pgfplotsset{#1}%
}%
% The main interface to draw a plot into an axis.
%
% Usage:
% \addplot
% plot coordinates {
% (0,0)
% (1,1)
% };
%
% or
%
% \addplot[color=blue,mark=*]
% plot coordinates {
% (0,0)
% (1,1)
% };
%
% or one of the other input types.
%
% The first syntax will use the next plot specification in the list
% \autoplotspeclist
% and the first will use blue color and * markers.
%
% \addplot [