diff options
Diffstat (limited to 'tex/.texmf/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex')
-rw-r--r-- | tex/.texmf/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex | 9152 |
1 files changed, 9152 insertions, 0 deletions
diff --git a/tex/.texmf/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex b/tex/.texmf/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex new file mode 100644 index 0000000..d370f84 --- /dev/null +++ b/tex/.texmf/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex @@ -0,0 +1,9152 @@ +%-------------------------------------------- +% +% 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 <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- + +% 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 (<x>,<y>) 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{<axis>}{<coordinate>} +% or +% \pgfplotspointticklabelcs[<default shift>]{<axis>}{<coordinate>} +% +% Yields a point in the '<axis>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 <default shift> 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 <relative coord> or <relative coord>,<shift>) +% +% @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{<lower z limit>}{0} +% +% -> +% \pgfplotspointonorientedsurfaceA = x +% \pgfplotspointonorientedsurfaceB = y +% \pgfplotspointonorientedsurfaceN = z +% \pgfplotspointonorientedsurfacespec = {ab0} +% \pgfplotspointonorientedsurfacespecunordered = {vv0} +% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{3}{4}{<lower z limit>} +% +% \pgfplotspointonorientedsurfaceabsetupfor yxz +% \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} +% -> +% \pgfplotspointonorientedsurfaceA = y +% \pgfplotspointonorientedsurfaceB = x +% \pgfplotspointonorientedsurfaceN = z +% \pgfplotspointonorientedsurfacespec = {ba0} +% \pgfplotspointonorientedsurfacespecunordered = {vv0} +% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{4}{3}{<lower z limit>} +% +% @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}} +% {<shift in B direction of #3>} +% +% 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{<lower z limit>}{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{<axis three char string>}{<transformed coordinate>} +\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 +\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{% + \if v#1% + \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotspointonorientedsurfaceabsetupforsety{\pgfplots@loc@TMPa}{#2}% + % + \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 + \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 + \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}% + % +%\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, +} +% Installs a rotation transformation matrix such that labels or +% whatever are aligned precisely in direction of one of the two/three +% coordinate directions. +% +% \pgfplotstransformtoaxisdirection[<options>]{<axis char>} +% +% <axis char>: 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 + % + % + % 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% {<start>}{<end>} -> computes <end> - <start> + {\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}, + 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 ##2\else ##3\fi + \else + \if##2+\ifdim##1pt>0pt ##2\else ##3\fi + \else + \if##2-\ifdim##1pt<0pt ##2\else ##3\fi + \else + \def\pgfplots@loc@TMPd{##1}\ifx\pgfplots@loc@TMPd\pgfutil@empty ##2\else ##3\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@@<name>@<function> + % 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}},% + % + % 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{<id>} will be + % invoked where <id> is the argument to + % \pgfplotscoordmath{<id>}... + 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<suffix><op>@\endcsname + % exists. Example: <suffix>=float --> \pgfmathfloatmultiply@ for <op>=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}% + \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}{{<a>}{<b>}} +% \pgfplotscoordmath {x}{parsenumber}{<a>} +\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 +}% + +% 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{}% + \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{}% + \edef\pgfplotsdeclarepointmetasource@{#1}% + \pgfqkeys{/pgfplots/@declare point meta src}{#2}% +}% +\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}},% +}% + +% 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")}% + }% + }, + 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}% + }, +}% +\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}% + }, + 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 +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinecomplete +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinecomplete +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \pgfplotsscanlinelengthincrease +% <process point> +% \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 + \noexpand\pgfplotsplothandlernotifyscanlinecomplete + }% + \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 + \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 + \fi + \else + \ifnum\pgfplots@scanlinelength=-2 + \else + \edef\pgfplots@scanlinelength{\the\c@pgfplots@scanlineindex}% + \fi + \fi + \c@pgfplots@scanlineindex=0 +} +\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{% + % 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 + % + \let\pgfplotsscanlinelength@nan@pendingwork=\relax + }% + \fi + \def\pgfplotsscanlinelength@nan@isfirst{1}% +}% +\let\pgfplotsscanlinelength@nan@cleanup=\relax +% +% ------------------------------------------------------------------------------- + + +\def\pgfplotsaxisfilteredcoordsaway{0}% +\def\pgfplotsaxisplothasjumps{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 <options> +% 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}% + % + % 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\ifx\noexpand\pgfplots@current@point@meta\noexpand\pgfutil@empty + \noexpand\else + \the\t@pgfplots@tokb + \noexpand\fi + }% + \def\pgfplotsaxisupdatelimitsforpointmeta##1{% + \begingroup + \def\pgfplots@current@point@meta{##1}% + \pgfplots@set@perpointmeta@limits + \endgroup + }% + \else + % there is no point meta: + \global\let\pgfplots@metamin=\pgfutil@empty + \global\let\pgfplots@metamax=\pgfutil@empty + \let\pgfplots@set@perpointmeta@limits=\relax + \def\pgfplotsaxisupdatelimitsforpointmeta##1{}% + \fi +}% +% 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] + % <any paths for error bars> + % \endscope + % \draw plot coordinates {...}; + % to share plot specifications between error bars and plot + % coordinates. Unfortunately, it is NOT sufficient to use + % \tikzset + \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 + \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\pgfkeyssetvalue{/pgfplots/on layer}{\pgfkeysvalueof{/pgfplots/on layer}}% + \noexpand\def\noexpand\pgfplots@serialized@afterpath{\the\t@pgfplots@tokc}% + }% + {% 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}% + \ifpgfplots@curplot@isirrelevant + % for \label commands: + \expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}% + \else + \expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@addplot@survey@@optionlist}% + \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 + \pgfplots@LUA@survey@log@deactivation{color map access=direct not supported (yet)}% + \pgfplots@LUA@backend@supportedfalse + \fi + % + \ifpgfplots@LUA@backend@supported + \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 (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[\the\pgfplots@numplots+1] = plothandler;^^J% + gca.currentPlotHandler = plothandler;^^J% + plothandler:surveystart();^^J% + }% +%\message{Executing ^^J\pgfplots@loc@TMPa^^J^^J}% + \directlua{\pgfplots@loc@TMPa}% + \endgroup + \fi + \fi +}% + +\def\pgfplots@LUA@survey@point{% + \directlua{pgfplots.texSurveyPoint("\pgfplots@current@point@x","\pgfplots@current@point@y","\pgfplots@current@point@z","\pgfplots@current@point@meta")}% +}% + +\def\pgfplots@LUA@survey@end{% + % LUA defines a couple of TeX macros here... + \directlua{pgfplots.texSurveyEnd()}% + % + \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{% + \directlua{pgfplots.texGetSurveyedCoordsToPgfplots()}% + }% + \else + % visualize using LUA! ... and acquire the coordinates. + \expandafter\def\expandafter\pgfplots@stored@current@data\expandafter{% + \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 + \pgfplotsaxisserializedatapoint@private + \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, {<value2>}\as \macro2,...} + % -> + % {<original private data>}<\macro1>{<value1>}<\macro2>{<value2>}...<\macroN>{<valueN>} + % + % prepare + % \t@pgfplots@tokb={<\macro1>{<value1>}<\macro2>{<value2>}...<\macroN>{<valueN>}} + \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 '<content>\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 <content> \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=<expression> \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 m\pgfplots@colormap@access + % colormap access=map + \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 + \else + % colormap access=direct + \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:0}% + \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% + \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{% + \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' (used for example by scatter plots and color maps). Maybe you need to add '\string\addplot[point meta=y]' or something like that?}% + \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\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{<encoded data>}% +% \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced{{<encoded data>}}% note the extra braces. +% \pgfplotsaxisdeserializedatapointfrom{<encoded data>} +% \pgfplots@coord@stream@coord +% +% \pgfplots@coord@stream@end +% ------------- +% +% The format of #1 is +% {<datapoint>}{<datapoint>}...{<datapoint>} +% 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}% + \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 no \the\pgfplots@numplots/.try}% + \pgfplotsset{/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 [<style options>] plot[<behavior options>] <input type and args> <post plot path> ; +% \addplot3[<style options>] plot[<behavior options>] <input type and args> <post plot path> ; +% +% The complete accumulation is done GLOBALLY. It should be safe to put +% '\addplot' into local groups. +% +% +% The linespec. will be used in the legend. +% +% Low-level implementation: +% +% \pgfplots@addplot +% \pgfplots@addplotimpl +% \pgfplots@start@plot@with@behavioroptions <--- \begingroup +% ... +% ... remember options GLOBALLY +% ... update limits GLOBALLY +% ... \pgfplots@addplot@enqueue@coords GLOBALLY +% ... +% \pgfplots@end@plot <--- \endgroup +\def\pgfplots@addplot{% + \pgfutil@ifnextchar3{% + \pgfplots@curplot@threedimtrue + \pgfplots@addplot@three + }{% + \pgfplots@curplot@threedimfalse + \pgfplots@addplot@ + }% +} +\def\pgfplots@addplot@three3{\pgfplots@addplot@}% +\def\pgfplots@addplot@{% + \pgfutil@ifnextchar+{% + \pgfplots@getautoplotspec into\nextplotspec + \pgfplots@addplotimplAPPEND + }{% + \pgfutil@ifnextchar[{% + \pgfplots@addplotimpl% + }{% + \pgfplots@getautoplotspec into\nextplotspec + % the space after ']' is required here: + % FIXME: + % - \addplot[]plot coordinates is NOT allowed!? + \expandafter\pgfplots@addplotimpl\expandafter[\nextplotspec]% + }% + }% +} + +\def\pgfplots@addplotimplAPPEND+{\pgfutil@ifnextchar[{\pgfplots@addplotimplAPPEND@}{\pgfplots@addplotimplAPPEND@[]}}% this allows to gobble spaces and to skip the '[]' +\def\pgfplots@addplotimplAPPEND@[{% + \expandafter\pgfplots@addplotimpl\expandafter[\nextplotspec,% +} + +\long\def\pgfplots@addplotimpl[#1]{% + \pgfplotsutil@ifnextchar p{% + \pgfplots@addplotimpl@plot{#1}% + }{% + \pgfplots@addplotimpl@plot{#1}plot + }% +} + +\long\def\pgfplots@addplotimpl@plot#1plot{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@plot@withoptions{#1}% + }{% + \pgfplots@addplotimpl@plot@withoptions{#1}[]% + }% +} + +\long\def\pgfplots@addplotimpl@plot@withoptions#1[#2]{ + \begingroup% <-- This groups ends in \pgfplots@end@plot + % + \pgfplotsutil@ifnextchar c{% + \pgfplots@addplotimpl@coordinates{#1}{#2}plot + }{% + \pgfplotsutil@ifnextchar f{% + \pgfplots@addplotimpl@f{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar t{% + \def\pgfplotssurveyphaseinputclass{table}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@addplotimpl@table{#1,#2}% + }{% + \pgfplotsutil@ifnextchar ({% + \pgfplots@addplotimpl@expression{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar\bgroup{% + \pgfplots@addplotimpl@expression@curly{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar e{% + \pgfplots@addplotimpl@expression@e{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar g{% + \pgfplots@addplotimpl@g{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar s{% + \pgfplots@addplotimpl@shell{#1}{#2}% + }{% + + \pgfplots@error{Sorry, the supplied plot command is unknown or unsupported by pgfplots! Ignoring it.}% + \pgfplots@gobble@until@semicolon + }% + }% + }% + }% + }% + }% + }% + }% +} +\long\def\pgfplots@addplotimpl@f#1#2f{% + \pgfplotsutil@ifnextchar i{% + \pgfplots@addplotimpl@fil{#1}{#2}% + }{% + \pgfplots@addplotimpl@function{#1}{#2}% + }% +}% + +\long\def\pgfplots@addplotimpl@fil#1#2il{% + \pgfplotsutil@ifnextchar e{% + \pgfplots@addplotimpl@file{#1}{#2}% + }{% + \pgfplots@addplotimpl@fillbetween{#1}{#2}% + }% +}% + +\def\pgfplots@addplotimpl@fillbetween#1#2l between{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@fillbetween@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@fillbetween@opt{#1}{#2}[]% + }% +} +% \addplot[#1] [#2] fill between[#3] #4; +\long\def\pgfplots@addplotimpl@fillbetween@opt#1#2[#3]#4;{\pgfplots@addplotimpl@fillbetween@opt@{#1}{#2}{#3}{#4}}% + +\long\def\pgfplots@addplotimpl@fillbetween@opt@#1#2#3#4{% + \pgfkeysifdefined{/tikz/fill between/of/.@cmd}{% + \pgfplotslibraryfillbetween@addplot{#1,#2}{#3}{#4}% + }{% + \pgfplotsthrow{invalid argument} + {\pgfplots@loc@TMPa}% + {Please load \string\usepgfplotslibrary{fillbetween} in order to use `\string\addplot\space fill between'.}% + \pgfeov + }% + % + \pgfplots@end@plot% +}% + +\def\pgfplots@gobble@until@semicolon#1;{} + +% PRECONDITION: +% the key-value sets have all been set in the current scope. +% +% POSTCONDITION: +% 1. the following macros are initialised and sanitized: +% \pgfplots@plot@domain +% \pgfplots@plot@ydomain (will be set to \pgfplots@plot@domain if empty) +% \pgfplots@plot@samples@at +% \pgfplots@plot@samples@y (will be set to the x variant if empty) +% \tikz@plot@var (will become a macro like '\x') +% \pgfplots@plot@var@nonmacro (the same as \tikz@plot@var, but without backslash) +% \pgfplots@plot@var@y (like \tikz@plot@var, but for y) +% \pgfplots@plot@var@y@nonmacro (like \pgfplots@plot@var@nonmacro, but for y) +% 2. the following key-value things are set: +% /pgfplots/mesh/rows +% /pgfplots/mesh/cols +% /pgfplots/samples y (will contain a value ) +% 3. the macro +% \b@pgfplots@should@sample@LINE +% will be +% \def\b@pgfplots@should@sample@LINE{1} +% if the expression plotter should sample a line +% and +% \def\b@pgfplots@should@sample@LINE{0} +% if it should sample a mesh. +\def\pgfplots@plot@expression@preparekeys{% + \pgfkeysgetvalue{/pgfplots/domain}\pgfplots@plot@domain + \pgfkeysgetvalue{/pgfplots/samples y}\pgfplots@plot@samples@y + \pgfkeysgetvalue{/pgfplots/samples at}\pgfplots@plot@samples@at + \pgfkeysgetvalue{/pgfplots/variable y}\pgfplots@plot@var@y + % + % \tikz@plot@var is '\x' be default: + \pgfplots@gettikzinternal@keyval{variable}{tikz@plot@var}{\x}% + % + \begingroup + \escapechar=-1 + \xdef\pgfplots@glob@TMPa{\expandafter\string\tikz@plot@var}% + \xdef\pgfplots@glob@TMPb{\expandafter\string\pgfplots@plot@var@y}% + \endgroup + % \pgfplots@plot@var@nonmacro is the value '\tikz@plot@var' + % without the '\', i.e. 'x' by default: + \let\pgfplots@plot@var@nonmacro=\pgfplots@glob@TMPa + \let\pgfplots@plot@var@y@nonmacro=\pgfplots@glob@TMPb + % + % make sure the 'plot vars' have a backslash (as it was in tikz + % plot expression): + \edef\pgfplots@loc@TMPa{\expandafter\string\tikz@plot@var}% + \ifx\pgfplots@plot@var@nonmacro\pgfplots@loc@TMPa + \edef\tikz@plot@var{\expandafter\noexpand\csname \tikz@plot@var\endcsname}% + \fi + % + \edef\pgfplots@loc@TMPa{\expandafter\string\pgfplots@plot@var@y}% + \ifx\pgfplots@plot@var@y@nonmacro\pgfplots@loc@TMPa + \edef\pgfplots@plot@var@y{\expandafter\noexpand\csname \pgfplots@plot@var@y\endcsname}% + \fi + % + % Check if we have to sample a line or a matrix. + % + \pgfkeysgetvalue{/pgfplots/sample dim}\pgfplots@loc@TMPa + \def\pgfplots@loc@TMPb{auto}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \ifpgfplots@curplot@threedim + \def\b@pgfplots@should@sample@LINE{0}% + \else + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \else + \ifcase\pgfplots@loc@TMPa\relax + % sample dim=0 not useful!? + \def\b@pgfplots@should@sample@LINE{1}% + \or + \def\b@pgfplots@should@sample@LINE{1}% + \or + \def\b@pgfplots@should@sample@LINE{0}% + \else + \pgfplots@error{Sorry, sample dim=\pgfplots@loc@TMPa\space is unsupported (use either 1 or 2)}% + \fi + \fi + % + \if0\b@pgfplots@should@sample@LINE + % sample a matrix. Check the keys; if they are one + % dimensional, switch back to line sampling: + \pgfkeysgetvalue{/pgfplots/y domain}{\pgfplots@plot@ydomain}% + \edef\pgfplots@plot@ydomain{\pgfplots@plot@ydomain}% + \def\pgfplots@loc@TMPa{0:0}% + \ifx\pgfplots@plot@ydomain\pgfplots@loc@TMPa + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \ifx\pgfplots@plot@ydomain\pgfutil@empty + \let\pgfplots@plot@ydomain=\pgfplots@plot@domain + \pgfkeyssetvalue{/pgfplots/y domain}{\pgfkeysvalueof{/pgfplots/domain}}% + \fi + \ifx\pgfplots@plot@samples@y\pgfutil@empty + \else + \ifnum\pgfplots@plot@samples@y<2 + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \fi + \else + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \ifx\pgfplots@plot@samples@y\pgfutil@empty + \pgfkeyssetvalue{/pgfplots/samples y}{\pgfkeysvalueof{/pgfplots/samples}}% + \pgfkeysgetvalue{/pgfplots/samples y}\pgfplots@plot@samples@y + \fi + % + \iftikz@plot@raw@gnuplot + % FIXME : verify this case + \else + \pgfkeyssetvalue{/pgfplots/mesh/rows}{\pgfkeysvalueof{/pgfplots/samples y}}% + \pgfkeyssetvalue{/pgfplots/mesh/cols}{\pgfkeysvalueof{/pgfplots/samples}}% + \fi + \if1\b@pgfplots@should@sample@LINE + \pgfkeyssetvalue{/pgfplots/sample dim}{1}% + \pgfkeyssetvalue{/pgfplots/mesh/cols}{1}% + \else + \pgfkeyssetvalue{/pgfplots/sample dim}{2}% + \fi + % +}% + +% Plot expression. It invokes the pgf math parser and a customized +% pgfplots point sampling routine. Combined with the 'fixed point +% library' of pgf, it results in highly accurate plots. +% +% +\long\def\pgfplots@addplotimpl@expression#1#2(#3,#4)#5;{\pgfplots@addplotimpl@expression@{#1}{#2}{#3}{#4}{#5}}% +% \addplot[#1] [#2] (#3,#4) #5; +\long\def\pgfplots@addplotimpl@expression@#1#2#3#4#5{% + \pgfplots@addplotimpl@expression@set@options{#1}{#2}% + \pgfplots@addplotimpl@expression@@{#3}{#4}{#5}% +} + +\long\def\pgfplots@addplotimpl@expression@set@options#1#2{% + \def\pgfplotssurveyphaseinputclass{expression}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/mesh input=lattice,/pgfplots/mesh/ordering/x varies}% + \pgfplots@plot@expression@preparekeys +}% + +% \addplot (#1,#2) #3; +\long\def\pgfplots@addplotimpl@expression@@#1#2#3{% + % + \pgfplots@PREPARE@COORD@STREAM{#3}% + % + \def\pgfplots@addplotimpl@expression@xEXPR{#1}% + % + % Determine whether the x range is parameterized or uniform and + % prepare a macro which assigns \pgfplots@current@point@x: + \def\pgfplots@addplotimpl@expression@prepare@x{% + \pgfmathparse{#1}% + \let\pgfplots@current@point@x=\pgfmathresult + }% + \def\pgfplots@addplotimpl@expression@prepare@y{% + \pgfmathparse{\pgfplots@addplotimpl@expression@yEXPR}% + \let\pgfplots@current@point@y=\pgfmathresult + }% + \def\pgfplots@addplotimpl@expression@hasuniform@x{0}% + % do we have '\x' as x coordinate? + \expandafter\def\expandafter\pgfplots@loc@TMPb\expandafter{\tikz@plot@var}% + \ifx\pgfplots@addplotimpl@expression@xEXPR\pgfplots@loc@TMPb + \def\pgfplots@addplotimpl@expression@hasuniform@x{1}% + \else + \edef\pgfplots@loc@TMPb{\pgfplots@plot@var@nonmacro}% + % do we have 'x' as x coordinate? + \ifx\pgfplots@addplotimpl@expression@xEXPR\pgfplots@loc@TMPb + \def\pgfplots@addplotimpl@expression@hasuniform@x{1}% + \fi + \fi + \if\pgfplots@addplotimpl@expression@hasuniform@x1% + % if '#1' is '\x' or 'x', we don't need the math parser - + % we can simply take \tikz@plot@var. + \def\pgfplots@addplotimpl@expression@prepare@x{% + \edef\pgfplots@current@point@x{\tikz@plot@var}% + }% + \fi + % + \def\pgfplots@addplotimpl@expression@hasuniform@y{0}% + % + % + % Now, prepare the loops. + % + % I am using \pgfplotsforeachungrouped in favor of + % \foreach because \foreach does NOT allow extended + % precision. Besides, \pgfplotsforeachungrouped avoids + % scoping problems. + \let\pgfplots@plot@data@notify@next@x=\relax + \let\pgfplots@plot@data@notify@next@y=\relax + % + \ifpgfplots@curplot@threedim + \def\pgfplots@addplotimpl@expression@split@yz##1,##2\pgfplots@EOI{% + \def\pgfplots@addplotimpl@expression@yEXPR{##1}% + \def\pgfplots@addplotimpl@expression@zEXPR{##2}% + }% + \pgfplots@addplotimpl@expression@split@yz#2\pgfplots@EOI% + % + % we don't have 'samples at' for 3D plots -> use domain! + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax{\pgfplots@plot@samples}% + \let\pgfplots@expression@xdomain=\pgfplotsretval + % + % do we have '\y' as y coordinate? + \expandafter\def\expandafter\pgfplots@loc@TMPb\expandafter{\pgfplots@plot@var@y}% + \ifx\pgfplots@addplotimpl@expression@yEXPR\pgfplots@loc@TMPb + \def\pgfplots@addplotimpl@expression@hasuniform@y{1}% + \def\pgfplots@addplotimpl@expression@prepare@y{% + \edef\pgfplots@current@point@y{\pgfplots@plot@var@y}% + }% + \else + \edef\pgfplots@loc@TMPb{\pgfplots@plot@var@y@nonmacro}% + % do we have 'y' as y coordinate? + \ifx\addplotimpl@expression@yEXPR\pgfplots@loc@TMPb + \def\pgfplots@addplotimpl@expression@hasuniform@y{1}% + \def\pgfplots@addplotimpl@expression@prepare@y{% + \edef\pgfplots@current@point@y{\pgfplots@plot@var@y}% + }% + \fi + \fi + % + % + \if0\b@pgfplots@should@sample@LINE + % Samples twodimensionally (a lattice): + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@ydomain\relax{\pgfplots@plot@samples@y}% + \let\pgfplots@expression@ydomain=\pgfplotsretval + % + % Assemble a + % \pgfplots@plot@data##1 -> + % \foreach \y in {-5,-4.6,...,5} {##1}; + % \foreach \x in {-5,-4.6,...,5} + % macro: + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\pgfplots@plot@var@y in {\pgfplots@expression@ydomain} + {% + \pgfplots@plot@data@notify@next@y + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@expression@xdomain} {% + \pgfplots@plot@data@notify@next@x + ##1% + }% + \noexpand\pgfplotsplothandlernotifyscanlinecomplete + }% + }% + \else + % sample a line: + \def\pgfplots@plot@ydomain{0:0}% + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@expression@xdomain} {% + \pgfplots@plot@data@notify@next@x + ##1% + }% + }% + % + % If we have (\x,\y,f(x)), use (\x,0,f(x)) instead and + % suppress the error message which would occur for \y. + \if1\pgfplots@addplotimpl@expression@hasuniform@y + \def\pgfplots@addplotimpl@expression@yEXPR{0}% + \def\pgfplots@plot@var@y{0}% + \else + \expandafter\edef\pgfplots@plot@var@y{\pgfplots@plot@var@y@nonmacro}% this provides an error message, see above. + \fi + \fi + \else + % Assemble a + % \pgfplots@plot@data##1 -> \foreach \x in {-5,-4.6,...,5} {##1} macro: + % + % + % if( + % x is logarithmic && + % #1 == '\x' && + % the 'samples at' key has not been used ) + % -> sample logarithmically! + \def\pgfplots@samples@logarithmically{0}% + \ifpgfplots@xislinear + \else + \if\pgfplots@addplotimpl@expression@hasuniform@x1% + \ifx\pgfplots@plot@samples@at\pgfutil@empty + % we don't have 'samples at' -> use domain! + \def\pgfplots@samples@logarithmically{1}% + \fi + \fi + \fi + \if\pgfplots@samples@logarithmically1% + \def\pgfplotsforeachlogarithmicmathid{x}% use \pgfplotscoordmath{x} + % sample logarithmically: + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachlogarithmicungrouped[\pgfplots@plot@samples] + \expandafter\noexpand\tikz@plot@var/\noexpand\pgfplots@current@point@x@log + in {\pgfplots@plot@domain}% + {% + \pgfplots@plot@data@notify@next@x + ##1% + }% + }% + % we have a logarithmic sampling sequence, + % \pgfplots@current@point@x@log is already available + % logarithmic! We can safe time and accuracy for the x + % coordinate by using that one instead of computing + % log(exp(\x)) numerically: + \pgfplots@disablelogfilter@xtrue + \def\pgfplots@addplotimpl@expression@prepare@x{% + \let\pgfplots@current@point@x=\pgfplots@current@point@x@log + }% + \pgflibraryfpuifactive + {\relax} + {% + % ok, if the FPU is NOT active, we should return + % results as fixed points. + % We need to configure that for + % \pgfplotsforeachlogarithmicungrouped manually: + \pgfplotsforeachlogarithmicformatresultwith{% + \pgfmathfloattofixed{\pgfmathresult}% + }% + }% + \else + \ifx\pgfplots@plot@samples@at\pgfutil@empty + % we don't have 'samples at' -> use domain! + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax{\pgfplots@plot@samples}% + \let\pgfplots@loc@TMPa=\pgfplotsretval + \else + % use 'samples at': + \let\pgfplots@loc@TMPa=\pgfplots@plot@samples@at + \fi + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@loc@TMPa}% + {% + \pgfplots@plot@data@notify@next@x + ##1% + }% + }% + \fi + \expandafter\def\pgfplots@plot@var@y{0}% + \def\pgfplots@addplotimpl@expression@yEXPR{#2}% + \def\pgfplots@addplotimpl@expression@zEXPR{}% + \def\pgfplots@current@point@z{}% + \fi + % + % + % START: + % (NOTE: this does also define 'x', 'y', and 'z' math + % expressions!) + \pgfplots@coord@stream@start + % + \pgfplots@addplotimpl@expression@check@LUA + \if1\pgfplotsretval + \pgfplots@log{\pgfplots@LUA@loglevel@debug}{lua backend=true: Activating LUA version of plot expression for plot \the\pgfplots@numplots\space (type '\pgfplotsplothandlername').}% + \begingroup + \expandafter\def\tikz@plot@var{\pgfplots@plot@var@nonmacro}% + \expandafter\def\pgfplots@plot@var@y{\pgfplots@plot@var@y@nonmacro}% + \expandafter\pgfplots@parse@domain\pgfplots@plot@domain\relax{pgfplots@plot@domain}% + % + \pgfmathparse{\pgfplots@plot@samples}% + \let\pgfplots@plot@samples=\pgfmathresult + % + \if0\b@pgfplots@should@sample@LINE + \expandafter\pgfplots@parse@domain\pgfplots@plot@ydomain\relax{pgfplots@plot@ydomain}% + \pgfmathparse{\pgfplots@plot@samples@y}% + \let\pgfplots@plot@samples@y=\pgfmathresult + \else + \def\pgfplots@plot@ydomain@min{0}% + \def\pgfplots@plot@ydomain@max{0}% + \def\pgfplots@plot@samples@y{1}% + \fi + % + % FIXME : there are some cases in which this here might be a + % bad idea: + % - if someone has redefined math functions on TeX + % - if someone has defined his own math functions (only in + % TeX) + % - if a plot expression contains directlua -- the expansion will play + % funny tricks in this case + \xdef\pgfplotsglobalretval{% + \directlua{% + pgfplots.texAddplotExpressionCoordinateGenerator(^^J% + \ifpgfplots@curplot@threedim true \else false\fi,^^J% + "#1", ^^J% + "\pgfplots@addplotimpl@expression@yEXPR",^^J% + "\pgfplots@addplotimpl@expression@zEXPR",^^J% + \b@pgfplots@should@sample@LINE,^^J% + "\pgfplots@plot@domain@min", "\pgfplots@plot@domain@max",^^J% + "\pgfplots@plot@ydomain@min", "\pgfplots@plot@ydomain@max",^^J% + "\pgfplots@plot@samples",^^J% + "\pgfplots@plot@samples@y",^^J% + "\pgfplots@plot@var@nonmacro",^^J% + "\pgfplots@plot@var@y@nonmacro", + "\pgfplots@plot@samples@at", + "\pgfplots@LUA@backend@debugmode")^^J% + }% + }% + \endgroup + \if0\pgfplotsglobalretval + \pgfplots@log{\pgfplots@LUA@loglevel@info}{lua backend=true: LUA version of plot expression failed. Using TeX version. (plot \the\pgfplots@numplots).}% + \pgfplots@LUA@backend@failed + \pgfplots@addplotimpl@expression@streamall + \else + \fi + \else + \pgfplots@addplotimpl@expression@streamall + \fi + % + \pgfplots@coord@stream@end +}% + +% Defines \pgfplotsretval to be '1' if the pure LUA version of +% \addplot expression is enabled. It defines \pgfplotsretval to be 0 +% if not. +\def\pgfplots@addplotimpl@expression@check@LUA{% + \def\pgfplotsretval{0}% + \ifpgfplots@LUA@backend@supported + \def\pgfplotsretval{1}% + \ifpgfplotsplothandlermesh@patch@type@sampling + \def\pgfplotsretval{0}% + \pgfplots@LUA@plotexpression@log@deactivation{patch type sampling unsupported (yet)}% + \fi + % + \if1\pgfplots@addplotimpl@expression@hasuniform@x + \else + \expandafter\pgfplotsutilifcontainsmacro\expandafter{\pgfplots@addplotimpl@expression@xEXPR}{% + \def\pgfplotsretval{0}% + \pgfplots@command@to@string\pgfplots@addplotimpl@expression@xEXPR\pgfplots@loc@TMPa + \pgfplots@LUA@plotexpression@log@deactivation{x expression '\pgfplots@loc@TMPa' contains a TeX macro}% + }{% + }% + \fi + % + \if1\pgfplots@addplotimpl@expression@hasuniform@y + \else + \expandafter\pgfplotsutilifcontainsmacro\expandafter{\pgfplots@addplotimpl@expression@yEXPR}{% + \def\pgfplotsretval{0}% + \pgfplots@command@to@string\pgfplots@addplotimpl@expression@yEXPR\pgfplots@loc@TMPa + \pgfplots@LUA@plotexpression@log@deactivation{y expression '\pgfplots@loc@TMPa' contains a TeX macro}% + }{% + }% + \fi + % + \ifpgfplots@curplot@threedim + \expandafter\pgfplotsutilifcontainsmacro\expandafter{\pgfplots@addplotimpl@expression@zEXPR}{% + \def\pgfplotsretval{0}% + \pgfplots@command@to@string\pgfplots@addplotimpl@expression@zEXPR\pgfplots@loc@TMPa + \pgfplots@LUA@plotexpression@log@deactivation{z expression '\pgfplots@loc@TMPa' contains a TeX macro}% + }{% + }% + \fi + \fi +}% + +\def\pgfplots@LUA@plotexpression@log@deactivation#1{% + \pgfplots@log{\pgfplots@LUA@loglevel@info}{Deactivating LUA version of plot expression for plot \the\pgfplots@numplots\space (type '\pgfplotsplothandlername'): #1.}% + \pgfplots@LUA@backend@failed +} +\def\pgfplots@parse@domain#1:#2\relax#3{% + \pgfmathparse{#1}% + \expandafter\let\csname #3@min\endcsname=\pgfmathresult% + \pgfmathparse{#2}% + \expandafter\let\csname #3@max\endcsname=\pgfmathresult% +}% +\def\pgfplots@addplotimpl@expression@streamall{% + % create a backup of the 'x' and 'y' math expressions which + % have been defined in \pgfplots@coord@stream@start: + \let\pgfplots@addplotimpl@expression@pseudoconst@old@x=\pgfmathx@ + \let\pgfplots@addplotimpl@expression@pseudoconst@old@y=\pgfmathy@ + % + % Prepare 'x' and 'y' as pseudo constants in expressions: + \gdef\pgfplots@noy@error{% + \pgfplots@error{Sorry, you can't use 'y' in this context. PGFPlots expected to sample a line, not a mesh. Please use the [mesh] option combined with [samples y>0] and [domain y!=0:0] to indicate a twodimensional input domain}% + \global\let\pgfplots@noy@error=\relax + }% + % Define a "function" x which sets \pgfmathresult := \x : + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@nonmacro}{\edef\pgfmathresult{\tikz@plot@var}}% + \if0\b@pgfplots@should@sample@LINE + % surface: + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@y@nonmacro}{\edef\pgfmathresult{\pgfplots@plot@var@y}}% + \else + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@y@nonmacro}{\pgfplots@noy@error\def\pgfmathresult{0.0}}% + \fi + % remember them here: + \let\pgfplots@addplotimpl@expression@pseudoconst@x=\pgfmathx@ + \let\pgfplots@addplotimpl@expression@pseudoconst@y=\pgfmathy@ + % +% \if n\pgfplots@meshmode + % mesh=false : ignore patch type sampling. +% \else + \ifpgfplotsplothandlermesh@patch@type@sampling + \pgfplots@plot@expression@prepare@patch@type@sampling + \fi +% \fi + % + % Warning for use fpu=false: evaluation '\x^3' might be different from 'x^3' for + % negative arguments: + % \x^3 ---> -0.2^3 but x^3 = (-0.2)^3 . + % This does not happen for use fpu=true. + % + \pgfplots@plot@data{% + \let\pgfmathx@=\pgfplots@addplotimpl@expression@pseudoconst@x + \let\pgfmathy@=\pgfplots@addplotimpl@expression@pseudoconst@y + % eval expressions: + \pgfplots@addplotimpl@expression@prepare@x% + \pgfplots@addplotimpl@expression@prepare@y% + \ifpgfplots@curplot@threedim + \pgfmathparse{\pgfplots@addplotimpl@expression@zEXPR}% + \let\pgfplots@current@point@z=\pgfmathresult + \fi + % restore 'x' and 'y': + \let\pgfmathx@=\pgfplots@addplotimpl@expression@pseudoconst@old@x + \let\pgfmathy@=\pgfplots@addplotimpl@expression@pseudoconst@old@y + % + %\pgfplots@expression@normalize@floats + % + % process coords as usual: + \pgfplots@coord@stream@coord + }% +} + +% Typically, the FPU will generate stuff like '1Y1.0e5'. Since such +% internal representations will be available to API users (especially +% 'x filter' and its variants, we want to simplify its output - by +% normalizing it. +% +% This routine will convert any floats to scientific format, i.e. +% 1.0e5 instead of 1Y1.0e5 (1Y means 'positive float', compare +% pgfmathfloat.code.tex). +\def\pgfplots@expression@normalize@floats{% + \pgflibraryfpuifactive{% + \ifx\pgfplots@current@point@x\pgfutil@empty\else + \pgfmathfloattosci{\pgfplots@current@point@x}\let\pgfplots@current@point@x=\pgfmathresult + \fi% + \ifx\pgfplots@current@point@y\pgfutil@empty\else + \pgfmathfloattosci{\pgfplots@current@point@y}\let\pgfplots@current@point@y=\pgfmathresult + \fi% + \ifx\pgfplots@current@point@z\pgfutil@empty\else + \pgfmathfloattosci{\pgfplots@current@point@z}\let\pgfplots@current@point@z=\pgfmathresult + \fi% + }{% + }% +}% + +% \addplot[#1] [#2] {#3} #4; +\long\def\pgfplots@addplotimpl@expression@curly#1#2#3#4;{\pgfplots@addplotimpl@expression@curly@{#1}{#2}{#3}{#4}}% +\long\def\pgfplots@addplotimpl@expression@curly@#1#2#3#4{% + \pgfplots@addplotimpl@expression@set@options{#1}{#2}% + \ifpgfplots@curplot@threedim + \t@pgfplots@toka={,#3}% + % the \pgfplots@plot@var@y will expand to the current value of + % '/pgfplots/variable y'. + % Keep it this way, \pgfplots@addplotimpl@expression@ checks + % for that special string. + \edef\pgfplots@loc@TMPb{% + {\expandafter\noexpand\tikz@plot@var}% + {\expandafter\noexpand\pgfplots@plot@var@y\the\t@pgfplots@toka}% + }% + \expandafter\pgfplots@addplotimpl@expression@@\pgfplots@loc@TMPb{#4}% + \else + \expandafter\pgfplots@addplotimpl@expression@@\expandafter{\tikz@plot@var}{#3}{#4}% + \fi +}% +% \addplot[#1] [#2] expression[#3] {#4} #5; +\def\pgfplots@addplotimpl@expression@e#1#2expression{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@expression@e@{#1}{#2}% + }{% + \pgfplots@addplotimpl@expression@e@{#1}{#2}[]% + }% +}% +\def\pgfplots@addplotimpl@expression@e@#1#2[#3]{% + \pgfplots@addplotimpl@expression@curly{#1}{#2,#3}% +}% + + +% This prepares the implementation for 'patch type sampling': +\def\pgfplots@plot@expression@prepare@patch@type@sampling{% + \pgfplotssurveyphaseaddoptionsbeforesurveybegins{ + mesh input=patches,% + }% + % + \pgfkeysgetvalue{/pgfplots/patch type}\pgfplotsplothandlermesh@patchclass + % + \let\pgfplots@plot@data@@=\pgfplots@plot@data + \let\pgfplots@plot@data@curx=\pgfutil@empty + \let\pgfplots@plot@data@cury=\pgfutil@empty + \let\pgfplots@plot@data@lastx=\pgfutil@empty + \let\pgfplots@plot@data@lasty=\pgfutil@empty + \let\pgfplots@plot@data@first@x=\pgfutil@empty + \let\pgfplots@plot@data@first@y=\pgfutil@empty + % + \def\pgfplots@plot@data@notify@next@x{% + \ifx\pgfplots@plot@data@first@x\pgfutil@empty + \edef\pgfplots@plot@data@first@x{\tikz@plot@var}% + \fi + \let\pgfplots@plot@data@lastx=\pgfplots@plot@data@curx + \edef\pgfplots@plot@data@curx{\tikz@plot@var}% + }% + \def\pgfplots@plot@data@notify@next@y{% + \ifx\pgfplots@plot@data@first@y\pgfutil@empty + \edef\pgfplots@plot@data@first@y{\pgfplots@plot@var@y}% + \fi + \let\pgfplots@plot@data@lasty=\pgfplots@plot@data@cury + \edef\pgfplots@plot@data@cury{\pgfplots@plot@var@y}% + }% + \def\pgfplots@plot@data##1{% + % + \pgfplots@plot@data@@{% + \let\tikz@plot@var@old=\tikz@plot@var + \let\pgfplots@plot@var@y@old=\pgfplots@plot@var@y + % + % + % + % boolean 'if is first row || is first cell': + \pgfplots@loc@tmpfalse + \ifx\pgfplots@plot@data@curx\pgfplots@plot@data@first@x + % ah - we have the first row. + \pgfplots@loc@tmptrue + \fi + \if0\b@pgfplots@should@sample@LINE + \ifx\pgfplots@plot@data@cury\pgfplots@plot@data@first@y + % ah - we have the first cell. + \pgfplots@loc@tmptrue + \fi + \fi + % + \ifpgfplots@loc@tmp + \else + \pgfmathparse{\pgfplots@plot@data@curx-\pgfplots@plot@data@lastx}% + \let\pgfplots@plot@data@hx=\pgfmathresult + % + \if0\b@pgfplots@should@sample@LINE + \pgfmathparse{\pgfplots@plot@data@cury-\pgfplots@plot@data@lasty}% + \let\pgfplots@plot@data@hy=\pgfmathresult + \fi + % + \def\pgfplotspatchready{\pgfplotsscanlinecomplete}% + \pgfplotspatchclass{\pgfplotsplothandlermesh@patchclass}{sample in unit cube}{% + \pgfmathparse{\pgfplots@plot@data@lastx + \pgfplotspatchclassx*\pgfplots@plot@data@hx}% + \let\tikz@plot@var=\pgfmathresult + % + \if0\b@pgfplots@should@sample@LINE + \pgfmathparse{\pgfplots@plot@data@lasty + \pgfplotspatchclassy*\pgfplots@plot@data@hy}% + \let\pgfplots@plot@var@y=\pgfmathresult + \fi + % + ##1% + % + \let\tikz@plot@var=\tikz@plot@var@old + \let\pgfplots@plot@var@y=\pgfplots@plot@var@y@old + }% + \fi + }% + }% +}% + +\let\pgfplots@backupof@pgfplotxyfile=\pgfplotxyfile + +% the following code +% results finally in +% +% set format "%.7e";; set samples <...>; plot ... +% +% The windows port of gnuplot doesn't run without the second semicolon +% - for whatever reason. +{ + \catcode`\%=12 + \catcode`\"=12 + \catcode`\;=12 + \xdef\pgfplots@gnuplot@format{set format "%.7e";} +} +\def\pgfplots@addplotimpl@g#1#2g{% + \pgfplotsutil@ifnextchar r{% + \pgfplots@addplotimpl@graphics{#1}{#2}% + }{% + \pgfplots@addplotimpl@gnuplot{#1}{#2}% + }% +}% + +% |\addplot gnuplot| is an alias to |\addplot function| +\def\pgfplots@addplotimpl@gnuplot#1#2nuplot{\pgfplots@addplotimpl@function{#1}{#2}unction}% + +% \addplot[#1] plot[#2] function[#3] {#4} #5; +\def\pgfplots@addplotimpl@function#1#2unction{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@function@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@function@opt{#1}{#2}[]% + }% +}% +\def\pgfplots@addplotimpl@function@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@function@opt@{#1}{#2}{#3}{#4}{#5}}% +% \addplot[#1] [#2] function[#3] {#4} #5; +\def\pgfplots@addplotimpl@function@opt@#1#2#3#4#5{% + % FIXME : what about the key search paths if the user changes + % them!? + \def\pgfplotssurveyphaseinputclass{gnuplot}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3,/pgfplots/mesh/ordering/x varies}% + % + \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% + \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-plot}% + \pgfplots@gettikzinternal@keyval{raw gnuplot}{iftikz@plot@raw@gnuplot}{\iffalse}% + \pgfplots@gettikzinternal@keyval{parametric}{iftikz@plot@parametric}{\iffalse}% + % + % determine dummy variables: + \iftikz@plot@parametric + \ifpgfplots@curplot@threedim + \pgfkeysgetvalue{/pgfplots/parametric/var 2d}\pgfplots@gnuplot@dummy% + \else + \pgfkeysgetvalue{/pgfplots/parametric/var 1d}\pgfplots@gnuplot@dummy% + \fi + \ifx\pgfplots@gnuplot@dummy\pgfutil@empty + \else + \expandafter\pgfutil@in@\expandafter,\expandafter{\pgfplots@gnuplot@dummy}% + \ifpgfutil@in@ + \def\pgfplots@loc@TMPa##1,##2\pgfeov{\pgfplotsset{variable={##1},variable y={##2}}}% + \else + \def\pgfplots@loc@TMPa##1\pgfeov{\pgfplotsset{variable={##1}}}% + \fi + \expandafter\pgfplots@loc@TMPa\pgfplots@gnuplot@dummy\pgfeov + \fi + \fi + % + % prepare domain and samples, normalize dummy variables: + \pgfplots@plot@expression@preparekeys + % + % FIXME: what with 'samples at'!? + \edef\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + % + \def\pgfplots@addplotimpl@gnuplotresult@isthreedim@withtwocoords{0}% + % + \edef\pgfplots@gnuplotcode{#4}% + \ifpgfplots@translategnuplot + \def\pgfplots@loc@TMPa{\pgfplotsutilstrreplace{^}{**}}% + \expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@gnuplotcode}% + \let\pgfplots@gnuplotcode=\pgfplotsretval + \fi + % + % + \iftikz@plot@raw@gnuplot% + \def\pgfplots@plot@data{\pgfplotgnuplot[\pgfplots@plot@filename]{\pgfplots@gnuplot@format;\pgfplots@gnuplotcode}}% + \else% + % collect logs: + \def\pgfplots@gnuplot@logdirs{}% + \ifpgfplots@xislinear + \else + \pgfplots@identify@gnuplot@logbehavior x% + \expandafter\def\expandafter\pgfplots@gnuplot@logdirs\expandafter{\pgfplots@gnuplot@logdirs x}% + \fi + \ifpgfplots@yislinear + \else + \pgfplots@identify@gnuplot@logbehavior y% + \expandafter\def\expandafter\pgfplots@gnuplot@logdirs\expandafter{\pgfplots@gnuplot@logdirs y}% + \fi + \ifpgfplots@curplot@threedim + \ifpgfplots@zislinear + \else + \pgfplots@identify@gnuplot@logbehavior z% + \expandafter\def\expandafter\pgfplots@gnuplot@logdirs\expandafter{\pgfplots@gnuplot@logdirs z}% + \fi + \fi + % + \ifpgfplots@curplot@threedim + \if1\b@pgfplots@should@sample@LINE + \pgfplots@error{Sorry, I do not know how to sample 3D LINE plots with gnuplot... I only know 2D line and 3D mesh. You may want to help the author of pgfplots to improve this feature.}% + \fi + \fi + \def\pgfplots@gnuplot@x{\pgfplots@plot@var@nonmacro}% + \def\pgfplots@gnuplot@y{\pgfplots@plot@var@y@nonmacro}% + \def\pgfplots@plot@data{\pgfplotgnuplot[\pgfplots@plot@filename]{% + \pgfplots@gnuplot@format; + set samples \pgfkeysvalueof{/pgfplots/samples}\if0\b@pgfplots@should@sample@LINE, \pgfkeysvalueof{/pgfplots/samples y}\fi; + set dummy \pgfplots@gnuplot@x\if0\b@pgfplots@should@sample@LINE,\pgfplots@gnuplot@y\fi; + \ifx\pgfplots@gnuplot@logdirs\pgfutil@empty + \else + set logscale \pgfplots@gnuplot@logdirs\space 2.71828182845905; + \fi + \iftikz@plot@parametric set parametric;\fi + \ifpgfplots@curplot@threedim + \if0\b@pgfplots@should@sample@LINE + % Samples twodimensionally (a lattice): + % and the isosamples thing confuses me. + set isosamples \pgfkeysvalueof{/pgfplots/samples}\if0\b@pgfplots@should@sample@LINE, \pgfkeysvalueof{/pgfplots/samples y}\fi; + splot [\pgfplots@gnuplot@x=\pgfplots@plot@domain] [\pgfplots@gnuplot@y=\pgfplots@plot@ydomain] \pgfplots@gnuplotcode;% + \else + % *should* sample a line, but I don't know how. + splot [\pgfplots@gnuplot@x=\pgfplots@plot@domain] \pgfplots@gnuplotcode;% + \fi + \else + plot [\pgfplots@gnuplot@x=\pgfplots@plot@domain] \pgfplots@gnuplotcode;% + \fi + }}% + \fi% + \def\pgfplotxyfile{\pgfplots@addplotimpl@gnuplotresult{#5}}% + \pgfplots@plot@data + \let\pgfplotxyfile=\pgfplots@backupof@pgfplotxyfile +}% + +\def\pgfplots@identify@gnuplot@logbehavior#1{% + \pgfutil@ifundefined{pgfplots@gnuplot@logscale@writes@log}{% + \pgfplots@identify@gnuplot@logbehavior@checkversion% + }{}% + \if1\pgfplots@gnuplot@logscale@writes@log + \csname pgfplots@disablelogfilter@#1true\endcsname + \fi +}% +\def\pgfplots@identify@gnuplot@logbehavior@checkversion{% + \begingroup + \immediate\write18{gnuplot -V >\pgfplots@plot@filename.vrs}% + \openin\r@pgfplots@reada=\pgfplots@plot@filename.vrs\relax + \ifeof\r@pgfplots@reada + \pgfplotswarning{gnuplot -V impossible}\pgfeov + \gdef\pgfplots@gnuplot@logscale@writes@log{1}% something doesn't work. set it somehow. + \else + \read\r@pgfplots@reada to\pgfplots@loc@TMPa + \gdef\pgfplots@gnuplot@logscale@writes@log{1}% + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% + \immediate\write-1{Package pgfplots: checking gnuplot -V : `\the\t@pgfplots@toka' (if this fails, set `/pgfplots/gnuplot writes logscale=true|false')}% + \expandafter\pgfplots@identify@gnuplot@logbehavior@checkversion@\pgfplots@loc@TMPa 0 0.0 0\relax + \if0\pgfplots@gnuplot@logscale@writes@log + \immediate\write-1{Package pgfplots: I found gnuplot version >= 4.4. This one doesn't write log() coordinates. I will apply log() manually.}% + \else + \immediate\write-1{Package pgfplots: I found gnuplot version < 4.4. This one writes log() coordinates. I'll handle it accordingly.}% + \fi + \closein\r@pgfplots@reada + \fi + \endgroup +}% +\long\def\pgfplots@identify@gnuplot@logbehavior@checkversion@{% + \pgfutil@ifnextchar\par{% + \pgfplotswarning{gnuplot -V format unknown}\pgfeov% + \gdef\pgfplots@gnuplot@logscale@writes@log{1}% + \pgfplots@identify@gnuplot@logbehavior@checkversion@@@ + }{% + \pgfplots@identify@gnuplot@logbehavior@checkversion@@ + }% +}% +\long\def\pgfplots@identify@gnuplot@logbehavior@checkversion@@@#1\relax{% +}% +\long\def\pgfplots@identify@gnuplot@logbehavior@checkversion@@#1 #2.#3 #4\relax{% + % starting with gnuplot 4.4, output files are no longer in + % logarithmic scale for log plots. + \ifnum#2<4 + % version 3.X + \gdef\pgfplots@gnuplot@logscale@writes@log{1}% + \else + \ifnum#2>4 + % version 5.X + \gdef\pgfplots@gnuplot@logscale@writes@log{0}% + \else + \ifnum#3<4 + % version 4.2 : + \gdef\pgfplots@gnuplot@logscale@writes@log{1}% + \else + % version 4.4 or later : + \gdef\pgfplots@gnuplot@logscale@writes@log{0}% + \fi + \fi + \fi +}% + +\def\pgfplots@addplotimpl@gnuplotresult#1#2{% + \begingroup + \openin\r@pgfplots@reada=#2 + \ifeof\r@pgfplots@reada + \pgfplots@error{Sorry, the gnuplot-result file '#2' could not be found. Maybe you need to enable the shell-escape feature? For pdflatex, this is '>> pdflatex -shell-escape'. You can also invoke '>> gnuplot <file>.gnuplot' manually on the respective gnuplot file.}% + \aftergroup\pgfplots@loop@CONTINUEfalse + \else + \aftergroup\pgfplots@loop@CONTINUEtrue + \fi + \closein\r@pgfplots@reada + \endgroup + \ifpgfplots@loop@CONTINUE + % Now, invoke 'plot file'. + % + % I invoke the private '@opt@' method because the semicolon ';' + % character may cause problems due to catcode mismatches. + % *sigh*. + \pgfplots@addplotimpl@file@opt@@{}{}{#2}{#1}% this does not invoke the \pgfplots@start@plot@with@behavioroptions method. + \else + \expandafter\pgfplots@end@plot + \fi +} + +% \addplot[#1] plot[#2] shell[#3] {#4} #5; +\def\pgfplots@addplotimpl@shell#1#2shell{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@shell@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@shell@opt{#1}{#2}[]% + }% +}% +\def\pgfplots@addplotimpl@shell@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@shell@opt@{#1}{#2}{#3}{#4}{#5}}% +% \addplot[#1] [#2] shell[#3] {#4} #5; +\def\pgfplots@addplotimpl@shell@opt@#1#2#3#4#5{% + \def\pgfplotssurveyphaseinputclass{shell}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3}% + \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% + \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-shell}% + % + \def\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + \def\pgfplots@plot@data{\pgfshell[\pgfplots@plot@filename]{#4}\pgfplotxyfile{\pgfplots@plot@filename.out}}% + \def\pgfplotxyfile{\pgfplots@addplotimpl@shellresult{#5}}% + \pgfplots@plot@data + \let\pgfplotxyfile=\pgfplots@backupof@pgfplotxyfile +}% + +\def\pgfplots@addplotimpl@shellresult#1#2{% + \begingroup + \openin\r@pgfplots@reada=#2 + \ifeof\r@pgfplots@reada + \pgfplots@error{Sorry, the shell-result file '#2' could not be found. Maybe you need to enable the shell-escape feature? For pdflatex, this is '>> pdflatex -shell-escape'. You can also invoke '>> sh <file>.sh > <file>.out' manually on the respective shell file.}% + \aftergroup\pgfplots@loop@CONTINUEfalse + \else + \aftergroup\pgfplots@loop@CONTINUEtrue + \fi + \closein\r@pgfplots@reada + \endgroup + \ifpgfplots@loop@CONTINUE + % Now, invoke 'plot file'. + % + % I invoke the private '@opt@' method because the semicolon ';' + % character may cause problems due to catcode mismatches. + % *sigh*. + \pgfplots@addplotimpl@file@opt@@{}{}{#2}{#1}% + \else + \expandafter\pgfplots@end@plot + \fi +} + +% \addplot[#1] [#2] file{#3} #4; +\def\pgfplots@addplotimpl@file#1#2e{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@file@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@file@opt{#1}{#2}[]% + }% +} + +% \addplot[#1] [#2] file[#3] {#4} #5; +\def\pgfplots@addplotimpl@file@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@file@opt@{#1}{#2}{#3}{#4}{#5}}% +\def\pgfplots@addplotimpl@file@opt@#1#2#3#4#5{% + % invoke this here - allows to share the 'plot file' impl with + % 'plot gnuplot'. + \def\pgfplotssurveyphaseinputclass{file}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@addplotimpl@file@opt@@{#1,#2}{#3}{#4}{#5}% +} +\def\pgfplots@addplotimpl@file@opt@@#1#2#3#4{% + \begingroup + \def\pgfplots@loc@TMPa{#2}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfqkeys{/pgfplots/plot file}{#2}% + \fi + \pgfplots@PREPARE@COORD@STREAM{#4}% + \pgfplots@addplotimpl@file@streamit{#3}% + \endgroup +}% +% #1: the file name +\def\pgfplots@addplotimpl@file@streamit#1{% + \pgfplots@coord@stream@start + \pgfplotsscanlinelengthinitzero + \openin\r@pgfplots@reada=#1 + \ifeof\r@pgfplots@reada + \pgfplots@error{sorry, plot file{#1} could not be opened}% + \else + \pgfplots@logfileopen{#1}% + \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 + \ifpgfplots@curplot@threedim + \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@threedim + \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @explicitinput\endcsname + \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@threedim@andmeta + \fi + \else + \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@twodim + \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @explicitinput\endcsname + \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@twodim@andmeta + \fi + \fi + \pgfplotstableinstallignorechars% + \pgfplots@addplotimpl@file@readall + \fi + \pgfplotsscanlinelengthcleanup + \pgfplots@coord@stream@end +}% +\def\pgfplots@addplotimpl@file@readall{% + \read\r@pgfplots@reada to\pgfplots@file@LINE + \expandafter\pgfplotstableread@checkspecial@line\pgfplots@file@LINE\pgfplotstable@EOI + \ifpgfplotstableread@skipline + \else + \ifpgfplots@plot@file@skipfirst + % Silently skip first data row, assuming it is a header. + \pgfplots@plot@file@skipfirstfalse + \else + \pgfplotsscanlinelengthincrease + \expandafter\pgfplots@addplotimpl@file@parsesingle\pgfplots@file@LINE 0 0 0 0 0\pgfplots@EOI + \fi + \fi + \ifeof\r@pgfplots@reada + \else + \expandafter + \pgfplots@addplotimpl@file@readall + \fi +}% + +\def\pgfplots@addplotimpl@file@parsesingle@threedim#1 #2 #3 #4\pgfplots@EOI{% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \def\pgfplots@current@point@z{#3}% + \pgfplots@coord@stream@coord% +}% +\def\pgfplots@addplotimpl@file@parsesingle@twodim#1 #2 #3\pgfplots@EOI{% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \pgfplots@coord@stream@coord% +}% +\def\pgfplots@addplotimpl@file@parsesingle@threedim@andmeta#1 #2 #3 #4 #5\pgfplots@EOI{% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \def\pgfplots@current@point@z{#3}% + \def\pgfplots@current@point@meta{#4}% + \pgfplots@coord@stream@coord% +}% +\def\pgfplots@addplotimpl@file@parsesingle@twodim@andmeta#1 #2 #3 #4\pgfplots@EOI{% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \def\pgfplots@current@point@meta{#3}% + \pgfplots@coord@stream@coord% +}% + + +\def\pgfplots@addplotimpl@graphics#1#2raphics{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@graphics@{#1}{#2}% + }{% + \pgfplots@addplotimpl@graphics@{#1}{#2}[]% + }% +}% +% \addplot[#1] plot[#2] graphics[#3] {#4} #5; +\long\def\pgfplots@addplotimpl@graphics@#1#2[#3]#4#5;{\pgfplots@addplotimpl@graphics@@{#1}{#2}{#3}{#4}{#5}}% +\long\def\pgfplots@addplotimpl@graphics@@#1#2#3#4#5{% + \def\pgfplotssurveyphaseinputclass{graphics}% + \pgfplots@start@plot@with@behavioroptions{% + /pgfplots/filter discard warning=false, + /pgfplots/mesh/rows=2,% allow \addplot[surf] graphics ... --> yields a good legend. + /pgfplots/mesh/cols=2, + /pgfplots/mesh/check=false, + #1,/pgfplots/.cd,#2,% + /pgfplots/plot graphics/@prepare legend, + /pgfplots/plot graphics,% + /pgfplots/plot graphics/.cd,% + #3,% + /pgfplots/plot graphics/src={#4},% + /tikz/mark=}% + \pgfplots@PREPARE@COORD@STREAM{#5}% + \pgfplots@coord@stream@start + % + \pgfkeysgetvalue{/pgfplots/plot graphics/points}{\pgfplots@current@point@points}% + \ifx\pgfplots@current@point@points\pgfutil@empty + \else + \let\pgfplotsplothandlergraphicspointmappoint=\pgfplotsplothandlergraphics@survey@pointmappoint + \expandafter\pgfplots@plot@handler@graphics@parsepointmap\expandafter{\pgfplots@current@point@points}% + \ifpgfplots@plot@graphics@autoadjustaxis + \pgfplotsplothandlergraphicspointmapcomputerequiredview + \ifx\pgfplotsretval\pgfutil@empty + \else + \expandafter\pgfplotssetlateoptions\expandafter{\pgfplotsretval}% + \fi + \fi + % + \def\pgfplots@addplotimpl@graphics@@error##1{}% + \fi + % + \pgfkeysgetvalue{/pgfplots/plot graphics/xmin}{\pgfplots@current@point@x}% + \pgfkeysgetvalue{/pgfplots/plot graphics/ymin}{\pgfplots@current@point@y}% + % + % these sanity checks do nothing of the 'plot graphics/points' feature has been used: + \ifx\pgfplots@current@point@x\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{xmin}\fi + \ifx\pgfplots@current@point@y\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{ymin}\fi + \ifpgfplots@curplot@threedim + \pgfkeysgetvalue{/pgfplots/plot graphics/zmin}{\pgfplots@current@point@z}% + \ifx\pgfplots@current@point@z\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{zmin}\fi + \fi + \pgfplots@coord@stream@coord + % + \pgfkeysgetvalue{/pgfplots/plot graphics/xmax}{\pgfplots@current@point@x}% + \pgfkeysgetvalue{/pgfplots/plot graphics/ymax}{\pgfplots@current@point@y}% + \ifx\pgfplots@current@point@x\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{xmax}\fi + \ifx\pgfplots@current@point@y\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{ymax}\fi + \ifpgfplots@curplot@threedim + \pgfkeysgetvalue{/pgfplots/plot graphics/zmax}{\pgfplots@current@point@z}% + \ifx\pgfplots@current@point@z\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{zmax}\fi + \fi + \pgfplots@coord@stream@coord + % + \pgfplots@coord@stream@end +}% +\def\pgfplots@addplotimpl@graphics@@error#1{% + \begingroup + \pgfplots@error{Sorry, but 'plot graphics' can't determine where to place the graphics file - (at least) the key '#1' is missing. Please verify that you provided all required limits, for example 'plot graphics[xmin=0,xmax=1,ymin=0,ymax=1] {<graphics>}'.}% + \endgroup +}% + + + + +% \addplot[#1] table[#2] [from] {<\macro>} #4; +% or +% \addplot[#1] table[#2] {<filename>} #4; +% +% The distinction between <\macro> and <filename> is done +% automatically. +% +% Input options can be provided in '#2' using +% - column names, +% for example '/pgfplots/table/x=firstcol' or just 'x=firstcol' +% +% - column indices, +% for example '/pgfplots/table/x index=3' or just 'x index=3' +% +% - expressions involving any of the table's data cells in the +% currently processed cell, +% for example '/pgfplots/table/x expr={\columnx * \columny + \thisrow{columnxxx}/2}' +% During expr, the following (non-exhaustive) list of macros is +% available: +% - \columnx, \columny, \columnz, \columnmeta, \columnerrorx, +% \columnerrory, \columnerrorz +% Provide access to the cell content which would be used without +% 'expr'. +% The first three access the input coordinate columns, \meta the meta column +% (if any) and the last three the error data (if any). +% +% That means it is allowed to provide both, 'x' and 'x expr': +% 'x expr' can use the (old) value stored in 'x'. the final x +% coordinate will be that returned of 'x expr'. +% +% - \coordindex +% +% - \lineno (physical line numbers including comments etc) +% +% - \thisrow{<colname>} +% allows access to any columns. +% +% - \getthisrow{<colname>}{<\macro>} +% this is a fragile command! Don't use it directly inside of +% a math expression, prefer \thisrow. +% +% The FPU will be used to evaluate any expressions. +% +% @REMARKS the implementation for '* expr' differs for the '<\macro>' +% and '<filename>' input types: +% - for '{<filename>}', only the current row is available. +% - for '{<\macro>}', the `create on use' framework of the table +% package is used - with all its features, including comfortable +% access to the previous and next row and accumulation features. +\def\pgfplots@addplotimpl@table#1table{% + \pgfplotsutil@ifnextchar[{% + \pgfplots@addplotimpl@table@getopts{#1}% + }{% + \pgfplots@addplotimpl@table@getopts{#1}[]% + }% +}% + +\def\pgfplots@addplotimpl@table@getopts#1[#2]{% + % set options outside of the following group. + % They may contain behavior options. + \pgfplots@addplotimpl@table@installkeypath + \pgfplotstableset{#2}% + % + \pgfplotsutil@ifnextchar s{% + \pgfplots@addplotimpl@table@fromshell{#1}{#2}% + }{% + \pgfplotsutil@ifnextchar f{% + \pgfplots@addplotimpl@table@fromstructure@gobble@space{#1}{#2}% + }{% + \pgfplots@addplotimpl@table@fromfile@gobble@space{#1}{#2}% + }% + }% +} + +% this macro simply invokes the "correct" table processing routine. +% The distinction between 'table from {<\macro>}' and 'table +% {<filename>}' is deprecated; it is done automatically now. +% +% \addplot[#1] table[#2] [from] {#3} #4; +\def\pgfplots@addplotimpl@table@startprocessing#1#2#3#4{% + \pgfplotstable@isloadedtable{#3}{% + \pgfplots@addplotimpl@table@fromstructure@{#1}{#2}{#3}{#4}% + }{% + \pgfplots@addplotimpl@table@fromfile@{#1}{#2}{#3}{#4}% + }% +}% + +% \addplot[#1] table[#2] from {#3} #4; +% +% #1: arguments to \addplot[...] +% #2: arguments to table[...] (already processed!) +% #3: the argument of plot table{...} +% #4: trailing path arguments after plot table{...}#4; +\long\def\pgfplots@addplotimpl@table@fromstructure@gobble@space#1#2from{% + \pgfplotstablecollectoneargwithpreparecatcodes{% + \pgfplots@addplotimpl@table@fromstructure{#1}{#2}from% + }% +}% + +\def\pgfplots@addplot@table@fromstructure@preparecolname#1#2#3#4{% + \pgfkeysgetvalue{/pgfplots/table/#1}{\pgfplots@loc@TMPa}% + % + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \pgfkeysgetvalue{/pgfplots/table/#1 index}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfplotstablegetcolumnnamebyindex\pgfplots@loc@TMPa\of#2\to\pgfplots@loc@TMPa + \fi + \fi + \let#3=\pgfplots@loc@TMPa + % + % modify \pgfplots@plot@tbl@{x,y,z,meta} if there are + % corresponding '#1 expr' statements: + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for{#1}{#3}{#4}% +} + +% Invokes `#1' if the command is invoked within +% \addplot table {<\macro>}; +% and `#2' if not. +\def\pgfplotsifinaddplottablestruct#1#2{% + \pgfutil@ifundefined{pgfplots@plot@tbl@meta}{#2}{#1}% +}% + +\long\def\pgfplots@addplotimpl@table@fromstructure#1#2from#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% +% \addplot[#1] table[#2] from {#3} #4 ; +\long\def\pgfplots@addplotimpl@table@fromstructure@#1#2#3#4{% + \begingroup + \def\pgfplotstablename{#3}% store the name of the currently processed table. + \pgfplotstablegetscanlinelength{#3}{\pgfplotsscanlinelength}% + % FIXME : this thing here has runtime O(N^2) ! + % I fear it is faster to simply reload the data .... !? + % + % well, for a lot of columns which are used in different contexts + % and few rows, this here IS more efficient. + % + \pgfplots@addplot@table@fromstructure@preparecolname{x}{#3}\pgfplots@plot@tbl@x\columnx + \pgfplots@addplot@table@fromstructure@preparecolname{y}{#3}\pgfplots@plot@tbl@y\columny + \ifpgfplots@curplot@threedim + \pgfplots@addplot@table@fromstructure@preparecolname{z}{#3}\pgfplots@plot@tbl@z\columnz + \fi + \pgfplots@addplot@table@fromstructure@preparecolname{meta}{#3}\pgfplots@plot@tbl@meta\columnmeta + % + % + % high level user interface functions: + \let\pgfplotstable@coordindex@old=\coordindex + \def\coordindex{\pgfplotstablerow}% + \def\lineno{\coordindex}% is the same here + % These macros are-unfortunately- not accessable here. And the + % worst is: error messages are impossible either because they are + % not executed... try to provide useful hints: + \def\thisrow##1{thisrow_unavailable_load_table_directly}% + \def\thisrowno##1{thisrowno_unavailable_load_table_directly}% + % this should work. + \def\getthisrow##1##2{\pgfplotstablegetelem{\coordindex}{##1}\of{#3}{##2}}% + \def\getthisrowno##1##2{\pgfplotstablegetelem{\coordindex}{[index]##1}\of{#3}{##2}}% + % + \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@x}\of#3\to\addplot@tbl@x + \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@y}\of#3\to\addplot@tbl@y + \ifpgfplots@curplot@threedim + \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@z}\of#3\to\addplot@tbl@z + \fi + % + \let\addplot@tbl@meta=\pgfutil@empty + \ifx\pgfplots@plot@tbl@meta\pgfutil@empty + \else + \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@meta}\of#3\to\addplot@tbl@meta + \fi + % + % + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init x{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init x{#3}{minus}% + % + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init y{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init y{#3}{minus}% + % + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init z{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init z{#3}{minus}% + \fi + % + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load x{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load x{#3}{minus}% + % + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load y{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load y{#3}{minus}% + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load z{#3}{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load z{#3}{minus}% + \fi + % + \let\coordindex=\pgfplotstable@coordindex@old + % + \pgfplots@PREPARE@COORD@STREAM{#4}% + \pgfplots@coord@stream@start + \pgfutil@loop + \pgfplotslistcheckempty\addplot@tbl@x + \ifpgfplotslistempty + \pgfplots@loop@CONTINUEfalse + \else + % This here is just for sanity checking: if the 'y' column is + % - for whatever reasons - invalid; provide good error + % recovery. + \pgfplotslistcheckempty\addplot@tbl@y + \ifpgfplotslistempty + \pgfplots@loop@CONTINUEfalse + \else + \pgfplots@loop@CONTINUEtrue + \fi + \fi + \ifpgfplots@loop@CONTINUE + \pgfplotslistpopfront\addplot@tbl@x\to\pgfplots@current@point@x + \pgfplotslistpopfront\addplot@tbl@y\to\pgfplots@current@point@y + \ifpgfplots@curplot@threedim + \pgfplotslistpopfront\addplot@tbl@z\to\pgfplots@current@point@z + \fi + \ifx\addplot@tbl@meta\pgfutil@empty + \else + \pgfplotslistpopfront\addplot@tbl@meta\to\pgfplots@current@point@meta + \fi + \ifpgfplots@errorbars@enabled + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext x{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext x{minus}% + % + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext y{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext y{minus}% + % + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext z{plus}% + \pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext z{minus}% + \fi + \fi + \pgfplots@coord@stream@coord + \pgfutil@repeat + \pgfplots@coord@stream@end + \pgfmath@smuggleone\pgfplotsscanlinelength + \endgroup +} + +% #1: x, y, or z +% #2: the table name +% #3: either "plus" or "minus" +\def\pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@init#1#2#3{% + \expandafter\let\csname addplot@tbl@error@#1@#3\endcsname=\pgfutil@empty + \expandafter\let\csname pgfplots@current@point@error@#1@#3\endcsname=\pgfutil@empty + \ifpgfplots@errorbars@enabled + % prepare with suitable expansion: + \def\pgfplots@loc@TMPa{% + \pgfplots@addplot@table@fromstructure@preparecolname{#1 error #3}{#2}}% + \edef\pgfplots@loc@TMPb{% + \expandafter\noexpand\csname pgfplots@plot@tbl@error@#1@#3\endcsname + % FIXME : these macros are UNDOCUMENTED! I suppose they are dead code... + \expandafter\noexpand\csname columnerror#1\endcsname + }% + % execute prepared statement: + % = \pgfplots@addplot@table@fromstructure@preparecolname + % {x error plus}{#2}{\pgfplots@plot@tbl@error@x@plus}{\columnerrorx} + \expandafter\pgfplots@loc@TMPa\pgfplots@loc@TMPb + % + \fi +}% + +% #1: x, y, or z +% #2: the table name +% #3: either "plus" or "minus" +\def\pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@load#1#2#3{% + \ifpgfplots@errorbars@enabled + \expandafter\ifx\csname pgfplots@plot@tbl@error@#1@#3\endcsname\pgfutil@empty + % ok, we do not have this error kind. + \else + % assemble the statement + % \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@error@x@plus}\of#2\to\addplot@tbl@error@x@plus + % -> but with suitable expansion restrictions. + \edef\pgfplots@loc@TMPa{\expandafter\noexpand\csname pgfplots@plot@tbl@error@#1@#3\endcsname}% + % + \def\pgfplots@loc@TMPb{% + \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@loc@TMPa}\of#2\to + }% + \expandafter\pgfplots@loc@TMPb\csname addplot@tbl@error@#1@#3\endcsname + \fi + \fi +}% + +% #1: x, y, or z +% #2: either "plus" or "minus" +\def\pgfplots@addplotimpl@table@fromstructure@prepare@errorbar@getnext#1#2{% + \expandafter\ifx\csname addplot@tbl@error@#1@#2\endcsname\pgfutil@empty + \expandafter\let\csname pgfplots@current@point@error@#1@#2\endcsname=\pgfutil@empty + \else + \expandafter\pgfplotslistpopfront\csname addplot@tbl@error@#1@#2\endcsname\to\pgfplots@loc@TMPa + \expandafter\let\csname pgfplots@current@point@error@#1@#2\endcsname=\pgfplots@loc@TMPa + \fi +}% + +% A private helper macro which initialises the '#1 expr' keys for plot +% table from structure. +% +% PRECONDITION: +% \pgfplots@plot@tbl@#1 contains the column name which would be used +% if '#1 expr' is empty. +% +% POSTCONDITION: +% \pgfplots@plot@tbl@#1 will be CHANGED to use the 'expr' column (a +% temporary name). +% The old value of \pgfplots@plot@tbl@#1 is available as column +% alias. +% the high level user interface command '#3' will be set correctly. +% +% #1: the key name of the current entity, for example 'x' for +% '/pgfplots/table/x' +% #2: the low level column name representing the data which is already +% defined somehow +% #3: a high level user interface command +\def\pgfplots@addplotimpl@table@fromstructure@prepareexpr@for#1#2#3{% + % get old column name into a register: + \t@pgfplots@tokb=\expandafter{#2}% + % + % high level user interface command: + \edef#3{\noexpand\thisrow{\the\t@pgfplots@tokb}}% + % + \pgfkeysgetvalue{/pgfplots/table/#1 expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + % get expression into register: + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% + % + % + % assemble pgfkeys statement which expands the names above + % just one time: + \edef\pgfplots@loc@TMPa{% + /pgfplots/table/create on use/#1expr@tempcol/.style={% + /pgfplots/table/create col/expr={\the\t@pgfplots@toka}% + },% + /pgfplots/table/alias/#1/.initial={\the\t@pgfplots@tokb}% + }% + \expandafter\pgfkeysalso\expandafter{\pgfplots@loc@TMPa}% + % + % tell `plot table' which column should be used for '#1': the + % temporary column. + \def#2{#1expr@tempcol}% + \fi +}% + + +% \addplot[#1] table[#2] {#3} #4; +% +% This here is the (probably) faster input method from tables. +% +% It has linear complexity in the number of rows (as long as the +% number of rows is less than about 110000). +% +% #1: arguments to \addplot[...] +% #2: arguments to table[...] (already processed!) +% #3: the argument of plot table{...} +% #4: trailing path arguments after plot table{...}#4; +% +\long\def\pgfplots@addplotimpl@table@fromfile@gobble@space#1#2{% + \pgfplotstablecollectoneargwithpreparecatcodes{% + \pgfplots@addplotimpl@table@fromfile{#1}{#2}% + }% +}% +\long\def\pgfplots@addplotimpl@table@fromfile#1#2#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% +% \addplot[#1] table[#2] {#3} {#4}; +\long\def\pgfplots@addplotimpl@table@fromfile@#1#2#3#4{% + \if1\pgfplots@addplotimpl@readcompletely@auto + \pgfplots@addplotimpl@table@check@createonuse@for{x}% + \pgfplots@addplotimpl@table@check@createonuse@for{y}% + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@check@createonuse@for{z}% + \fi + \pgfplots@addplotimpl@table@check@createonuse@for{x error plus}% + \pgfplots@addplotimpl@table@check@createonuse@for{x error minus}% + \pgfplots@addplotimpl@table@check@createonuse@for{y error plus}% + \pgfplots@addplotimpl@table@check@createonuse@for{y error minus}% + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@check@createonuse@for{z error plus}% + \pgfplots@addplotimpl@table@check@createonuse@for{z error minus}% + \fi + \pgfplots@addplotimpl@table@check@createonuse@for{meta}% + \fi + % + \ifpgfplots@addplotimpl@readcompletely + \pgfplotstableread{#3}\pgfplots@table + \pgfplots@addplotimpl@table@fromstructure@{#1}{}{\pgfplots@table}{#4}% + \else + \pgfplotsapplistXXglobalnewempty + % + % these data pointers will be prepared to allow fast access + % into the current row while we read rows succesively from + % disk. + % Note: their initialisation must be postponed until + % \pgfplotstableread is running - otherwise, we can't query + % pointers into the table. See below. + \let\pgfplots@table@PTR@x=\pgfutil@empty + \let\pgfplots@table@PTR@y=\pgfutil@empty + \let\pgfplots@table@PTR@z=\pgfutil@empty + \let\pgfplots@table@PTR@meta=\pgfutil@empty + % + % + \let\pgfplots@current@point@meta=\pgfutil@empty + \let\pgfplots@current@point@z=\pgfutil@empty + % + % high level user interface functions: + \def\lineno{\pgfplotstablelineno}% + \def\columnx{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@x}}% + \def\columny{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@y}}% + \def\columnz{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@z}}% + \def\columnmeta{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@meta}}% + % + \pgfplots@PREPARE@COORD@STREAM{#4}% + \pgfplots@coord@stream@start + \ifpgfplots@errorbars@enabled + % more fast-access pointers for error data: + \let\pgfplots@table@ERRPTR@x=\pgfutil@empty + \let\pgfplots@table@ERRPTR@y=\pgfutil@empty + \let\pgfplots@table@ERRPTR@z=\pgfutil@empty + % + % prepare: + \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 + % + % high level user interface functions: + % FIXME : these macros are UNDOCUMENTED! I suppose they are dead code... + \def\columnerrorx{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@x}}% + \def\columnerrory{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@y}}% + \def\columnerrorz{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@z}}% + % + \pgfplotstableread*{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL + \else + \pgfplotstableread*{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@COLLECTNORMALIZED + \fi + \pgfplots@coord@stream@end + \fi +} +\def\pgfplots@addplotimpl@table@check@createonuse@for#1{% + \pgfkeysgetvalue{/pgfplots/table/#1}\pgfplots@addplotimpl@table@check@createonuse@for@ + \expandafter\pgfplotstableifiscreateonuse\expandafter{\pgfplots@addplotimpl@table@check@createonuse@for@}{% + \pgfplots@addplotimpl@readcompletelytrue + }{% + }% +}% +\def\pgfplots@addplotimpl@table@fromfile@listener@COLLECTNORMALIZED{% + \pgfplots@addplotimpl@table@fromfile@listener@ + \pgfplots@coord@stream@coord +} +\def\pgfplots@addplotimpl@table@fromfile@listener@PREPARE{% + % this here is only evaluated ONCE. + \pgfkeysgetvalue{/pgfplots/table/x}{\pgfplots@plot@tbl@x}% + \pgfkeysgetvalue{/pgfplots/table/x index}{\pgfplots@plot@tbl@xindex}% + \pgfkeysgetvalue{/pgfplots/table/y}{\pgfplots@plot@tbl@y}% + \pgfkeysgetvalue{/pgfplots/table/y index}{\pgfplots@plot@tbl@yindex}% + \pgfkeysgetvalue{/pgfplots/table/z}{\pgfplots@plot@tbl@z}% + \pgfkeysgetvalue{/pgfplots/table/z index}{\pgfplots@plot@tbl@zindex}% + \pgfkeysgetvalue{/pgfplots/table/meta}{\pgfplots@plot@tbl@meta}% + \pgfkeysgetvalue{/pgfplots/table/meta index}{\pgfplots@plot@tbl@metaindex}% + % + \pgfkeysgetvalue{/pgfplots/table/x expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@x{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@x\pgfplots@current@point@x + }% + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@x{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/x expr}}% + \let\pgfplots@current@point@x=\pgfmathresult + }% + \fi + % + \pgfkeysgetvalue{/pgfplots/table/y expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@y{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@y\pgfplots@current@point@y + }% + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@y{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/y expr}}% + \let\pgfplots@current@point@y=\pgfmathresult + }% + \fi + % + \ifx\pgfplots@plot@tbl@x\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@xindex}{\pgfplots@table@PTR@x}% + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@x}{\pgfplots@table@PTR@x}% + \fi + \ifx\pgfplots@plot@tbl@y\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@yindex}{\pgfplots@table@PTR@y}% + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@y}{\pgfplots@table@PTR@y}% + \fi + \ifpgfplots@curplot@threedim + % + \pgfkeysgetvalue{/pgfplots/table/z expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@z{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@z\pgfplots@current@point@z + }% + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@z{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/z expr}}% + \let\pgfplots@current@point@z=\pgfmathresult + }% + \fi + \ifx\pgfplots@plot@tbl@z\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@zindex}{\pgfplots@table@PTR@z}% + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@z}{\pgfplots@table@PTR@z}% + \fi + \else + \let\pgfplots@dereferencepointer@and@ASSIGN@z=\relax + \fi + % + % + \def\pgfplots@dereferencepointer@and@ASSIGN@meta{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@meta\pgfplots@current@point@meta + }% + \ifx\pgfplots@plot@tbl@meta\pgfutil@empty + \ifx\pgfplots@plot@tbl@metaindex\pgfutil@empty + \let\pgfplots@dereferencepointer@and@ASSIGN@meta=\relax + \else + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@metaindex}{\pgfplots@table@PTR@meta}% + \fi + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@meta}{\pgfplots@table@PTR@meta}% + \fi + \pgfkeysgetvalue{/pgfplots/table/meta expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@meta{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/meta expr}}% + \let\pgfplots@current@point@meta=\pgfmathresult + }% + \fi + \let\pgfplots@addplotimpl@table@fromfile@listener@PREPARE=\relax +}% +\def\pgfplots@addplotimpl@table@fromfile@listener@{% + \pgfplots@addplotimpl@table@fromfile@listener@PREPARE + \pgfplots@dereferencepointer@and@ASSIGN@x + \pgfplots@dereferencepointer@and@ASSIGN@y + \pgfplots@dereferencepointer@and@ASSIGN@z + \pgfplots@dereferencepointer@and@ASSIGN@meta +}% + +% #1: x, y, or z +% #2: either "plus" or "minus" +\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@#1#2{% + \pgfkeysgetvalue{/pgfplots/table/#1 error #2 index}\pgfplots@plot@tbl@error@index + \pgfkeysgetvalue{/pgfplots/table/#1 error #2}\pgfplots@plot@tbl@error + % + \expandafter\def\csname pgfplots@table@ERRPTR@#1@#2\endcsname{#1 error #2}% + % + \expandafter\def\csname pgfplots@dereferencepointer@and@ASSIGN@error@#1@#2\endcsname{% + \expandafter\pgfplotstablereadevalptr\csname pgfplots@table@ERRPTR@#1@#2\endcsname\pgfmathresult + \expandafter\let\csname pgfplots@current@point@error@#1@#2\endcsname=\pgfmathresult + }% + % + \ifx\pgfplots@plot@tbl@error\pgfutil@empty + \ifx\pgfplots@plot@tbl@error@index\pgfutil@empty + \let\pgfplotsretval=\relax + \expandafter\let\csname pgfplots@dereferencepointer@and@ASSIGN@error@#1@#2\endcsname=\relax + \else + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@index}{\pgfplotsretval}% + \fi + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error}{\pgfplotsretval}% + \fi + \expandafter\let\csname pgfplots@table@ERRPTR@#1@#2\endcsname=\pgfplotsretval + % + \pgfkeysgetvalue{/pgfplots/table/#1 error #2 expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \expandafter\def\csname pgfplots@dereferencepointer@and@ASSIGN@error@#1@#2\endcsname{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/#1 error #2 expr}}% + \expandafter\let\csname pgfplots@current@point@error@#1@#2\endcsname=\pgfmathresult + }% + \fi +}% + +\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare{% + % this here is only evaluated ONCE. + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ x{plus}% + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ x{minus}% + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ y{plus}% + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ y{minus}% + % + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ z{plus}% + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare@ z{minus}% + \else + \let\pgfplots@dereferencepointer@and@ASSIGN@error@z@plus=\relax + \let\pgfplots@dereferencepointer@and@ASSIGN@error@z@minus=\relax + \fi + \let\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare=\relax +} +\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL{% + \pgfplots@addplotimpl@table@fromfile@listener@ + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare + % + \pgfplots@dereferencepointer@and@ASSIGN@error@x@plus + \pgfplots@dereferencepointer@and@ASSIGN@error@x@minus + % + \pgfplots@dereferencepointer@and@ASSIGN@error@y@plus + \pgfplots@dereferencepointer@and@ASSIGN@error@y@minus + % + \ifpgfplots@curplot@threedim + \pgfplots@dereferencepointer@and@ASSIGN@error@z@plus + \pgfplots@dereferencepointer@and@ASSIGN@error@z@minus + \fi + \pgfplots@coord@stream@coord +}% +\def\pgfplots@addplotimpl@table@installkeypath{% + \pgfkeysdef{/pgfplots/table/.unknown}{% + \let\pgfplots@table@curkeyname=\pgfkeyscurrentname + \pgfqkeys{/pgfplots}{\pgfplots@table@curkeyname=##1}% + }% +}% + +% \addplot[#1] table[#2] shell{#3} #4; +% +% #1: arguments to \addplot[...] +% #2: arguments to table[...] +% #3: the argument of plot table shell{...} +% #4: trailing path arguments after plot table shell{...}#4; +\long\def\pgfplots@addplotimpl@table@fromshell#1#2shell#3#4;{% + \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% + \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-shell}% + % + \def\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + \pgfshell[\pgfplots@plot@filename]{#3}\pgfplots@addplotimpl@table@fromfile{#1}{#2}{\pgfplots@plot@filename.out}#4;% +}% + +% This is a backwards-compatibility method to ensure that +% \axis[ybar] +% and +% \addplot[ybar] +% work as documented. +% +% The problem: earlier versions used /pgfplots/ybar for the global +% setting and /tikz/ybar for the local one. Now, both contexts yield +% /pgfplots/ybar in contradiction to the manual. +% +% So, this macro install special handlers to restore the old setting. +\def\pgfplots@install@local@bar@handlers{% + \pgfkeysgetvalue{/pgfplots/xbar/.@cmd}\pgfplotskeys@orig@xbar + \pgfkeysgetvalue{/pgfplots/ybar/.@cmd}\pgfplotskeys@orig@ybar + \pgfkeysgetvalue{/pgfplots/xbar interval/.@cmd}\pgfplotskeys@orig@xbari + \pgfkeysgetvalue{/pgfplots/ybar interval/.@cmd}\pgfplotskeys@orig@ybari + \pgfkeysdef{/pgfplots/xbar}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/xbar}% + \else + \pgfplotskeys@orig@xbar##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/ybar}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/ybar}% + \else + \pgfplotskeys@orig@ybar##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/xbar interval}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/xbar interval}% + \else + \pgfplotskeys@orig@xbari##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/ybar interval}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/ybar interval}% + \else + \pgfplotskeys@orig@ybari##1\pgfeov + \fi + }% +}% + +\def\pgfplots@end@plot{% + \ifpgfplots@curplot@isirrelevant + \else + \pgfplots@countplots@advance + \fi + \pgfkeysvalueof{/pgfplots/execute at end plot@@}% + \pgfkeysvalueof{/pgfplots/execute at end plot}% + \endgroup%<-- close the \begingroup of \pgfplots@addplotimpl@plot@withoptions +} + +% \numplotsofactualtype +% Expands to the number of plots which have been seen in the current +% axis and which have the same type as the actual plot handler. +% +% See also \plotnumofactualtype +\def\pgfplots@numplotsofactualtype{% + \pgfutil@ifundefined{pgfplotssurveyphase@setactiveplothandlers@\pgfplotsplothandlername}{% + 0% + }{% + \csname c@pgfplots@numplotsofactualtype@\pgfplotsplothandlername\endcsname + }% +}% +% use this only inside of \addplot or during the visualization phase +% of a plot. +\def\pgfplots@numplotsofactualtype@duringplot{% + \pgfutil@ifundefined{pgfplotssurveyphase@setactiveplothandlers@\pgfplotsplothandlername@actual}{% + 0% + }{% + \csname c@pgfplots@numplotsofactualtype@\pgfplotsplothandlername@actual\endcsname + }% +}% +% +% +\def\pgfplots@countplots@init{% +% + % + \pgfplotssurveyphase@setactiveplothandlers + % + \let\numplotsofactualtype=\pgfplots@numplotsofactualtype@duringplot + % + % Store this name during the \addplot command. Thus, even if the + % plot handler changes, we will keep this one. + \edef\pgfplotsplothandlername@actual{\pgfplotsplothandlername}% + % + \pgfutil@ifundefined{pgfplotssurveyphase@setactiveplothandlers@\pgfplotsplothandlername@actual}{% + % oh. This is the first time \pgfplotsplothandlername was used + % in this axis. Set its counter to 0 and remember that it has + % been initialised. + \expandafter\xdef\csname c@pgfplots@numplotsofactualtype@\pgfplotsplothandlername@actual\endcsname{0}% + \t@pgfplots@toka=\expandafter{\pgfplotssurveyphase@setactiveplothandlers}% + \t@pgfplots@tokb=\expandafter{\pgfplotsplothandlername@actual}% + \xdef\pgfplotssurveyphase@setactiveplothandlers{% + \the\t@pgfplots@toka + \noexpand\expandafter\noexpand\def\noexpand\csname pgfplotssurveyphase@setactiveplothandlers@\the\t@pgfplots@tokb\noexpand\endcsname{1}% + }% + \expandafter\def\csname pgfplotssurveyphase@setactiveplothandlers@\the\t@pgfplots@tokb\endcsname{1}% + }{% + % ok. do nothing. + }% + % +}% +\def\pgfplots@countplots@advance{% + \global\advance\pgfplots@numplots by1\relax% + % + \expandafter\pgfplotsutil@advancestringcounter@global\csname c@pgfplots@numplotsofactualtype@\pgfplotsplothandlername@actual\endcsname +}% + +% \addplot[#1] [#2] {#3} #4; +\long\def\pgfplots@addplotimpl@coordinates#1#2plot coordinates#3#4;{\pgfplots@addplotimpl@coordinates@{#1}{#2}{#3}{#4}}% +% \addplot[#1] [#2] coordinates {#3} #4; +\long\def\pgfplots@addplotimpl@coordinates@#1#2#3#4{% + \def\pgfplotssurveyphaseinputclass{coordinates}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@PREPARE@COORD@STREAM{#4}% + \ifpgfplots@curplot@threedim + \pgfplots@coord@stream@foreach@threedim{#3}% + \else + \pgfplots@coord@stream@foreach{#3}% + \fi +}% + +{ + % A block which handles active semicolons. + % + % ATTENTION: this block does only work if + % \pgfplots@addplotimpl.... changes are reflected here! + % + \catcode`\;=\active + \globaldefs=1 + % 'AS' == 'active semicolon' + % 'IS' == 'inactive semicolon' + \let\pgfplots@gobble@until@semicolon@IS=\pgfplots@gobble@until@semicolon + \let\pgfplots@addplotimpl@expression@IS=\pgfplots@addplotimpl@expression + \let\pgfplots@addplotimpl@expression@curly@IS=\pgfplots@addplotimpl@expression@curly + \let\pgfplots@addplotimpl@function@opt@IS=\pgfplots@addplotimpl@function@opt + \let\pgfplots@addplotimpl@file@opt@IS=\pgfplots@addplotimpl@file@opt + \let\pgfplots@addplotimpl@fillbetween@opt@IS=\pgfplots@addplotimpl@fillbetween@opt + \let\pgfplots@addplotimpl@table@fromstructure@IS=\pgfplots@addplotimpl@table@fromstructure + \let\pgfplots@addplotimpl@table@fromfile@IS=\pgfplots@addplotimpl@table@fromfile + \let\pgfplots@addplotimpl@graphics@IS=\pgfplots@addplotimpl@graphics@ + \let\pgfplots@addplotimpl@coordinates@IS=\pgfplots@addplotimpl@coordinates + % + \def\pgfplots@gobble@until@semicolon@AS#1;{} + \long\def\pgfplots@addplotimpl@expression@AS#1#2(#3,#4)#5;{\pgfplots@addplotimpl@expression@{#1}{#2}{#3}{#4}{#5}}% + \long\def\pgfplots@addplotimpl@expression@curly@AS#1#2#3#4;{\pgfplots@addplotimpl@expression@curly@{#1}{#2}{#3}{#4}}% + \def\pgfplots@addplotimpl@function@opt@AS#1#2[#3]#4#5;{\pgfplots@addplotimpl@function@opt@{#1}{#2}{#3}{#4}{#5}}% + \def\pgfplots@addplotimpl@file@opt@AS#1#2[#3]#4#5;{\pgfplots@addplotimpl@file@opt@{#1}{#2}{#3}{#4}{#5}}% + \long\def\pgfplots@addplotimpl@fillbetween@opt@AS#1#2[#3]#4;{\pgfplots@addplotimpl@fillbetween@opt@{#1}{#2}{#3}{#4}}% + \long\def\pgfplots@addplotimpl@table@fromstructure@AS#1#2from#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% + \long\def\pgfplots@addplotimpl@table@fromfile@AS#1#2#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% + \long\def\pgfplots@addplotimpl@coordinates@AS#1#2plot coordinates#3#4;{\pgfplots@addplotimpl@coordinates@{#1}{#2}{#3}{#4}}% + \long\def\pgfplots@addplotimpl@graphics@AS#1#2[#3]#4#5;{\pgfplots@addplotimpl@graphics@@{#1}{#2}{#3}{#4}{#5}}% + % + % Checks whether ';' is an active character and, if that is the + % case, modifies all public macros for it. + \pgfplots@appendto@activesemicolon@switcher{% + \let\pgfplots@gobble@until@semicolon=\pgfplots@gobble@until@semicolon@AS + \let\pgfplots@addplotimpl@expression=\pgfplots@addplotimpl@expression@AS + \let\pgfplots@addplotimpl@expression@curly=\pgfplots@addplotimpl@expression@curly@AS + \let\pgfplots@addplotimpl@function@opt=\pgfplots@addplotimpl@function@opt@AS + \let\pgfplots@addplotimpl@file@opt=\pgfplots@addplotimpl@file@opt@AS + \let\pgfplots@addplotimpl@fillbetween@opt=\pgfplots@addplotimpl@file@opt@AS + \let\pgfplots@addplotimpl@table@fromstructure=\pgfplots@addplotimpl@table@fromstructure@AS + \let\pgfplots@addplotimpl@table@fromfile=\pgfplots@addplotimpl@table@fromfile@AS + \let\pgfplots@addplotimpl@coordinates=\pgfplots@addplotimpl@coordinates@AS + \let\pgfplots@addplotimpl@graphics@=\pgfplots@addplotimpl@graphics@AS + }% +} + +\newif\ifpgfplots@update@limits@for@one@point@ISCLIPPED +\def\pgfplots@math@ONE{1.0}% + +\def\pgfplots@invoke@prefilter{% + \pgfkeysvalueof{/pgfplots/pre filter/.@cmd}\pgfeov% +}% +\def\pgfplots@invoke@filter#1#2{% + \pgfkeysvalueof{/pgfplots/#2 filter/.@cmd}#1\pgfeov% +}% +\def\pgfplots@invoke@filter@xyz{% + \pgfkeysgetvalue{/pgfplots/filter point/.@cmd}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key + \else + \pgfkeyslet{/data point/x}\pgfplots@current@point@x + \pgfkeyslet{/data point/y}\pgfplots@current@point@y + \pgfkeyslet{/data point/z}\pgfplots@current@point@z + \pgfplots@loc@TMPa\pgfeov% + \pgfkeysgetvalue{/data point/x}\pgfplots@current@point@x + \pgfkeysgetvalue{/data point/y}\pgfplots@current@point@y + \pgfkeysgetvalue{/data point/z}\pgfplots@current@point@z + \fi% +}% + +% #1 the target which will contain the filter +% #2 a math expression. +\def\pgfplots@install@filter@expression#1#2{% + \pgfkeysdef{/pgfplots/#1}{\pgfplots@filter@expression{#1}}% + \pgfkeyssetvalue{/pgfplots/#1/@expressionvalue}{#2}% +}% + +% Executes #2 if the filter key was defined by +% \pgfplots@install@filter@expression. +% +% #1 the target which will contain the filter (like 'x filter') +% #2: true code +% #3: false code +\def\pgfplots@ifisfilterexpression#1#2#3{% + \pgfkeysgetvalue{/pgfplots/#1/.@cmd}\pgfplots@loc@TMPc + \long\def\pgfplots@loc@TMPd##1\pgfeov{\pgfplots@filter@expression{#1}}% + \ifx\pgfplots@loc@TMPc\pgfplots@loc@TMPd + #2\relax + \else + #3\relax + \fi +}% + +% the key name (example: 'x filter') +\def\pgfplots@filter@expression#1{% + \begingroup + \pgfkeys{/pgf/fpu=true}% + \pgfkeysgetvalue{/pgfplots/#1/@expressionvalue}\pgfplots@loc@TMPa + \pgfmathparse{\pgfplots@loc@TMPa}% + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + +% this is a convenience macro to save storage in the long coordinate +% lists. +\def\pgfplots@stream#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} +\def\pgfplots@stream@#1#2#3{\def\pgfplots@current@point@coordindex{#1}\pgfplots@stream{#2}{#3}} +\def\pgfplots@stream@withmeta#1#2#3{\def\pgfplots@current@point@meta{#3}\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} +\def\pgfplots@stream@withmeta@#1#2#3#4{\def\pgfplots@current@point@coordindex{#1}\pgfplots@stream@withmeta{#2}{#3}{#4}} + +\def\pgfplots@stream@decode@and@apply#1#2#3#4{% + \def\pgfplots@current@point@coordindex{#1}% + \pgfplotsaxisdeserializedatapointfrom@private{#2}% + \pgfplotstreampoint{\pgfqpoint{#3}{#4}}% +} + +% Takes a sequence of PREPARED coordinates which are given in floating +% point representation and applies the data scaling trafo (if +% necessary). +% +% Any coordinate will be plotted with the selected PGF plot handler. +% +% This stream is designed to be done at the end of an axis. +% See \pgfplots@coord@stream@finalize@storedcoords@START +% +\def\pgfplots@coord@stream@INIT@finalize@storedcoords{% + % + % Init the plot handlers: + \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler + \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% + % + \ifpgfplots@threedim + \pgfplots@apply@zbuffer + \fi + % + \pgfplots@perpointmeta@preparetrafo + % + \ifpgfplots@stackedmode + \pgfplots@stacked@visphase@beginplot + \fi + \ifpgfplots@errorbars@enabled + \pgfplots@errorbars@visphase@begin + \fi + \pgfplots@prepare@visualization@dependencies + % + \def\pgfplots@loc@TMPa{0}% <-- if (collectmark positions) + \ifpgfplots@scatterplotenabled + \def\pgfplots@loc@TMPa{1}% collect mark positions even if 'mark=none'! scatter might not even use markers. + \fi + \ifx\tikz@plot@mark\pgfutil@empty + \else + \def\pgfplots@loc@TMPa{1}% + \fi + % + % OK, initialize the plot handler. + \pgfplotsresetplothandler + \pgfplots@basiclevel@plothandler + \expandafter\pgfplotsplothandlerdeserializestatefrom\expandafter{\pgfplots@serialized@state@plothandler}% + % + \pgfplots@LUA@visualization@of@current@plot + % + \pgfplotstreamstart + % + % Now, set up coordinate streams. + \def\pgfplots@coord@stream@start@{% + \let\pgfplots@data@scaletrafo@result=\pgfutil@empty + \c@pgfplots@coordindex=0 + }% + \def\pgfplots@coord@stream@end@{% + \ifpgfplots@stackedmode + \pgfplots@stacked@visphase@endplot + \fi + \ifpgfplots@errorbars@enabled + \pgfplots@errorbars@visphase@end + \fi + \pgfplots@addplot@get@named@startendpoints@command\pgfplots@loc@TMPa + \pgfplots@loc@TMPa + \pgfplotstreamend + }% + \begingroup + \let\E=\noexpand + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \pgfplots@coord@stream@INIT@finalize@storedcoords@prepare@scaletrafomacro + % + % Will be inserted in one of two possible places below (to collect + % marker positions) + % This finalize command maps the logical coordinate into PGF's + % point space. Furthermore, it collects marker coordinates + % (properly clipped by position) if markers are required (see + % above). + % + % It is prepared here to eliminate if's. + \gdef\pgfplots@coord@stream@finalize@currentpt{% + % + % NOTE: this here INVALIDATES \pgfplotlastpoint. However, we assign a correct value + % for that macro after all coordinates have been assigned - and we do it in a way + % which respects the special coordinates of 'patch plots'. + % + \pgfplotstreampoint{}% it will simply take \pgf@x and \pgf@y! + % + \advance\c@pgfplots@coordindex by1 + }% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \endgroup +% +%\message{Prepared macro \string \pgfplotsaxisvisphasetransformcoordinate {\meaning\pgfplotsaxisvisphasetransformcoordinate}}% +%\message{Prepared macro \string \pgfplots@coord@stream@finalize@currentpt {\meaning\pgfplots@coord@stream@finalize@currentpt}}% + \if1\b@pgfplots@LUA@visualization@enabled + \def\pgfplots@coord@stream@coord@{% + \ifx\pgfplots@current@point@x\pgfutil@empty% this implements `unbounded coords=jump', for example + \pgfplotsplothandlervisualizejump + \else + \pgfplotscoordmath{x}{tofixed}{\pgfplots@current@point@x}\let\pgfplots@current@point@x=\pgfmathresult + \pgfplotscoordmath{y}{tofixed}{\pgfplots@current@point@y}\let\pgfplots@current@point@y=\pgfmathresult + \ifpgfplots@curplot@threedim + \pgfplotscoordmath{z}{tofixed}{\pgfplots@current@point@z}\let\pgfplots@current@point@z=\pgfmathresult + \fi + % no need to call this here -- we got them from LUA: + % \pgfplotsaxis@toPGF@coords + \pgfplots@coord@stream@finalize@currentpt + \fi + }% + \else + \def\pgfplots@coord@stream@coord@{% + \ifpgfplots@stackedmode + \pgfplots@stacked@visphase@stream@coord@ + \fi + \ifx\pgfplots@current@point@x\pgfutil@empty% this implements `unbounded coords=jump', for example + \pgfplotsplothandlervisualizejump + \else + \pgfplotsaxisvisphasegetpoint + \pgfplots@coord@stream@finalize@currentpt + \fi + }% + \fi +} + +\def\pgfplots@LUA@visualization@init{% + \ifpgfplots@LUA@backend@supported + \edef\pgfplots@loc@TMPa{% + \directlua{pgfplots.texVisualizationInit(\plotnum, \ifpgfplots@curplot@threedim true\else false\fi)}% + }% + \if1\pgfplots@loc@TMPa + \pgfplots@log{\pgfplots@LUA@loglevel@debug}{lua backend=true: Activating partial LUA backend for visualization of plot \plotnum.}% + \else + \pgfplots@LUA@backend@supportedfalse + \fi + \fi +}% + +% Takes the current point (defined by a set of macros) as input and defines \pgf@x and \pgf@y +% as the output point. It also defines +% \pgfplots@current@point@x and its variants to contain the +% transformed canvas coords (those which can be given to +% \pgfplotsqpointxyz). +% +\def\pgfplotsaxisvisphasegetpoint{% + \pgfplotsaxisvisphasetransformcoordinate\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@z% + \pgfplotsaxisvisphasepreparedatapoint + \pgfplotsaxis@toPGF@coords +}% + +\def\pgfplotsaxis@toPGF@coords{% + \ifpgfplots@curplot@threedim + \pgfplotsqpointxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@current@point@z}% + \else + \pgfplotsqpointxy{\pgfplots@current@point@x}{\pgfplots@current@point@y}% + \fi +}% + +% Returns the current points into the keys +% /data point/x +% /data point/y +% /data point/z +% /data point/meta +\def\pgfplotspointgetcoordinates{% + \pgfplotspointgetnormalizedcoordinates + \pgfplotspointgetcoordinatesfromnormalized +}% + +% PRECONDITION: \pgfplots@current@point@x and its variants is given in +% TRANSFORMED format, i.e. we assume that we are in the visualization +% phase after the coordinates have been prepared. +% POSTCONDITION: the untransformed #1 coordinate is assigned to +% \pgfplotsretval +\def\pgfplotspointgetnormalizedcoordinates@#1{% + % XXX : this is slower than it used to be - in 1.11, I simply + % remembered 'x untransformed'! I switched it to this lazy + % computation due to the LUA backend in which case remembering it + % leads to extensive (=expensive?) communication between lua and + % TeX. Does it hurt here? Scatter plots compute this stuff... + \expandafter\let\expandafter\pgfplotsretval\csname pgfplots@current@point@#1\endcsname + \ifx\pgfplotsretval\pgfutil@empty + \else + \pgfplots@if{pgfplots@apply@datatrafo@#1}{% + \pgfplotscoordmath{#1}{datascaletrafo inverse}{\pgfplotsretval}% + \let\pgfplotsretval=\pgfmathresult + }{}% + \fi +}% + +% Same as \pgfplotspointgetcoordinates, but the resulting values are +% for use in 'normalized axis cs'. +\def\pgfplotspointgetnormalizedcoordinates{% + \pgfplotspointgetnormalizedcoordinates@ x% + \pgfkeyslet{/data point/x}\pgfplotsretval + % + \pgfplotspointgetnormalizedcoordinates@ y% + \pgfkeyslet{/data point/y}\pgfplotsretval + % + \ifpgfplots@curplot@threedim + \pgfplotspointgetnormalizedcoordinates@ z% + \pgfkeyslet{/data point/z}\pgfplotsretval + \else + \pgfkeyslet{/data point/z}\pgfutil@empty + \fi + % + \pgfkeyslet{/data point/meta}\pgfplots@current@point@meta + \edef\pgfplots@loc@TMPa{\pgfplots@current@point@coordindex}% + \pgfkeyslet{/data point/index}\pgfplots@loc@TMPa +}% + +% Assumes that we are given normalized coordinates (i.e. those for use +% in 'normalized axis cs') and transforms them into those which are +% for use in 'axis cs'. +% +% Accepts an optional argument in square brackets, namely one or more +% options in the /pgfplots/coords key path (see below). +\def\pgfplotspointgetcoordinatesfromnormalized{% + \pgfutil@ifnextchar[{\pgfplotspointgetcoordinatesfromnormalized@opt}{\pgfplotspointgetcoordinatesfromnormalized@opt[]}% +}% + +% Defines where to expect INPUT coordinates +% \pgfplotspointgetcoordinatesfromnormalized[path=/data point/ +% would expect input coordinates +% /data point/x +% /data point/y +% /data point/z +\pgfkeyssetvalue{/pgfplots/coords/path}{/data point} + +% \pgfplotspointgetcoordinatesfromnormalized[target path=/data point/zero/ +% would write output coordinates +% /data point/zero/x +% /data point/zero/y +% /data point/zero/z +\pgfkeyssetvalue{/pgfplots/coords/target path}{\pgfkeysvalueof{/pgfplots/coords/path}} + +\def\pgfplotspointgetcoordinatesfromnormalized@opt[#1]{% + \begingroup + \pgfqkeys{/pgfplots/coords}{#1}% + \pgfkeysgetvalue{/pgfplots/coords/path}\pgfplots@path + \pgfkeysgetvalue{/pgfplots/coords/target path}\pgfplots@path@trg + \pgfkeysifdefined{\pgfplots@path/x}{}{% + \pgfplots@error{Illegal argument: '\pgfplots@path' is no valid data point path (\pgfplots@path/x does not exist)}% + }% + \pgfkeysgetvalue{\pgfplots@path/x}\pgfplots@loc@x + \pgfkeysgetvalue{\pgfplots@path/y}\pgfplots@loc@y + \pgfkeysgetvalue{\pgfplots@path/z}\pgfplots@loc@z + % + \pgfplotspointgetcoordinatesfromnormalized@transform x\pgfplots@loc@x% + \pgfplotspointgetcoordinatesfromnormalized@transform y\pgfplots@loc@y% + \ifpgfplots@threedim + \pgfplotspointgetcoordinatesfromnormalized@transform z\pgfplots@loc@z% + \fi + \xdef\pgfplots@glob@TMPa{% + \noexpand\pgfkeyssetvalue{\pgfplots@path@trg/x}{\pgfplots@loc@x}% + \noexpand\pgfkeyssetvalue{\pgfplots@path@trg/y}{\pgfplots@loc@y}% + \noexpand\pgfkeyssetvalue{\pgfplots@path@trg/z}{\pgfplots@loc@z}% + }% + \endgroup + \pgfplots@glob@TMPa +}% +\def\pgfplotspointgetcoordinatesfromnormalized@transform#1#2{% + \pgfplots@if{pgfplots@#1islinear}{% + \pgfplotscoordmath{#1}{tofixed}{#2}% + }{% + \pgfplotscoordmath{#1}{exp}{#2}% + }% + \let#2=\pgfmathresult + \pgfplots@coord@inv@trafo@apply{#1}{#2}% + \let#2=\pgfmathresult +}% + +% Defines an optimized and matching \pgfplotsaxisvisphasetransformcoordinate +% during the coordinate finalization step in \end{axis}. +\def\pgfplots@coord@stream@INIT@finalize@storedcoords@prepare@scaletrafomacro{% + \begingroup + \let\E=\noexpand + % + % \pgfplotsaxisvisphasetransformcoordinate + % Maps a point to the low level xyz coordinate system by applying + % data scaling transformations. + % + % This method should be invoked for every coordinate before it can + % be drawn. + % + % It is prepared here to eliminate if's. + % + % Arguments: + % #1 : a MACRO containing the x value + % #2 : a MACRO containing the y value + % #3 : a MACRO containing the z value + % + % PRECONDITION: + % - the visualization phase is running. + % - #1,#2,#3 are defined and contain + % values resulting from the survey phase. + % + % POSTCONDITION + % - #1,#2,#3 will be redefined to contain data which is + % readily usable by low level pgf plot handlers for + % visualization. + % + % @see \pgfplotsaxisvisphasepreparedatapoint + \xdef\pgfplotsaxisvisphasetransformcoordinate##1##2##3{% + \ifpgfplots@apply@datatrafo@x + \E\pgfplotscoordmath{x}{datascaletrafo}{##1}% + \E\let##1=\E\pgfmathresult + \fi + \ifpgfplots@apply@datatrafo@y + \E\pgfplotscoordmath{y}{datascaletrafo}{##2}% + \E\let##2=\E\pgfmathresult + \fi + \ifpgfplots@curplot@threedim + \ifpgfplots@apply@datatrafo@z + \E\pgfplotscoordmath{z}{datascaletrafo}{##3}% + \E\let##3=\E\pgfmathresult + \fi + \fi + % \t@pgfplots@tokc=\expandafter{\pgfplots@data@scaletrafo@result}% + % \edef\pgfplots@data@scaletrafo@result{\the\t@pgfplots@tokc(\pgfplots@current@point@x,\pgfplots@current@point@y)}% + }% + % + % Just before the visualization phase can call the low level + % interface, this method is called to handle final changes. + % It is currently only used by the stacked plot interface. + \xdef\pgfplotsaxisvisphasepreparedatapoint{% + \ifpgfplots@stackedmode + % all these calls work with pgfmath; no more floating point + % arithmetics are applied. + \E\pgfplots@stacked@visphasepreparedatapoint% + \fi + }% + % + \endgroup +} + +% Defines \pgfmathresult to contain the transformed coordinate entry +% #1: one of x,y ,or z +% #2: the input value +\def\pgfplotsaxisvisphasetransformcoordinateentry#1#2{% + \pgfplots@if{pgfplots@apply@datatrafo@#1}{% + \pgfplotscoordmath{#1}{datascaletrafo}{#2}% + }{% + \edef\pgfmathresult{#2}% + }% +}% + +\def\pgfplots@addplot@get@named@startendpoints@command#1{% + \ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty + % empty plot. + \def#1{% + \pgfcoordinate{current plot begin}{\pgfplotspointaxisorigin}% + \pgfcoordinate{current plot end}{\pgfplotspointaxisorigin}% + }% + \else + \ifpgfplots@curplot@threedim + \edef#1{% + \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfplotsqpointxyz{\pgfplots@currentplot@firstcoord@x}{\pgfplots@currentplot@firstcoord@y}{\pgfplots@currentplot@firstcoord@z}}% + \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfplotsqpointxyz{\pgfplots@currentplot@lastcoord@x}{\pgfplots@currentplot@lastcoord@y}{\pgfplots@currentplot@lastcoord@z}}% + }% + \else + \edef#1{% + \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@firstcoord@x}{\pgfplots@currentplot@firstcoord@y}}% + \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@lastcoord@x}{\pgfplots@currentplot@lastcoord@y}}% + }% + \fi + \fi +}% + +% This is the pgfplots implementation for 'node[pos=<fraction>]'. +% Besides modifications of the transformation matrix, it also defines the COORDINATES of the point to +% /data point/x +% /data point/y +% /data point/z +% (or more keys which depend on the plot handler). +\def\pgfplots@plot@timer{% + \pgfplotstransformplotattime{\tikz@time}% +} + +% Installs a transformation matrix such that (0,0) is the point of the +% current plot with fraction #1. +% +% This does actually nothing more than using +% \pgfplotspointplotattime{#1} as shift and using the slope of the +% curve at that point to set up the 'sloped' rotation (if enabled). +\def\pgfplotstransformplotattime#1{% + \pgftransformshift{\pgfplotspointplotattime{#1}}% + \ifpgfresetnontranslationattime% + \pgftransformresetnontranslations% + \fi% + \ifpgfslopedattime% + \pgfplotsplothandlertransformslopedattime{#1}{\pgfplotspointplotattimefirst}{\pgfplotspointplotattimesecond}% + \fi% +} + +\def\pgfplotspointplotattimeclearcache{% + \global\let\pgfplotspointplotattime@cache=\pgfutil@empty + \gdef\pgfplotspointplotattime@cachesize{0}% +}% +\pgfplotspointplotattimeclearcache +\def\pgfplotspointplotattime@cachesize@max{20} + +% Checks if the cache for \pgfplotspointplotattime has a cached entry for '#1'. +% POSTCONDITION: +% if \ifpgfplots@loc@tmp is true, the value(s) from the cache have been retrieved successfully. +% if \ifpgfplots@loc@tmp is false, there is not hit. +\def\pgfplotspointplotattimegetfromcache#1{% + \pgf@xa=#1pt % + \pgfplotspointplotattime@cache + \pgfkeysifdefined{/data point/@pos \the\pgf@xa/segment \pgfkeysvalueof{/tikz/pos segment}}{% + \pgfkeysvalueof{/data point/@pos \the\pgf@xa/segment \pgfkeysvalueof{/tikz/pos segment}}% + \pgfplots@loc@tmptrue + }{% + \pgfplots@loc@tmpfalse + }% +}% +\def\pgfplotspointplotattimeaddtocache#1{% + \pgfplotsutil@advancestringcounter@global\pgfplotspointplotattime@cachesize + \ifnum\pgfplotspointplotattime@cachesize=\pgfplotspointplotattime@cachesize@max + \pgfplotspointplotattimeclearcache + \fi + \pgf@xa=#1pt % + \edef\pgfplots@loc@TMPa{% + \noexpand\gdef\noexpand\pgfplotspointplotattimefirst{\pgfplotspointplotattimefirst}% + \noexpand\gdef\noexpand\pgfplotspointplotattimesecond{\pgfplotspointplotattimesecond}% + \noexpand\gdef\noexpand\pgfplotspointplotattimecoords{\pgfplotspointplotattimecoords}% + }% + \t@pgfplots@toka=\expandafter{\pgfplotspointplotattime@cache}% + \t@pgfplots@tokb=\expandafter{\pgfplots@loc@TMPa}% + \xdef\pgfplotspointplotattime@cache{% + \the\t@pgfplots@toka + \noexpand\pgfkeyssetvalue{/data point/@pos \the\pgf@xa/segment \pgfkeysvalueof{/tikz/pos segment}}{\the\t@pgfplots@tokb}% + }% +} + +% Sets (\pgf@x,\pgf@y) to the point of the current plot with fraction #1. +% For #1 = 0, this is the first point. +% For #1 = 1, this is the last point. +% For #1 = 0.5, it is the middle of the plot. +% The argument '#1' is optional: if you leave it away, the current value of the 'pos' key will be used. +% This method will work for most plot handlers, although some of them might be unsupported. +% +% As a side-effect, it defines the (global) macros +% - \pgfplotspointplotattimefirst the start coordinate of the line segment containing #1 +% - \pgfplotspointplotattimesecond the end coordinate of the line segment containing #1 +% - \pgfplotspointplotattimecoords the coordinates of #1 +% The first two are interesting in order to allow the computation of gradients. +% \pgfplotsplothandlerpointtokeys{/data point}% +% for the \pgfplotspointplotattimecoords point +% +% Any of these macros can be decoded using +% \pgfplotsplothandlerdeserializepointfrom\pgfplotspointplotattimesecond +% \pgfplotsaxisvisphasegetpoint +% +% @see \pgfplotsplothandlerpointtokeys +\def\pgfplotspointplotattime{% + \pgfutil@ifnextchar\bgroup{\pgfplotspointplotattime@}{\pgfplotspointplotattime@{\tikz@time}}% +} +\def\pgfplotspointplotattime@#1{% + \edef\pgfplots@loc@TMPa{#1}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \pgfplots@error{Sorry, the provided fraction of the plot is empty (maybe the argument of 'pos' has been cleared by the tikz node processing). Please provide a valid 'pos' argument}% + \else + \pgfplotspointplotattimegetfromcache{#1}% + \ifpgfplots@loc@tmp + % CACHE HIT! +%\message{CACHE HIT for \string\pgfplotspointplotattime{#1}^^J}% + \else +%\message{NO cache hit for \string\pgfplotspointplotattime{#1}^^J}% + \begingroup + % + \if1\b@pgfplots@LUA@visualization@enabled + \ifx\pgfplots@plot@timer@args\relax + \expandafter\gdef\expandafter\pgfplots@plot@timer@args\expandafter{% + \directlua{pgfplots.texGetSurveyedCoordsToPgfplots()}% + }% + \fi + \let\pgfplotsaxisdeserializedatapointfrom@private=\pgfplotsaxisdeserializedatapointfrom@private@nonLUA + \else + \global\let\pgfplots@plot@timer@args=\pgfplots@stored@current@data + \fi + % + % + \edef\pgfplots@time{#1}% + \pgfplotscoordmathparsemacro{default}{\pgfplots@time}% + \pgfkeysgetvalue{/tikz/pos segment}\pgfplots@pos@segment + % +\iffalse + % this here is a simple experiment which finds x or y + % values. IMPLEMENT IT! + \def\pgfplotspointattime@do@set@current@value{% + \pgfplotscoordmath{default}{parsenumber}{\pgfplots@current@point@y}% + \let\pgfplotspointattime@value@current=\pgfmathresult + }% + \def\pgfplotspointattime@do@set@target@value{% + \let\pgfplotspointattime@value@target=\pgfplots@time + }% + \def\pgfplots@ifpointattime@do@set@current@value@accumulates##1##2{##2}% +\fi + % + \let\pgfplotspointattime@do=\relax + \let\pgfplots@coord@stream@start@=\pgfplots@coord@stream@start@plot@at@time + \let\pgfplots@coord@stream@coord@=\pgfplots@coord@stream@coord@plot@at@time + \def\pgfplots@coord@stream@end@{}% + \pgfplots@ifpointattime@do@set@current@value@accumulates{% + % 1. compute the total length of the plot (by integrating along a linear spline) + % + % we need to compute the TOTAL length in order to set the + % target values. + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@plot@timer@args}% + }{}% + % + \pgfplotspointattime@do@set@target@value + % + \pgfplotscoordmath{default}{zero}% + \let\pgfplots@len@last=\pgfmathresult + \let\pgfplots@len@last@last=\pgfplots@len@last +%\message{plot at time (#1, segment \pgfplots@pos@segment): total length=\pgfplotspointattime@value@current; target len \pgfplotspointattime@value@target\space (#1)^^J}% + % + \def\pgfplots@HIT{0}% + \let\pgfplots@last@last=\pgfutil@empty + \let\pgfplots@coord@stream@coord@=\pgfplots@coord@stream@coord@plot@at@time + \let\pgfplotspointattime@do=\pgfplotspointattime@do@find@target@value + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@plot@timer@args}% + \if\pgfplots@HIT0% + \let\pgfplots@last@processed=\pgfplots@last@last + \let\pgfplots@len@last=\pgfplots@len@last@last + \pgfplotspointattime@pointbetween@two + \fi + \endgroup + \pgfplotspointplotattimeaddtocache{#1}% + \fi + \pgfplotsplothandlerdeserializepointfrom\pgfplotspointplotattimecoords + \pgfplotscoordmath{x}{tofixed}{\pgfplots@current@point@x}% + \pgfplots@coord@inv@trafo@apply{x}{\pgfmathresult}% + \let\pgfplots@current@point@x=\pgfmathresult + \pgfplotscoordmath{y}{tofixed}{\pgfplots@current@point@y}% + \pgfplots@coord@inv@trafo@apply{y}{\pgfmathresult}% + \let\pgfplots@current@point@y=\pgfmathresult + \ifpgfplots@curplot@threedim + \pgfplotscoordmath{z}{tofixed}{\pgfplots@current@point@z}% + \pgfplots@coord@inv@trafo@apply{z}{\pgfmathresult}% + \let\pgfplots@current@point@z=\pgfmathresult + \fi + \pgfplotsplothandlerpointtokeys{/data point}% + \fi +} + +% coordinate streaming method for use in +% \pgfplotspointplotattime +\def\pgfplots@coord@stream@start@plot@at@time{% + \ifx\pgfplots@pos@segment\pgfutil@empty + \let\c@pgfplots@segments=\pgfutil@empty + \else + \def\c@pgfplots@segments{0}% + \c@pgf@countd=\pgfplots@pos@segment\relax + \edef\pgfplots@pos@segment{\the\c@pgf@countd}% + \fi + \pgfplotscoordmath{default}{zero}% + \let\pgfplotspointattime@value@current=\pgfmathresult + \let\pgfplots@last@processed=\pgfutil@empty + \def\pgfplots@last@was@empty{1}% +}% + + +% coordinate streaming method for use in +% \pgfplotspointplotattime +% +% It invokes \pgfplotspointattime@do{} whenever is has found a line +% segment. +\def\pgfplots@coord@stream@coord@plot@at@time{% +%\message{plot at time (#1, segment \pgfplots@pos@segment): processing (\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)^^J}% + \ifx\pgfplots@current@point@x\pgfutil@empty + \if1\pgfplots@last@was@empty + \else + % oh. a jump... start new length segment + \ifx\c@pgfplots@segments\pgfutil@empty + \else + \ifx\pgfplots@pos@segment\c@pgfplots@segments + \let\pgfplots@coord@stream@coord@=\relax + \fi + \pgfplotsutil@advancestringcounter\c@pgfplots@segments + \fi + \fi + \let\pgfplots@last@processed=\pgfutil@empty + \def\pgfplots@last@was@empty{1}% + \else + \ifx\pgfplots@pos@segment\c@pgfplots@segments + \pgfplotsplothandlerserializepointto{\pgfplots@cur}% + \pgfplotspointattime@do@set@current@value + % + \ifx\pgfplots@last@processed\pgfutil@empty + \else + \pgfplotspointattime@do + \fi + % + \let\pgfplots@len@last@last=\pgfplots@len@last + \let\pgfplots@len@last=\pgfplotspointattime@value@current + \let\pgfplots@last@last=\pgfplots@last@processed + \let\pgfplots@last@processed=\pgfplots@cur + \fi + \def\pgfplots@last@was@empty{0}% + \fi +}% + +% A macro which is invoked whenever \pgfplotspointplotattime found a +% line segment. +% +% INPUT: +% - \pgfplots@cur : serialized current point. This current point's +% properties are available in the macros +% \pgfplots@current@point@[xyz] etc. +% - \pgfplots@last@processed : serialized last point +% - \pgfplotspointattime@value@current : the accumulated length so far +% +\def\pgfplotspointattime@do{} + +% \pgfplots@ifpointattime@do@set@current@value@accumulates{<true code>}{<false code>} +% +% is invokes to test if \pgfplotspointattime@do@set@current@value +% accumulates stuff. If so, it will invoke <true code>. If it does NOT +% accumulate stuff, it will invoke <false code> +\def\pgfplots@ifpointattime@do@set@current@value@accumulates#1#2{% + % the default "time fraction" implementation accumulates: + #1\relax +} + +\def\pgfplotspointattime@do@set@current@value{% + \ifx\pgfplots@last@processed\pgfutil@empty + \else + \pgfplotsplothandlersurveydifflen{\pgfplots@last@processed}{\pgfplots@cur}% + \pgfplotscoordmath{default}{op}{add}{{\pgfmathresult}{\pgfplotspointattime@value@current}}% + \let\pgfplotspointattime@value@current=\pgfmathresult + \fi +%\message{plot at time (#1, segment \pgfplots@pos@segment): length \pgfplotspointattime@value@current^^J}% +}% + +% Needs to define \pgfplotspointattime@value@target . +% +% This value is the search target: once the loop realizes that it +% passed \pgfplotspointattime@value@target, it will report a hit in the current +% interval. +\def\pgfplotspointattime@do@set@target@value{% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfplots@time}{\pgfplotspointattime@value@current}}% + \let\pgfplotspointattime@value@target=\pgfmathresult +}% + +\def\pgfplotspointattime@do@find@target@value{% + % compare \pgfplotspointattime@value@target and \pgfplotspointattime@value@current to see if + % we passed the target interval: + \pgfplotscoordmath{default}{if less than} + {\pgfplotspointattime@value@target} + {\pgfplotspointattime@value@current} + {% HIT! + \def\pgfplots@HIT{1}% + \pgfplotspointattime@pointbetween@two + % + % we cannot stop the loop; what we can turn it into no-op: + \let\pgfplots@coord@stream@coord@=\relax + }{% + }% +}% + +\def\pgfplotspointattime@pointbetween@two{% + \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotspointattime@value@target}{\pgfplots@len@last}}% + \let\pgfplots@tmp=\pgfmathresult + \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotspointattime@value@current}{\pgfplots@len@last}}% + \pgfplotscoordmath{default}{op}{divide}{{\pgfplots@tmp}{\pgfmathresult}}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@time@between@two=\pgfmathresult +%\message{HIT of \pgfplotspointattime@value@target\space between \pgfplots@len@last\space and \pgfplotspointattime@value@current\space (\pgfplots@time@between@two)^^J}% + \ifx\pgfplots@last@processed\pgfutil@empty + \pgfplotsplothandlerserializepointto{\pgfplots@cur}% + \else + \pgfplotsplothandlersurveypointattime{\pgfplots@time@between@two}{\pgfplots@last@processed}{\pgfplots@cur}% + \fi + \pgfplotsplothandlerserializepointto\pgfplots@loc@TMPa + \global\let\pgfplotspointplotattimecoords=\pgfplots@loc@TMPa + \pgfplotsaxisvisphasegetpoint + \global\let\pgfplotspointplotattimefirst=\pgfplots@last@processed + \global\let\pgfplotspointplotattimesecond=\pgfplots@cur +}% + + +% #1 : either x,y, or z +% #2 : the argument on which the inv trafo shall be applied. It has to +% be a fixed point number. +\def\pgfplots@coord@inv@trafo@apply#1#2{% + \edef\pgfmathresult{#2}% + \pgfkeysgetvalue{/pgfplots/#1 coord inv trafo/.@cmd}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key + \else + \expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}\pgfeov + \fi +}% + +% INPUT: +% either floating point or fixed point coordinates (depending on the +% state of the \ifpgfplots@apply@datatrafo boolean) +% +\long\def\pgfplots@coord@stream@finalize@storedcoords@START{% + % de-activate the FPU here! I fear its number + % format may cause errors when used in low-level + % routines. + \pgfkeys{/pgf/fpu=false}% + % + \pgfplots@assert@tikzinternal@exists{tikz@make@last@position}% + % + \ifpgfplots@clip + \else + % "clip marker paths=true" actually doesn't checks anything -- + % it leaves the checks to the clip path. But since there is no + % clip path, it is adequate to use it here: + \pgfplots@clip@marker@pathstrue + \fi + % + \pgfplots@stored@current@cmd%[current plot style] <--- options are already set + \pgfextra + % + \tikzset{every plot/.try}% + \pgfplots@coord@stream@INIT@finalize@storedcoords% + % + \iffalse + %\ifx\pgfplots@basiclevel@plothandler\pgfplothandlerdiscard + % discard!? Well, no need to loop through the elements. + % But there may be a good reason that we entered the phase! + % keep it. + % FIXME : this does not work, although it might be desirable. + % It fails because we need the named start/end points. + \pgfplots@coord@stream@start + \pgfplots@coord@stream@end + \else + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@stored@current@data}% + \fi + % + % This here ensures that the LAST position of the path is the last plotted point. + % However, the "last plotted point" is not necessarily the LAST in the sequence. + % This here is the last plotted point: + \xdef\pgfplotlastpoint{\noexpand\pgfpointanchor{current plot end}{center}}% + \tikz@make@last@position{\pgfplotlastpoint}% + % + % the coordinate stream will be assigned as soon as it is needed: + \global\let\pgfplots@plot@timer@args=\relax + \pgfplotspointplotattimeclearcache + \let\tikz@timer=\pgfplots@plot@timer% + \pgfplotsaxisvisphase@get@afterpath% + \expandafter + \endpgfextra + \pgfplotsretval + ;% + % + \pgfplotspointplotattimeclearcache + \global\let\pgfplots@plot@timer@args=\relax + % +}% + +% Defines \pgfplotsretval to contain the "after path", i.e. the +% standard tikz instructions which are to be carried out after the +% plot path. This depends on the current visualization phase and the +% available visualization phases. +\def\pgfplotsaxisvisphase@get@afterpath{% + \ifx\pgfplots@visphase@name\pgfplotsaxis@visphase@name@default + % ah - we have the standard visualization phase. Draw them + % here. + % + % Note that the existance of (nontrivial) after path + % instructions ALWAYS implies the existance of a standard + % visualization phase (compare \pgfplotssurveyphase@set@visphase@names) + \let\pgfplotsretval=\pgfplots@serialized@afterpath% + \else + \let\pgfplotsretval=\pgfutil@empty + \fi +}% + + +% This routine is called at the begin of every plot. +% It initialises a zero level stream. +% +% The default is to use '0' as zero level streams. +% +% This method is called as "precommand"; before any Tikz drawing +% commands have been started. +\def\pgfplots@initzerolevelhandler{% + \ifpgfplots@stackedmode + % ATTENTION: this thing here says: + % "draw zero level coordinates from list XYZ." + % But at the time of this initialisation, the list will be EMPTY! + % + % It will be filled later. That's ok, because + % \pgfplots@initzerolevelhandler will be + % used as 'precommand', that means before Tikz sees any + % coordinates. + \pgfplots@stacked@initzerolevelhandler + \else + \ifpgfplots@threedim + \def\pgfplotxzerolevelstreamstart{}% + \def\pgfplotxzerolevelstreamend{}% + \def\pgfplotxzerolevelstreamnext{% + \begingroup + \pgf@xa=\pgf@y + \pgfplotsqpointxyz{\pgfplots@logical@ZERO@x}{\pgfplots@current@point@y}{\ifpgfplots@curplot@threedim\pgfplots@current@point@z\else\pgfplots@logical@ZERO@z\fi}% + \global\pgf@x=\pgf@x + \global\pgf@y=\pgf@xa + \endgroup + }% + % + \def\pgfplotyzerolevelstreamstart{}% + \def\pgfplotyzerolevelstreamend{}% + \def\pgfplotyzerolevelstreamnext{% + \begingroup + \pgf@xa=\pgf@y + \pgfplotsqpointxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@logical@ZERO@z}% + \global\pgf@x=\pgf@y + \global\pgf@y=\pgf@xa + \endgroup + }% + \else + \pgfplotspointaxisorigin + \expandafter\pgfplotxzerolevelstreamconstant\expandafter{\the\pgf@x}% + \expandafter\pgfplotyzerolevelstreamconstant\expandafter{\the\pgf@y}% + \fi + \fi +} + +% This code is mainly interesting for bar plots. +% +% It precomputes x = 0 and y = 0 - which is not necessarily +% trivial in case of data scaling. Furthermore, it applies +% coordinate clipping to the resulting values and multiplies them +% with x- and y scale vectors. +\def\pgfplots@prepare@ZERO@coordinates{% + \ifpgfplots@xislinear + \ifpgfplots@apply@datatrafo@x + \pgfplotscoordmath{x}{parsenumber}{0}% + \pgfplotscoordmath{x}{datascaletrafo}{\pgfmathresult}% + \global\let\pgfplots@logical@ZERO@x=\pgfmathresult + \else + \gdef\pgfplots@logical@ZERO@x{0}% + \fi + % this works in standard fixed pt math: + \pgfplotsmathmax{\pgfplots@logical@ZERO@x}{\pgfplots@xmin}% + \global\let\pgfplots@logical@ZERO@x=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@x}{\pgfplots@xmax}% + \global\let\pgfplots@logical@ZERO@x=\pgfmathresult + \else + \if\pgfplots@log@origin@choice@x0% + \global\let\pgfplots@logical@ZERO@x=\pgfplots@xmin% + \else + \gdef\pgfplots@logical@ZERO@x{0}% + \fi + \fi + % + \ifpgfplots@yislinear + \ifpgfplots@apply@datatrafo@y + \pgfplotscoordmath{y}{parsenumber}{0}% + \pgfplotscoordmath{y}{datascaletrafo}{\pgfmathresult}% + \global\let\pgfplots@logical@ZERO@y=\pgfmathresult + \else + \gdef\pgfplots@logical@ZERO@y{0}% + \fi + \pgfplotsmathmax{\pgfplots@logical@ZERO@y}{\pgfplots@ymin}% + \global\let\pgfplots@logical@ZERO@y=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@y}{\pgfplots@ymax}% + \global\let\pgfplots@logical@ZERO@y=\pgfmathresult + \else + \if\pgfplots@log@origin@choice@y0% + \global\let\pgfplots@logical@ZERO@y=\pgfplots@ymin% + \else + \gdef\pgfplots@logical@ZERO@y{0}% + \fi + \fi + % + \ifpgfplots@threedim + \ifpgfplots@zislinear + \ifpgfplots@apply@datatrafo@z + \pgfplotscoordmath{z}{parsenumber}{0}% + \pgfplotscoordmath{z}{datascaletrafo}{\pgfmathresult}% + \global\let\pgfplots@logical@ZERO@z=\pgfmathresult + \else + \gdef\pgfplots@logical@ZERO@z{0}% + \fi + \pgfplotsmathmax{\pgfplots@logical@ZERO@z}{\pgfplots@zmin}% + \global\let\pgfplots@logical@ZERO@z=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@z}{\pgfplots@zmax}% + \global\let\pgfplots@logical@ZERO@z=\pgfmathresult + \else + \if\pgfplots@log@origin@choice@z0% + \global\let\pgfplots@logical@ZERO@z=\pgfplots@zmin% + \else + \gdef\pgfplots@logical@ZERO@z{0}% + \fi + \fi + \fi + % + % + \ifpgfplots@threedim + \pgfplotsqpointxyz{\pgfplots@logical@ZERO@x}{\pgfplots@logical@ZERO@y}{\pgfplots@logical@ZERO@z}% + \else + \pgfplotsqpointxy{\pgfplots@logical@ZERO@x}{\pgfplots@logical@ZERO@y}% + \fi + \xdef\pgfplots@ZERO@x{\the\pgf@x}% + \xdef\pgfplots@ZERO@y{\the\pgf@y}% + \xdef\pgfplotspointaxisorigin{\noexpand\global\pgf@x=\pgfplots@ZERO@x\space\noexpand\global\pgf@y=\pgfplots@ZERO@y\space}% + % + % + %-------------------------------------------------- + % \pgfkeyslet{/pgfplots/axis/zero/x}\pgfplots@logical@ZERO@x + % \pgfkeyslet{/pgfplots/axis/zero/y}\pgfplots@logical@ZERO@y + % \ifpgfplots@threedim + % \pgfkeyslet{/pgfplots/axis/zero/z}\pgfplots@logical@ZERO@z + % \fi + %-------------------------------------------------- +}% + + + +% the low-level Tikz command which implements 'plot graphics'. +% +% It's current state is described by some pgfkeys options and two +% coordinates. +\def\pgfplotsplothandlergraphics{% + \def\pgf@plotstreamstart{% + \gdef\pgfplots@plot@handler@graphics@bb@first{\pgf@x=16000pt \pgf@y=16000pt }% + \gdef\pgfplots@plot@handler@graphics@bb@second{\pgf@x=-16000pt \pgf@y=-16000pt }% + \global\let\pgf@plotstreampoint=\pgfplots@plot@handler@graphics@collectbb% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplots@plot@handler@graphics@finish% + \def\pgfplotsplothandlervisualizejump{% + \pgfplots@error{Sorry, plot graphics does not support 'unbounded coords=jump'.}% + }% + }% + \def\pgfplotsplothandlername{graphics}% +}% +\def\pgfplots@plot@handler@graphics@collectbb#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgfplots@plot@handler@graphics@bb@first + \ifdim\pgf@xa<\pgf@x \pgf@x=\pgf@xa\fi + \ifdim\pgf@ya<\pgf@y \pgf@y=\pgf@ya\fi + \xdef\pgfplots@plot@handler@graphics@bb@first{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + % + \pgfplots@plot@handler@graphics@bb@second + \ifdim\pgf@xa>\pgf@x \pgf@x=\pgf@xa\fi + \ifdim\pgf@ya>\pgf@y \pgf@y=\pgf@ya\fi + \xdef\pgfplots@plot@handler@graphics@bb@second{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + % +}% +\def\pgfplots@plot@handler@graphics@finish{% + \let\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + % + % check if we have a pointmap. If so, the pointmap should be used + % to place the graphics. + \pgfkeysgetvalue{/pgfplots/plot graphics/points}\pgfplots@plot@handler@graphics@pointmap + \ifx\pgfplots@plot@handler@graphics@pointmap\pgfutil@empty + \else + \let\pgfplots@plot@handler@graphics@parsepointmap@error=\relax + \expandafter\pgfplots@plot@handler@graphics@parsepointmap\expandafter{\pgfplots@plot@handler@graphics@pointmap}% + \fi + % + % + \ifx\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + % no pointmap. Good; then squeze graphics into the bounding + % box: + \pgfplots@plot@handler@graphics@usebb + \else + % oh, a pointmap! Process it. + \pgfplots@plot@handler@graphics@process@pointmap + \fi +}% + +% Parses the argument of '/pgfplots/plot graphics/points'. +% +% #1: the argument of the key above. +\def\pgfplots@plot@handler@graphics@parsepointmap#1{% + \let\pgfplots@plot@handler@graphics@pointmap@A@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@B@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@C@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@C@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@D@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \pgfplots@plot@handler@graphics@parsepointmap@loop#1\pgfplots@EOI + \ifpgfplots@plot@graphics@autoadjustaxis + \ifx\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \def\pgfplots@loc@TMPa{#1}% + \pgfplots@plot@handler@graphics@parsepointmap@error + \fi + \fi + \fi +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@error{% + \pgfplots@error{plot graphics/points={\pgfplots@loc@TMPa} cannot be processed: I need at least *four* inner anchor points to automatically adjust the axis, i.e. 4 points of the form (x,y,z) => (imgx,imgy). Use 'plot graphics/auto adjust axis=false' to disable this feature}% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop{% + \pgfutil@ifnextchar\pgfplots@EOI{% + \pgfplots@gobble@until@EOI + }{% + \pgfplots@plot@handler@graphics@parsepointmap@loop@ + }% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@(#1,#2){% + \pgfutil@ifnextchar={% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)% + }{% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)=>(,)% + }% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)=>{% + \pgfutil@ifnextchar({% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@@(#1,#2)% + }{% + \pgfplots@error{Syntax error for plot graphics/pointmap: expected '(#1,#2) => (...,...)'}% + \pgfplots@gobble@until@EOI + }% +} +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@@@(#1,#2)(#3,#4){% + \def\pgfplotsplothandlergraphicspointmappointindex{}% + \def\pgfplots@loc@TMPc{#4}% + \ifx\pgfplots@loc@TMPc\pgfutil@empty + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{A}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@B@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{B}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@C@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{C}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{D}% + \else + \def\pgfplotsplothandlergraphicspointmappointindex{*}% + %\pgfplots@error{Sorry, the argument '(#1,#2) => (#3,#4)' of plot graphics/pointmap is superfluos; ignoring it.}% + \fi + \fi + \fi + \fi + \pgfmathparse{#3}% + \let\pgfplots@loc@TMPb=\pgfmathresult + % + \pgfmathparse{#4}% + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @img\endcsname{{\pgfplots@loc@TMPb}{\pgfmathresult}}% + \fi + % + % + \pgfutil@in@,{#2}% + \ifpgfutil@in@ + \def\pgfplots@loc@TMPa##1,##2\relax{% + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @logical\endcsname{{#1}{##1}{##2}}% + % + \pgfplotsplothandlergraphicspointmappoint(#1,##1,##2)(#3,#4) + }% + \pgfplots@loc@TMPa#2\relax + \else + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @logical\endcsname{{#1}{#2}{}}% + \pgfplotsplothandlergraphicspointmappoint(#1,#2,)(#3,#4) + \fi + \pgfplots@plot@handler@graphics@parsepointmap@loop +} + +\def\pgfplotsplothandlergraphics@survey@pointmappoint(#1,#2,#3)(#4,#5){% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \def\pgfplots@current@point@z{#3}% + \pgfplots@coord@stream@coord +}% + +% PRECONDITION: +% \pgfplotsplothandlergraphicspointmappointindex is +% empty if and only if (#4,#5) is empty +% or it is an index among all points with non--empty (#4,#5) image +% coordinates. +\def\pgfplotsplothandlergraphicspointmappoint(#1,#2,#3)(#4,#5){% + \ifx\pgfplotsplothandlergraphicspointmappointindex\pgfutil@empty + \else + \def\pgfplots@loc@TMPc{#3}% + \ifx\pgfplots@loc@TMPc\pgfutil@empty + \pgfplotspointaxisxy{#1}{#2}% + \else + \pgfplotspointaxisxyz{#1}{#2}{#3}% + \fi + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @canvas\endcsname{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + \fi +}% + +% Computes view-related keys which should be communicated to the axis +% in order to render the plot graphics correctly. +% +% @POSTCONDITION: \pgfplotsretval contains any required keys. +\def\pgfplotsplothandlergraphicspointmapcomputerequiredview{% + \begingroup + \let\pgfplotsretval=\pgfutil@empty + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \else + \pgfkeysgetvalue{/pgfplots/plot graphics/debug}\pgfplots@loc@TMPa + \def\pgfplots@loc@TMPb{false}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \let\pgfplots@loc@TMPa=\pgfplots@loc@TMPb + \fi + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug{0}% + \else + \def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug{1}% + \fi + % The following implementation computes the 'unit vector + % ratio' of the IMAGE. + % + % It then tells PGFPlots to use the very same unit vector + % ratio for its axis. + % + % + % The actual implementation is dumb; it requires 4 (!) points for + % which BOTH, the 3D coordinates and the projected 2D + % coordinates relative to the image's lower left corner are + % available. + % + % Since the 2D projected coordinates are generated by the map + % + % T(x,y,z) = o + x e_x + y e_y + z e_z in R^2 + % with o,e_x,e_y,e_z in R^2, + % + % I have 8 degrees of freedom (two for each of the four + % involved vectors). Thus, a simple approach is to provide 4 + % linearly independend points to get 8 equations. + % + % Then, I solve for o,e_x,e_y,e_z + % + \pgfplotsmatrixnewempty\pgfplotsmatrix + \pgfplotsmatrixresize\pgfplotsmatrix88% + % + \pgfplotsarraynewempty\pgfplotsE + \pgfplotsarrayresize\pgfplotsE8% + % + \def\pgfplots@extractimg##1##2{% + \def\pgfplots@img@x{##1}% + \def\pgfplots@img@y{##2}% + }% + \def\pgfplots@extractlogical##1##2##3{% + \def\pgfplots@logical@x{##1}% + \def\pgfplots@logical@y{##2}% + \def\pgfplots@logical@z{##3}% + }% + % Assemble the linear system such that + % x = [ + % exx + % exy + % eyx + % eyy + % ezx + % ezy + % ox + % oy] + % are the degrees of freedom. + \c@pgfplots@coordindex=0 + \pgfplotsutilforeachcommasep{A,B,C,D}\as\pgfplots@loc@TMPa{% + \expandafter\expandafter\expandafter\pgfplots@extractimg\csname pgfplots@plot@handler@graphics@pointmap@\pgfplots@loc@TMPa @img\endcsname + \expandafter\expandafter\expandafter\pgfplots@extractlogical\csname pgfplots@plot@handler@graphics@pointmap@\pgfplots@loc@TMPa @logical\endcsname + \ifx\pgfplots@logical@z\pgfutil@empty + \else + % + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,0\of\pgfplotsmatrix=\pgfplots@logical@x% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,1\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,2\of\pgfplotsmatrix=\pgfplots@logical@y% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,3\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,4\of\pgfplotsmatrix=\pgfplots@logical@z% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,5\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,6\of\pgfplotsmatrix\to{1}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,7\of\pgfplotsmatrix\to{0}% + % + \pgfplotsarrayletentry\c@pgfplots@coordindex\of\pgfplotsE=\pgfplots@img@x + % + \advance\c@pgfplots@coordindex by1 + \pgfplotsmatrixset \the\c@pgfplots@coordindex,0\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,1\of\pgfplotsmatrix=\pgfplots@logical@x% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,2\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,3\of\pgfplotsmatrix=\pgfplots@logical@y% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,4\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,5\of\pgfplotsmatrix=\pgfplots@logical@z% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,6\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,7\of\pgfplotsmatrix\to{1}% + % + \pgfplotsarrayletentry\c@pgfplots@coordindex\of\pgfplotsE=\pgfplots@img@y + % + \advance\c@pgfplots@coordindex by1 + \fi + }% + \ifx\pgfplots@logical@z\pgfutil@empty + \else + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + \pgfplotsplothandlergraphics@debug@matrix@to@string + \fi + % + % + \pgfplotsmatrixsolveLEQS\pgfplotsmatrix=\pgfplotsE + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem0\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@xx=\pgfmathresult + \edef\pgfmathresult{\pgfplotsarrayvalueofelem1\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@xy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/x dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@xx{-\pgfplots@xx}% + \edef\pgfplots@xy{-\pgfplots@xy}% + \fi + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem2\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@yx=\pgfmathresult + \edef\pgfmathresult{\pgfplotsarrayvalueofelem3\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@yy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/y dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@yx{-\pgfplots@yx}% + \edef\pgfplots@yy{-\pgfplots@yy}% + \fi + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem4\of\pgfplotsE}% + \pgfkeysgetvalue{/pgfplots/plot graphics/snap z}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \let\pgfplots@zx=\pgfmathresult + \pgfplotscoordmath{default}{op}{veclen}{% + {\pgfplotsarrayvalueofelem4\of\pgfplotsE}% + {\pgfplotsarrayvalueofelem5\of\pgfplotsE}% + }% + \let\pgfplotszlen=\pgfmathresult + % + % compute 'snap z' relative to + % '\pgfplotszlen' + \pgfplotscoordmath{default}{parsenumber}{\pgfplots@loc@TMPa}% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\pgfplotszlen}}% + \let\pgfplots@loc@TMPa=\pgfmathresult + % + \pgfplotscoordmath{default}{op}{abs}{{\pgfplots@zx}}% + \pgfplotscoordmath{default}{if less than}{\pgfmathresult}{\pgfplots@loc@TMPa}{% + \pgfplotscoordmath{default}{zero}% + }{% + \let\pgfmathresult=\pgfplots@zx + }% + \fi + \pgfplotscoordmath{default}{tofixed}\pgfmathresult% + \let\pgfplots@zx=\pgfmathresult + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem5\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@zy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/z dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@zx{-\pgfplots@zx}% + \edef\pgfplots@zy{-\pgfplots@zy}% + \fi + % + % + \if1\b@pgfplots@compat@plot@graphics@threedim + \pgfplotswarning{plot3 graphics compatibility mode}\pgfeov% + \else + \fi + % + \edef\pgfplotsretval{% + x={(\pgfplots@xx,\pgfplots@xy)},% + y={(\pgfplots@yx,\pgfplots@yy)},% + z={(\pgfplots@zx,\pgfplots@zy)},% + scale mode=scale uniformly,% + \if1\b@pgfplots@compat@plot@graphics@threedim + % this is the only strategy pre 1.6 + scale uniformly strategy=change vertical limits,% + \fi + }% + % + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + \pgfplotsplothandlergraphicspointmapcomputerequiredview@debug@output + \fi + % + \ifx\pgfplotsretval\pgfutil@empty + \pgfplots@error{plot graphics failed to perform the 'auto adjust axis' feature \csname on@line\endcsname\space\space (compare 'plot graphics[debug]). The graphics might be scaled incorrectly. Perhaps the provided 'points' are not linearly independent?}% + \else + \begingroup + \pgfkeysgetvalue{/pgfplots/plot graphics/src}\pgfplots@loc@TMPa + \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% + \immediate\write + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug 16\else -1\fi + {PGFPlots plot graphics[auto adjust axis=true] {\the\t@pgfplots@tokc} \csname on@line\endcsname: determined options '\pgfplotsretval'. + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + See \the\t@pgfplots@tokc.dat for debug output. + \else + Use 'plot graphics[debug]' or 'plot graphics[debug=visual]' to generate debug output files. + \fi + ^^J}% + \endgroup + \fi + % + \fi + \fi + \pgfmath@smuggleone\pgfplotsretval + \endgroup +}% +\def\pgfplotsplothandlergraphics@debug@matrix@to@string{% + \pgfplotsmatrixtotext\pgfplotsmatrix + \let\pgfplotsmatrix@text=\pgfplotsretval + \pgfplotsarraytotext\pgfplotsE + \let\pgfplotsrhs@text=\pgfplotsretval +}% +\def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug@output{% + \begingroup + \immediate\openout\w@pgf@writea=\pgfkeysvalueof{/pgfplots/plot graphics/src}.dat + \pgfplotsarrayselect0\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect1\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img x unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/x dir/value}(reversed due to x dir=reverse)\fi,}% + \pgfplotsarrayselect2\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect3\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img y unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/y dir/value}(reversed due to y dir=reverse)\fi,}% + \pgfplotsarrayselect4\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect5\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img z unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb,}% + \pgfplotsarrayselect6\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect7\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img origin=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/z dir/value}(reversed due to z dir=reverse)\fi,}% + \def\n{^^J}% + \def\t{^^I}% + \immediate\write\w@pgf@writea{canvasmapmatrix=[\pgfplotsmatrix@text];^^Jcanvasmaprhs = [\pgfplotsrhs@text];^^J}% + % + \immediate\write\w@pgf@writea{key configuration = \pgfplotsretval;^^J}% + \immediate\write\w@pgf@writea{use debug=visual to see the mapped keys.^^J}% + \immediate\closeout\w@pgf@writea + \endgroup +}% + +\def\pgfplots@plot@handler@graphics@process@pointmap{% + \begingroup + % determine natural size: + \pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel get natural size/.@cmd}{}% + \def\pgfplots@loc@TMPa##1##2{% + \global\pgf@x=##1 + \global\pgf@y=##2 + }% + \expandafter\pgfplots@loc@TMPa\pgfmathresult + \edef\pgfplots@W{\pgf@sys@tonumber\pgf@x}% natural WIDTH + \edef\pgfplots@H{\pgf@sys@tonumber\pgf@y}% natural HEIGHT + % + \def\pgfplots@extractimg##1##2{% + \def\pgfplots@img@x{##1}% + \def\pgfplots@img@y{##2}% + }% + \def\pgfplots@extractimgaspoint##1##2{% + \pgfqpoint{##1pt}{##2pt}% + }% + \expandafter\pgfplots@extractimg\pgfplots@plot@handler@graphics@pointmap@A@img% anchor 1 in image + \let\pgfplots@Ax=\pgfplots@img@x + \let\pgfplots@Ay=\pgfplots@img@y + % + \pgfplots@plot@handler@graphics@pointmap@A@canvas% the canvas coordinate corresponding to 'A' + \edef\pgfplots@ax{\pgf@sys@tonumber\pgf@x}% call it 'a' + \edef\pgfplots@ay{\pgf@sys@tonumber\pgf@y}% + % + % compute the CANVAS diagonal between the two anchors points a,b, + % dd := b-a + \pgfpointdiff + \pgfplots@plot@handler@graphics@pointmap@A@canvas + \pgfplots@plot@handler@graphics@pointmap@B@canvas + \edef\pgfplots@ddx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@ddy{\pgf@sys@tonumber\pgf@y}% + % + % compute the IMAGE diagonal between the two image anchor points A,B, + % DD := B - A + \pgfpointdiff + {\expandafter\pgfplots@extractimgaspoint\pgfplots@plot@handler@graphics@pointmap@A@img} + {\expandafter\pgfplots@extractimgaspoint\pgfplots@plot@handler@graphics@pointmap@B@img}% + \pgfplots@loop@CONTINUEtrue + \ifdim\pgf@x=0pt \pgfplots@loop@CONTINUEfalse \fi + \ifdim\pgf@y=0pt \pgfplots@loop@CONTINUEfalse \fi + \ifpgfplots@loop@CONTINUE + \else + \pgfplots@error{Sorry, the first two points with '=>' in plot graphics[points={}] are expected to have different image Y coordinates. Please reorder the sequence.}% + \fi + \edef\pgfplots@DDx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@DDy{\pgf@sys@tonumber\pgf@y}% + % + % What I need now is a shift and the CANVAS dimensions of the + % image. Both can be computed using the relative sizes dd/DD. + % + % The shift is needed to compute the lower left corner of the + % CANVAS image. thus, the lower left CANVAS image corresponds to + % the (0,0) coordinate in the IMAGE. + % + % Remember that 'A' is the anchor 1 in IMAGE coordinates. It is a + % vector from (0,0) --> (A_x,A_y) in IMAGE coordinates. + % + % Now, I want a vector (v_x,v_y) such that q + v = a in CANVAS + % coordinates. Here, 'q' is the lower left corner; it corresponds + % to the (0,0) in IMAGE coordinates. Thus, we have + % v = (a-q). Taking the relative sizes of dd and DD, we find + % + % DD_x / A_x = dd_x / v_x + % DD_y / A_y = dd_y / v_y + % + % and finally q = a-v is the lower left CANVAS coordinate. + \pgfmath@basic@divide@{\pgfplots@ddx}{\pgfplots@DDx}% + \let\pgfplots@x@rel=\pgfmathresult + % + \pgfmath@basic@divide@{\pgfplots@ddy}{\pgfplots@DDy}% + \let\pgfplots@y@rel=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Ax}{\pgfplots@x@rel}% + \let\pgfplots@vx=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Ay}{\pgfplots@y@rel}% + \let\pgfplots@vy=\pgfmathresult + % + % + % + % + % now, the canvas width. It is even simpler because it holds + % + % DD_x / dd_x = W / w + % DD_y / dd_y = H / h + % + % where (W,H) is the natural size (i.e. in IMAGE coordinates) of the picture and + % (w,h) is the size the picture will occupy in CANVAS coordinates. + % + \pgfmath@basic@multiply@{\pgfplots@x@rel}{\pgfplots@W}% + \let\pgfplots@w=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@y@rel}{\pgfplots@H}% + \let\pgfplots@h=\pgfmathresult + % + \edef\pgfplots@plot@handler@graphics@DRAW@{% + \noexpand\pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{% + {\pgfplots@w pt}% width + {\pgfplots@h pt}% height + }% + }% + \pgfpointadd + {\pgfplots@plot@handler@graphics@pointmap@A@canvas}% the canvas coordinate corresponding to 'A' + {\pgfqpointscale{-1} + {\pgfqpoint{\pgfplots@vx pt}{\pgfplots@vy pt}}% + }% + \edef\pgfplots@plot@handler@graphics@pointmap@lowerleft@canvas{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% +% + % + % + \begingroup + \pgftransformshift{}% simply take \pgf@x and \pgf@y + % + \node[/pgfplots/plot graphics/node] {% + \pgfplots@plot@handler@graphics@DRAW@ + };% + \endgroup + % + % + \pgfkeysgetvalue{/pgfplots/plot graphics/debug}\pgfplots@loc@TMPa + \edef\pgfplots@loc@TMPb{visual}% + \ifx\pgfplots@loc@TMPb\pgfplots@loc@TMPa + % debug = visual: "sanitize" also triggers the visualization. + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{A}% + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{B}% + \fi + % + % + \ifx\pgfplots@plot@handler@graphics@pointmap@C@canvas\pgfutil@empty + \ifpgfplots@threedim + \pgfplotswarning{plot3 graphics too few inner anchors}\pgfeov% + \fi + \else + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{C}% + \ifx\pgfplots@plot@handler@graphics@pointmap@D@canvas\pgfutil@empty + \else + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{D}% + \fi + \fi + \endgroup +}% + +% Checks if the logical and canvas coordinates of the point identified +% by #1 are correct. +% +% #1: a character in {A,B,C...}. +% +\def\pgfplots@plot@handler@graphics@pointmap@sanitize@scaling#1{% + \begingroup + \expandafter\let\expandafter\pgfplots@point@img\csname pgfplots@plot@handler@graphics@pointmap@#1@img\endcsname + \expandafter\let\expandafter\pgfplots@point@canvas\csname pgfplots@plot@handler@graphics@pointmap@#1@canvas\endcsname + \expandafter\let\expandafter\pgfplots@point@logical\csname pgfplots@plot@handler@graphics@pointmap@#1@logical\endcsname + \expandafter\pgfplots@extractimgaspoint\pgfplots@point@img% anchor 3 in image + \edef\pgfplots@Cx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@Cy{\pgf@sys@tonumber\pgf@y}% + % + \pgfmath@basic@multiply@{\pgfplots@Cx}{\pgfplots@x@rel}% + \let\pgfplots@Cx=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Cy}{\pgfplots@y@rel}% + \let\pgfplots@Cy=\pgfmathresult + \pgfpointadd + {\pgfplots@plot@handler@graphics@pointmap@lowerleft@canvas}% + {\pgfpoint\pgfplots@Cx\pgfplots@Cy}% + \edef\pgfplots@point@canvas@check{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + \pgfpointdiff + {\pgfplots@point@canvas@check}% + {\pgfplots@point@canvas}% + \ifdim\pgf@x<0pt \pgf@x=-\pgf@x\fi + \ifdim\pgf@y<0pt \pgf@y=-\pgf@y\fi + \def\pgfplots@is@the@same@point{1}% + \ifdim\pgf@x>\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol} + \def\pgfplots@is@the@same@point{0}% + \else + \ifdim\pgf@y>\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol} + \def\pgfplots@is@the@same@point{0}% + \fi + \fi + \if0\pgfplots@is@the@same@point + % + \begingroup + \pgfkeysgetvalue{/pgfplots/plot graphics/src}\pgfplots@loc@TMPa + \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% + \def\pgfplots@extractcoord##1##2##3{##1,##2,##3}% + \pgfplots@error{sorry, I can't fix the scaling of 'plot graphics {\the\t@pgfplots@tokc}'. + The points (\expandafter\pgfplots@extractcoord\pgfplots@plot@handler@graphics@pointmap@A@logical) and (\expandafter\pgfplots@extractcoord\pgfplots@plot@handler@graphics@pointmap@B@logical) are correct, but the point (\expandafter\pgfplots@extractcoord\pgfplots@point@logical) is wrong (its position vector has an error of (\the\pgf@x,\the\pgf@y) which is larger than 'squeeze tol=\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol}'). This is probably caused by improper relations between the axis' unit vectors because the view is incorrect.^^J + - Is the 'view' argument correct (matlab: [h,v] = view)? ^^J + - Does your image have a non-trivial 'plot box ratio' (matlab: ratio = pbaspect)?^^J + Please refer to the pgfplots manual for details. If you continue now, I'll show the points in the image}% + \endgroup + % + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling@draw + % + \fi + \pgfkeysgetvalue{/pgfplots/plot graphics/debug}\pgfplots@loc@TMPa + \edef\pgfplots@loc@TMPb{visual}% + \ifx\pgfplots@loc@TMPb\pgfplots@loc@TMPa + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling@draw + \fi + \endgroup +} + +\def\pgfplots@plot@handler@graphics@pointmap@sanitize@scaling@draw{% + \scope + \pgfsetstrokecolor{black}% + \pgfsetfillcolor{red}% + \pgfpathcircle{\pgfplots@point@canvas@check}{2pt}% + \pgfusepath{stroke,fill}% + \pgfsetfillcolor{green}% + \pgfpathcircle{\pgfplots@point@canvas}{2pt}% + \pgfusepath{stroke,fill}% + \draw[->,red] + \pgfextra{ + \pgfpathmoveto{\pgfplots@point@canvas@check}% + \pgfpathlineto{\pgfplots@point@canvas}}; + \endscope +}% + +\def\pgfplots@plot@handler@graphics@usebb{% + \pgfpointdiff{\pgfplots@plot@handler@graphics@bb@first}{\pgfplots@plot@handler@graphics@bb@second}% + \def\pgfplots@plot@handler@graphics@finish@ok{1}% + \ifdim\pgf@x=0pt + \def\pgfplots@plot@handler@graphics@finish@ok{0}% + \else + \ifdim\pgf@y=0pt + \def\pgfplots@plot@handler@graphics@finish@ok{0}% + \fi + \fi + \if0\pgfplots@plot@handler@graphics@finish@ok + \pgfplots@error{Error using 'plot graphics': I got too few coordinates! I expected the lower left and upper right corners!}% + \xdef\pgfplots@plot@handler@graphics@bb@first{\noexpand\pgfqpoint{0pt}{0pt}}% + \xdef\pgfplots@plot@handler@graphics@bb@first{\noexpand\pgfqpoint{0pt}{0pt}}% + + \fi + \begingroup + % determine the lower left / upper right corners. + \pgfplots@plot@handler@graphics@bb@first + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgfplots@plot@handler@graphics@bb@second + \pgf@xb=\pgf@x + \pgf@yb=\pgf@y + % + % xc,yc = lower left corner + % x,y = upper right + \ifdim\pgf@xa<\pgf@xb + \pgf@xc=\pgf@xa + \pgf@x=\pgf@xb + \else + \pgf@xc=\pgf@xb + \pgf@x=\pgf@xa + \fi + \ifdim\pgf@ya<\pgf@yb + \pgf@yc=\pgf@ya + \pgf@y=\pgf@yb + \else + \pgf@yc=\pgf@yb + \pgf@y=\pgf@ya + \fi + \advance\pgf@x by-\pgf@xc + \advance\pgf@y by-\pgf@yc + \edef\pgfplots@plot@handler@graphics@DRAW@{% + \noexpand\pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{% + {\the\pgf@x}% width + {\the\pgf@y}% height + }% + }% + \pgf@x=\pgf@xc + \pgf@y=\pgf@yc + \pgftransformshift{}% + \node[/pgfplots/plot graphics/node] {% + \pgfplots@plot@handler@graphics@DRAW@ + };% + \endgroup +}% +% initial value for /pgfplots/plots graphics/lowlevel draw: +\def\pgfplots@plot@handler@graphics@DRAW#1#2{% + \pgfkeysgetvalue{/pgfplots/plot graphics/includegraphics}{\pgfplots@loc@TMPc}% + \pgfkeysgetvalue{/pgfplots/plot graphics/src}{\pgfplots@loc@TMPd}% + \ifx\pgfplots@loc@TMPd\pgfutil@empty + \pgfplots@error{Error using 'plot graphics': I don't have a graphics file name! Please set the '/pgfplots/plot graphics/src' key to the image file name. Skipping this plot.}% + \else + \begingroup + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPc}% + % + \def\pgfplots@loc@TMPa{#1}% + \def\pgfplots@loc@TMPb{#2}% + % + \edef\pgfplots@loc@TMPc{% + \the\t@pgfplots@toka,% + \ifx\pgfplots@loc@TMPa\pgfutil@empty\else width=#1,\fi + \ifx\pgfplots@loc@TMPb\pgfutil@empty\else height=#2,\fi + }% + \pgfmath@smuggleone\pgfplots@loc@TMPc + \endgroup + % + \def\pgfplots@loc@TMPa{\pgfkeysvalueof{/pgfplots/plot graphics/includegraphics cmd}}% + \expandafter\pgfplots@loc@TMPa\expandafter[\pgfplots@loc@TMPc]{\pgfplots@loc@TMPd}% + \fi +}% + +\def\pgfplots@plot@handler@graphics@getnaturalsize{% + \begingroup + \setbox0=\hbox{% + \pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{{}{}}% + }% + \pgf@x=\wd0 + \pgf@y=\ht0 + \ifdim\dp0>0pt + \advance\pgf@y by\dp0 + \else + \ifdim\dp0<0pt + \advance\pgf@y by-\dp0 + \fi + \fi + \xdef\pgfplots@glob@TMPb{{\the\pgf@x}{\the\pgf@y}}% + \endgroup + \let\pgfmathresult=\pgfplots@glob@TMPb +}% + +% legends for plot graphics should not use 'plot graphics' themselfes +% (for obvious reasons). +% This key handles that. Furthermore, it remembers the plot mark for +% the legend -- although no plot mark is allowed for plot graphics as +% such. +\pgfkeysdef{/pgfplots/plot graphics/@prepare legend}{% + \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% + % + \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler + \t@pgfplots@tokc=\expandafter{\pgfplots@basiclevel@plothandler}% + % + \edef\pgfplots@loc@TMPa{% + \noexpand\pgfkeys{/pgfplots/every legend image post/.append code={% + \noexpand\def\noexpand\tikz@plot@handler{\the\t@pgfplots@tokc}% + \ifx\tikz@plot@mark\pgfutil@empty + \else + \noexpand\pgfkeysalso{/tikz/mark=\tikz@plot@mark}% + \fi + }% + }% + }% + \pgfplots@loc@TMPa +} + + + +% Input : \pgfplots@stored@current@data contains the coordinate stream +% Output: \pgfplots@stored@current@data contains the (modified) +% coordinate stream +\def\pgfplots@apply@zbuffer{% + \ifcase\pgfplotsplothandlermesh@zbuffer@choice\relax + % none. + \or + % reverse x seq: only for 'mesh' + \if\pgfplots@meshmode n% + \pgfplots@error{Sorry, `/pgfplots/z buffer=reverse x seq' can only be used for mesh/surf plots.}% + \else + \pgfplotsautocompletemeshkeys + \if\pgfplots@plot@mesh@ordering0% + % ordering = rowwise -> scanline is cols! + \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversescanline% + \else + % ordering = colwise: scanline is rows! + \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversetransposed% + \fi + \fi + \or + % reverse y seq: only for 'mesh' + \if\pgfplots@meshmode n% + \pgfplots@error{Sorry, `/pgfplots/z buffer=reverse y seq' can only be used for mesh/surf plots.}% + \else + \pgfplotsautocompletemeshkeys + \if\pgfplots@plot@mesh@ordering0% + % ordering = rowwise -> scanline is cols! + \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversetransposed% + \else + % ordering = colwise: scanline is rows! + \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversescanline% + \fi + \fi + \or + % reverse xy seq: + \ifpgfplots@LUA@backend@supported + \directlua{pgfplots.texApplyZBufferReverseStream()}% + \else + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsprependlistXnewempty{reversed}% + }% + \def\pgfplots@coord@stream@coord{% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{reversed}% + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversed}% + \pgfplotsprependlistXnewempty{reversed}% clear it + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@stored@current@data}% + \endgroup + \let\pgfplots@stored@current@data=\pgfplotsglobalretval + \global\let\pgfplotsglobalretval=\pgfutil@empty + \fi + \or + % sort. + \if\pgfplots@meshmode n% + \ifpgfplots@LUA@backend@supported + \directlua{pgfplots.texApplyZBufferSort()}% + \else + \pgfplots@apply@zbuffer@sort@coordinates + \fi + \else + % meshmode handles sort separately! + \fi + \or + % z buffer=auto + % + % I can decide for each axis if coordinate reversal is + % necessary. + % Idea: check if axis side planes are on foreground or not (a + % very simple task)! I + % only need to know whether [xy] coordinates are sorted + % ascending or descending. This information is already ready. + % + \if1\pgfplotsplothandlermesh@matrixinput + % mesh input=lattice + \begingroup + \if+\pgfkeysvalueof{/pgfplots/x coord sorting}% + \def\pgfplots@minmaxvalue@x{0}% + \else + \def\pgfplots@minmaxvalue@x{0}% + \fi + \if+\pgfkeysvalueof{/pgfplots/y coord sorting}% + \def\pgfplots@minmaxvalue@y{0}% + \else + \def\pgfplots@minmaxvalue@y{1}% + \fi + \pgfplotsifaxissurfaceisforeground{\pgfplots@minmaxvalue@x vv}{% + \def\pgfplots@reverse@x{1}% + }{% + \def\pgfplots@reverse@x{0}% + }% + \pgfplotsifaxissurfaceisforeground{v\pgfplots@minmaxvalue@y v}{% + \def\pgfplots@reverse@y{1}% + }{% + \def\pgfplots@reverse@y{0}% + }% + \if1\pgfplots@reverse@x + \if1\pgfplots@reverse@y + \pgfkeys{/pgfplots/z buffer=reverse xy seq}% + \else + \pgfkeys{/pgfplots/z buffer=reverse x seq}% + \fi + \else + \if1\pgfplots@reverse@y + \pgfkeys{/pgfplots/z buffer=reverse y seq}% + \else + \pgfkeys{/pgfplots/z buffer=none}% + \fi + \fi +%\message{z buffer=auto mode chose z buffer= \ifcase\pgfplotsplothandlermesh@zbuffer@choice NONE \or reverse x seq \or reverse y seq \or reverse xy seq \or sort\or default \fi. mesh ordering = \ifcase\pgfplots@plot@mesh@ordering x varies/rowwise\or y varies/colwise\fi}% + \pgfmath@smuggleone\pgfplotsplothandlermesh@zbuffer@choice + \endgroup + % 'z buffer' is no longer 'auto' now: + \pgfplots@apply@zbuffer + \else + % mesh input=patches + \ifpgfplots@threedim + \if\pgfplots@meshmode n% + \else + \pgfkeys{/pgfplots/z buffer=sort}% + \fi + \else + \pgfkeys{/pgfplots/z buffer=none}% + \fi + \fi + \or + % z buffer=default. + \if\pgfplots@meshmode n% + % mesh mode deactivated! + \else + % mesh=true + \pgfkeysalso{/pgfplots/z buffer=auto}% + \pgfplots@apply@zbuffer% + \fi + \fi +}% + +\def\pgfplots@apply@zbuffer@sort@coordinates{% + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsarraynewempty\pgfplots@zbuffer@local + \pgfplotsarrayresize\pgfplots@zbuffer@local{\numcoords}% + \c@pgfplots@scanlineindex=0 + \def\pgfplots@zbuffer@local@SETCUR####1{% + \expandafter\pgfplotsarrayset\c@pgfplots@scanlineindex\of\pgfplots@zbuffer@local\to{####1}% + }% + }% + \def\pgfplots@coord@stream@coord{% + \expandafter\pgfplots@zbuffer@local@SETCUR\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded}% + \advance\c@pgfplots@scanlineindex by1 + }% + \def\pgfplots@coord@stream@end{% + \ifnum\c@pgfplots@scanlineindex=\numcoords + \else + \pgfplotsarrayresize\pgfplots@zbuffer@local{\c@pgfplots@scanlineindex}% + \fi + \pgfkeyslet{/pgfplots/iflessthan/.@cmd}\pgfplots@apply@zbuffer@SORT@iflessthan + \pgfkeysdef{/pgfplots/array/unscope pre}{% + \pgfplotsapplistXnewempty{\pgfp@sortedlist}% + \pgfplotsarrayforeachungrouped\pgfplots@zbuffer@local\as\curelem{% + \expandafter\pgfplotsapplistXpushback\expandafter{\expandafter{\curelem}}\to{\pgfp@sortedlist}% + }% + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\pgfp@sortedlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \pgfkeysdef{/pgfplots/array/unscope post}{}% + \pgfplotsarraysort\pgfplots@zbuffer@local + }% + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@stored@current@data}% + \endgroup + \let\pgfplots@stored@current@data=\pgfplotsglobalretval + \global\let\pgfplotsglobalretval=\pgfutil@empty +}% +% Defines \pgfplotsglobalretval (globally) to be a partial reversion of the +% (normalized) 2d coordinate sequence '#1'. +% +% In other words, the normalized coordinate sequence '#1' is visited +% linearly and while we go, each scanline is reversed. The result is +% collected into \pgfplotsglobalretval. +% +% This implements the 'z buffer=reverse x seq' feature for +% ordering=y varies. +% +% PRECONDITION: +% \pgfplotsscanlinelength contains the scanline length +% POSTCONDITION: +% \pgfplotsglobalretval contains the partial reversion. +\def\pgfplots@apply@zbuffer@reversescanline{% + \ifpgfplots@LUA@backend@supported + \directlua{pgfplots.texApplyZBufferReverseScanline(\pgfplotsscanlinelength)}% + \else + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsprependlistXnewempty{reversedscanline}% + \c@pgfplots@scanlineindex=0 + \pgfplotsapplistXnewempty{\resultlist}% + }% + \def\pgfplots@coord@stream@coord{% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{reversedscanline}% + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversedscanline}% + \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@loc@TMPa}\to\resultlist + \pgfplotsprependlistXnewempty{reversedscanline}% + \c@pgfplots@scanlineindex=0 + \fi + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversedscanline}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfplots@zbuffer@error + \fi + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\resultlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@stored@current@data}% + \endgroup + \let\pgfplots@stored@current@data=\pgfplotsglobalretval + \global\let\pgfplotsglobalretval=\pgfutil@empty + \fi +%\message{I have performed partial reversion of '#1' and got '\pgfplotsglobalretval'!}% +}% + +% A very similar method of \pgfplots@apply@zbuffer@reversescanline, +% but this one keeps everything inside of each scanline in the +% original ordering, and reverses the ordering in which whole +% scanlines occur. +\def\pgfplots@apply@zbuffer@reversetransposed{% + \ifpgfplots@LUA@backend@supported + \directlua{pgfplots.texApplyZBufferReverseTransposed(\pgfplotsscanlinelength)}% + \else + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsapplistXnewempty{\scanline}% + \c@pgfplots@scanlineindex=0 + \pgfplotsprependlistXnewempty{resultlist}% + }% + \def\pgfplots@coord@stream@coord{% + \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{\scanline}% + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\scanline}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@loc@TMPa}\to{resultlist} + \pgfplotsapplistXnewempty{\scanline}% + \c@pgfplots@scanlineindex=0 + \fi + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\scanline}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfplots@zbuffer@error + \fi + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={resultlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@stored@current@data}% + \endgroup + \let\pgfplots@stored@current@data=\pgfplotsglobalretval + \global\let\pgfplotsglobalretval=\pgfutil@empty + \fi +%\message{I have performed partial reversion (reverse transposed) of '#1' and got '\pgfplotsglobalretval'!}% +}% +\def\pgfplots@zbuffer@error{% + \pgfplots@error{An internal error occured during z buffer reorderings: the rows/cols where not balanced! I have rows= \pgfkeysvalueof{/pgfplots/mesh/rows}, cols=\pgfkeysvalueof{/pgfplots/mesh/cols}. If this happens to be wrong, you might want to provide rows and cols manually.}% +} + +% A special '<' operation which returns true if the point coordinate +% '#1' is BEHIND #2 with respect to the current 3D view. +\def\pgfplots@apply@zbuffer@SORT@iflessthan#1#2#3#4\pgfeov{% + \pgfplotsaxisdeserializedatapointfrom{#1}% + \pgfplotsmathvectorfromstring{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z}{default}% + \pgfplotsmathvectorscalarproduct{\pgfplots@view@dir@threedim}{\pgfplotsretval}{default}% + \let\pgfplots@apply@zbuffer@SORT@iflessthan@a=\pgfplotsretval + % + \pgfplotsaxisdeserializedatapointfrom{#2}% + \pgfplotsmathvectorfromstring{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z}{default}% + \pgfplotsmathvectorscalarproduct{\pgfplots@view@dir@threedim}{\pgfplotsretval}{default}% + \let\pgfplots@apply@zbuffer@SORT@iflessthan@b=\pgfplotsretval + % + \pgfplotscoordmath{default}{if less than}{\pgfplots@apply@zbuffer@SORT@iflessthan@b}{\pgfplots@apply@zbuffer@SORT@iflessthan@a}{% + #3\relax + }{% + #4\relax + }% +}% + + +% Defines \pgfmathresult to be the view depth of a three component +% vector. The third component will be used if and only if the boolean +% \ifpgfplots@curplot@threedim is true. +% The return value will be assigned in floating point. +% +% The arguments need to be numbers (will be parsed with +% \pgfmathfloatparsenumber). +% @see \pgfplotsmathviewdepthxyz +% DEPRECATED use \pgfplotsmathvectorviewdepth instead! +\def\pgfplotsmathfloatviewdepthxyz#1#2#3{% + \begingroup + \pgfmathfloatparsenumber{#1}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfmathfloatparsenumber{#2}\let\pgfplots@loc@TMPb=\pgfmathresult + \pgfmathfloatparsenumber{#3}\let\pgfplots@loc@TMPc=\pgfmathresult + \edef\pgfplots@loc@TMPa{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}}% + \expandafter\pgfplotsmathfloatviewdepthxyz@\pgfplots@loc@TMPa + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% + +% #1: a 3d vector of the form x,y,z in 'default' coordmath format +% defines \pgfplotsretval to the view depth +% of the point +% +% Use \pgfplotsmathvectorfromstring{x,y,z}{default} to transform a +% vector into the requested format. +% +% Use \pgfplotscoordmath{default}{tofixed}{\pgfplotsretval} to +% transform the result into fixed point representation. +\def\pgfplotsmathvectorviewdepth#1{% + \pgfplotsmathvectorscalarproduct{#1}{\pgfplots@view@dir@threedim}{default}% +}% + +\def\pgfplotsmathfloatviewdepthxyz@#1#2#3{% + \pgfplots@error{Sorry, you can't use \string\pgfplotsmathfloatviewdepthxyz\space in this context.}% +}% +\def\pgfplotsmathfloatviewdepthxyz@infigure#1#2#3{% + \pgfplotsmathvectorfromstring{\pgfplots@view@dir@threedim}{float}% + \pgfplotsmathvectorscalarproduct{#1,#2,#3}{\pgfplotsretval}{float}% FIXME : \pgfplots@view@dir@threedim might have a different math format! + \let\pgfmathresult=\pgfplotsretval +}% + +% Similar to \pgfplotsmathfloatviewdepthxyz, but this always relies on +% fixed point arithmetics. +% DEPRECATED use \pgfplotsmathvectorviewdepth instead +\def\pgfplotsmathviewdepthxyz#1#2#3{\pgfplotsmathviewdepthxyz@{#1}{#2}{#3}} +\def\pgfplotsmathviewdepthxyz@#1#2#3{% + \pgfplots@error{Sorry, you can't use \string\pgfplotsmathviewdepthxyz\space in this context.}% +} +\def\pgfplotsmathviewdepthxyz@infigure#1#2#3{% + \pgfplotsmathvectorfromstring{\pgfplots@view@dir@threedim@unitlength}{pgfbasic}% + \pgfplotsmathvectorscalarproduct{#1,#2,#3}{\pgfplotsretval}{pgfbasic}% FIXME : \pgfplots@view@dir@threedim might have a different math format! + \let\pgfmathresult=\pgfplotsretval +}% + + +% Evaluate shell commands. +% +% #1 = filename prefix for .sh and .out files (optional, +% default is \jobname) +% #2 = shell command text +% +% Description: +% +% This command will write the command text to a file called +% #1.sh. Then it calls sh (using the \write18 mechanism) to +% execute the file and redirect the output to a file called +% #1.out. +% In contrast to pgfplotgnuplot the result has to be read +% from #1.out later using \pgfplotxyfile. (This allows +% using the function from within the plot table functions +% as well.) +% +% Example: +% +% \pgfplothandlerlineto +% \pgfshell[\jobname]{cat table.dat} +% \pgfplotxyfile{\jobname.out} + +\pgfutil@IfUndefined{w@pgf@writea}{% + \csname newwrite\endcsname\pgf@shellwrite +}{% + \let\pgf@shellwrite=\w@pgf@writea +} +\newif\ifpgf@resample@shell + +\def\pgfshell{\pgfutil@ifnextchar[{\pgf@shell}{\pgf@shell[\jobname]}}%} +\def\pgf@shell[#1]#2{% + \pgf@resample@shelltrue% + % Check, whether it is up-to-date + \openin\pgfutil@inputcheck=#1.sh + \ifeof\pgfutil@inputcheck% + \else% + \read\pgfutil@inputcheck to\pgf@shell@line% + \edef\pgf@plot@code{#2\space}% + \ifx\pgf@plot@code\pgf@shell@line% + \openin\pgfutil@inputcheck=#1.out + \ifeof\pgfutil@inputcheck% + \else% + \pgf@resample@shellfalse + \fi% + \fi% + \fi + \ifpgf@resample@shell% + \immediate\openout\pgf@shellwrite=#1.sh + \immediate\write\pgf@shellwrite{#2}% + \immediate\closeout\pgf@shellwrite% + \immediate\write18{sh #1.sh > #1.out} + \fi% +} |