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