%-------------------------------------------- % % 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 % 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@xx=\pgf@x \pgf@xy=0pt \pgf@yx=0pt \pgf@yy=\pgf@y \pgf@zx=0pt \pgf@zy=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}}% % % 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 }% % 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) % '1' : is either 1, a, b, v or 2 (i.e. NOT 0) % 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. \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}% } \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 % return TRUE. % I admit I am not sure at all if this works in all % cases \pgfplotspointonorientedsurfaceabmatchaxisline@warn{#1}% \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 \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} % FIXME : this doesn't work if one of the three characters is '2' (for % center) \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@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@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@baxis{x}% \def\pgfplots@loc@naxis{y}% \fi \fi \ifcase\pgfplots@loc@char@for@baxis\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\pgfplots@loc@baxissign{-}% \or % case 1: % in this case, the OUTSIDE area requires a plus sign - the b % axis already points to the inside. \def\pgfplots@loc@baxissign{+}% \or % case 2: we have the 'axis lines=centered' case. % FIXME : \def\pgfplots@loc@baxissign{+}% \fi \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}% }% % % Now the same game for the other axis: \ifcase\pgfplots@loc@char@for@naxis\relax % case 0: % this means : the '##2' 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\pgfplots@loc@naxissign{-}% \or % case 1: % in this case, the OUTSIDE area requires a plus sign - the n % axis already points to the inside. \def\pgfplots@loc@naxissign{+}% \or % case 2: centered. % FIXME \def\pgfplots@loc@naxissign{+}% \fi \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 }% % very-low-level internal routine. Never invoke it directly. % @PRECONDITION: % an \begingroup has been opened. % @POSTCONDITION % an \endgroup has been closed and \pgf@x and \pgf@y are assigned. % % This grouping stuff has the intention to keep the "plug" things % local. % % #1#2#3 are the three characters for the line, delimited by \relax. % #4: the argument supplied as coordinate on that axis. % #5: the shift along the outer unit normal. \def\pgfplotspointoutsideofaxis@#1#2#3\relax#4#5{% \if v#1% \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPa=\pgfmathresult \pgfplotspointonorientedsurfaceabsetupforsety{\pgfplots@loc@TMPa}{#2}% % \pgfplotspointonorientedsurfaceabsetupfor xzy% \pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@A=\pgfmathresult \ifpgfplots@threedim \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@B=\pgfmathresult \else \def\pgfplots@loc@B{0}% \fi \else \if v#2% \ifpgfplots@threedim \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPa=\pgfmathresult \else \def\pgfplots@loc@TMPa{0}% \fi \pgfplotspointonorientedsurfaceabsetupforsetz{\pgfplots@loc@TMPa}{#3}% % \pgfplotspointonorientedsurfaceabsetupfor yxz% \pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@A=\pgfmathresult \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@B=\pgfmathresult \else \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPa=\pgfmathresult \pgfplotspointonorientedsurfaceabsetupforsetx{\pgfplots@loc@TMPa}{#1}% % \pgfplotspointonorientedsurfaceabsetupfor zyx% \ifpgfplots@threedim \pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@A=\pgfmathresult \else \def\pgfplots@loc@A{0}% \fi \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@B=\pgfmathresult \fi \fi % % read dimen argument #5: \afterassignment\pgfplots@gobble@until@relax \pgf@xa=#5pt\relax \edef\pgfplots@loc@distalong@normal{\pgf@sys@tonumber\pgf@xa}% % %\message{pgfplotspointoutsideofaxis{#1#2#3}{#4}{#5}: A = \pgfplots@loc@A, B = \pgfplots@loc@B.^^J}% % \pgf@process{% \pgfpointadd {\pgfplotspointonorientedsurfaceab{\pgfplots@loc@A}{\pgfplots@loc@B}} {% \pgfplotspointouternormalvectorofaxissetv{#1#2#3}{\pgfplots@loc@A}% \pgfqpointscale {\pgfplots@loc@distalong@normal}% {\pgfplotspointouternormalvectorofaxis{#1#2#3}}% }% }% \endgroup }% %-------------------------------------------------- % \def\pgfplotspointoutsideofaxis@#1#2#3\relax#4#5{% % \if v#1% % \def\pgfplots@loc@point@orthogonal@to@v{% % \pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult % \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPb=\pgfmathresult % \ifpgfplots@threedim % \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult % \else % \def\pgfplots@loc@TMPc{0}% % \fi % \pgfplotsqpointxyz{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}% % }% % \else % \if v#2% % \def\pgfplots@loc@point@orthogonal@to@v{% % \pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult % \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult % \ifpgfplots@threedim % \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult % \else % \def\pgfplots@loc@TMPc{0}% % \fi % \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPc}% % }% % \else % \def\pgfplots@loc@point@orthogonal@to@v{% % \ifpgfplots@threedim % \pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult % \else % \def\pgfplots@loc@TMPa{0}% % \fi % \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult % \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPc=\pgfmathresult % \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}{\pgfplots@loc@TMPa}% % }% % \fi % \fi % % % % read dimen argument #5: % \afterassignment\pgfplots@gobble@until@relax % \pgf@xa=#5pt\relax % \edef\pgfplots@loc@distalong@normal{\pgf@sys@tonumber\pgf@xa}% % % % % % \pgf@process{% % \pgfpointadd % {\pgfplots@loc@point@orthogonal@to@v} % {% % \pgfqpointscale % {\pgfplots@loc@distalong@normal}% % {\pgfplotspointouternormalvectorofaxis{#1#2#3}}% % }% % }% % \endgroup % }% %-------------------------------------------------- % Helper method for \pgfplotsqpointoutsideofaxis and its variants. % #1: an axis (x,y or z) % #2: o(\pgfplots@loc@TMPa - \pgfplots@loc@TMPb) ne of '0', '1' or '2' where % 0 == add lower #1 axis limit, % 1 == add upper #1 axis limit, % 2 == add nothing. % #3: the value to add. \def\pgfplotspointoutsideofaxis@getlimit@#1#2{% \if#20% \expandafter\let\expandafter\pgfmathresult\csname pgfplots@#1min\endcsname \else \if#21% \expandafter\let\expandafter\pgfmathresult\csname pgfplots@#1max\endcsname \else \expandafter\let\expandafter\pgfmathresult\csname pgfplots@logical@ZERO@#1\endcsname \fi \fi }% \newif\ifpgfplots@sloped \pgfplots@slopedtrue % its only purpose is to *DEACTIVATE* the sloped transformation after it has been activated. \newif\ifpgfplots@sloped@resets@nontranslations \newif\ifpgfplots@sloped@allowupsidedown \pgfkeys{ /pgfplots/sloped/true/.code={\pgfplots@slopedtrue}, /pgfplots/sloped/false/.code={\pgfplots@slopedfalse}, /pgfplots/sloped/allow upside down/.is if=pgfplots@sloped@allowupsidedown, /pgfplots/sloped/allow upside down/.default=true, /pgfplots/sloped/execute for upside down/.initial=, /pgfplots/sloped/reset nontranslations/.is if=pgfplots@sloped@resets@nontranslations, /pgfplots/sloped/reset nontranslations/.default=true, } % Installs a rotation transformation matrix such that labels or % whatever are aligned precisely in direction of one of the two/three % coordinate directions. % % \pgfplotstransformtoaxisdirection[]{} % % : 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}} % % 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{% \begingroup \pgfutil@ifundefined{pgfreferencednodename}{% % use given transformation matrix. }{% \ifx\pgfreferencednodename\pgfutil@empty % just use the given transformation matrix - we are % typesetting an unlabeled node. \else \pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}% \fi }% % I only need to apply the trafo matrix to direction vectors. Eliminate % shifts. \pgf@pt@x=0pt \pgf@pt@y=0pt % % I'll apply the inverse transformation matrix to direction % vectors. To ensure the relative position of these vectors % and the anchors of the node, I have to invert the matrix: \pgftransforminvert % % % This here is the normal direction (points to the axis) \pgfqpointscale{-1}{\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}% % % 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). If we choose % this anchor, we *won't* penetrate the axis! % % This is a heuristicial procedure. % \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\pgfplots@anchor{% \pgfplots@ycomp \ifx\pgfplots@ycomp\pgfutil@empty \else \ifx\pgfplots@xcomp\pgfutil@empty \else \space \fi \fi \pgfplots@xcomp}% % % % 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: % % Now, 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 :-( % % 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). % Scale unit vector to length 1 to improve conditioning: \pgfqpointscale {\csname pgfplotsunit#1invlength\endcsname} {\csname pgfplotspointunit#1\endcsname}% \pgf@xa=\pgf@x \pgf@ya=\pgf@y \pgf@pos@transform\pgf@xa\pgf@ya % % 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}% }% % \pgf@sh@reanchor{#3}{center}% \edef\pgfplots@loc@center{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% % % apply inverse matrix to right-hand-side (and compute RHS): \pgfpointdiff% {}{} -> computes - {\pgfplots@loc@center}% {\pgf@sh@reanchor{#3}{\pgfplots@anchor}}% \edef\pgfplots@RHS{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}% % \pgfutilsolvetwotwoleq{\pgfplots@LEQ}{\pgfplots@RHS}% \def\pgfplots@extract##1##2{% \def\pgfplots@r{##1}% }% \expandafter\pgfplots@extract\pgfmathresult % GOT IT! % % compute x_c + r*n: \pgfpointadd {\pgfplots@loc@center}% {\pgfqpointscale{\pgfplots@r}{\pgfplots@tmp@normaldir}}% \else \message{^^JPGFPlots warning: The ticklabel anchor cannot be determined, the normal vector -(\the\pgf@xb,\the\pgf@yb) and the unit #1 vector (\the\pgf@xa,\the\pgf@ya) are almost parallel (abs(cos(angle)) = \the\pgf@xc)!^^J}% % 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 }% \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=\pgfmathparse{##1}, parsenumber=\pgfmathfloatparsenumber{##1}\pgfmathfloattofixed{##1},% zero= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{0}, one= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{1}, log e= \pgfmathlog@{##1},% log to display log=\pgfmath@basic@multiply@{##1}{2.3025851},% * log(10) log from display log=\pgfmath@basic@multiply@{##1}{0.434294},% / log(10) log unsigned int={% \edef\pgfmathresult{% \ifcase##1 \or0 \or0.693147 \or1.098612 \or1.386294 \or1.60943791 \or1.7917594 \or1.94591014 \or2.07944154 \or2.197224 \fi }% }, set log basis=\edef\pgfmathresult{{#1}{##1}}\expandafter\pgfplotscoordmath@log@set@basis\pgfmathresult, exp e={% % make sure the exponential can be represented, i.e. use % 'float' in the default repr: \pgfmathfloatparsenumber{##1}% \pgfmathfloatexp@\pgfmathresult% \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{\pgfmathresult}% }, tofixed= \edef\pgfmathresult{##1},% tostring= \edef\pgfmathresult{##1},% max= \pgfplotsmathmax{##1}{##2},% min= \pgfplotsmathmin{##1}{##2},% min limit= \def\pgfmathresult{-16300},% max limit= \def\pgfmathresult{16300},% if less than= {\pgfplotsmathlessthan{##1}{##2}\ifpgfmathfloatcomparison ##3\else ##4\fi}, if is= {% \if##20 \ifdim##1pt=0pt ##2\else ##3\fi \else \if##2+\ifdim##1pt>0pt ##2\else ##3\fi \else \if##2-\ifdim##1pt<0pt ##2\else ##3\fi \else \def\pgfplots@loc@TMPd{##1}\ifx\pgfplots@loc@TMPd\pgfutil@empty ##2\else ##3\fi \fi \fi \fi },% if is bounded=\edef\pgfplotsretval{##1}\ifx\pgfplotsretval\pgfutil@empty ##3\else ##2\fi, suffix= #1,% datascaletrafo set params=, datascaletrafo get params= \def\pgfmathresult{{0}{0}}, 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}},% % % Calls pgfmathparse. Note that this might need to switch to the % required math library (which is not necessarily cheap) parse/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parse\endcsname##1{#1}},% % % takes a parsed number and returns a fixed point number: tofixed/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tofixed\endcsname##1{#1}},% % % chooses a human readable string (which can be processed by parsenumber): tostring/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tostring\endcsname##1{#1}},% % % defines a max routine which returns the max of *exactly* two numbers: max/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max\endcsname##1##2{#1}},% % % counterpart for max: min/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min\endcsname##1##2{#1}},% % % defines \pgfmathresult to be the largest supported number. max limit/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max limit\endcsname{#1}},% % % defines \pgfmathresult to be the smallest supported number. min limit/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min limit\endcsname{#1}},% % % computes ##1 < ##2 and invokes ##3 in the true case and ##4 in % the false case. if less than/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if less than\endcsname##1##2##3##4{#1}},% % checks if ##1 is 0, positive, negative or unbounded % ##1: the number to check % ##2: either 0 or + or - or u (u = unbounded) % ##3: true code % ##4: false code if is/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is\endcsname##1##2##3##4{#1}},% % % Checks if the argument ##1 is bounded and invokes ##2 in that % case. IF the argument is unbounded, it invokes #3. if is bounded/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is bounded\endcsname##1##2##3{#1}},% % % applies the natural logarithm. If the log is not defined, the % argument is "unbounded", see 'if is bounded' % % 'log' is special in that it accepts a number literal which may % be OUTSIDE of the accepted number format. The result, however, is % then in the accepted number format. log e/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ log e\endcsname##1{#1}},% % % Similar, but the log basis can be set with 'set log basis'. % This allows \pgfplotscoordmath{x}{log}{} to use a different log % basis thatn \pgfplotscoordmath{y}{log}{} (with special handling) log/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log\endcsname##1{#1}},% % applies a *scale* from the actual log basis to the actual % *display* log basis. The display log basis is usually 10, unless % the log basis has been changed. log to display log/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to display log\endcsname##1{#1}},% % applies a *scale* from the displau log basis to the actual % log basis (the inverse of `log to display log'). log from display log/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log from display log\endcsname##1{#1}},% log to log 10/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to log 10\endcsname##1{#1}},% % returns log(i) where i \in {1,2,3,...,basis-1} % currently, it is only invoked for log basis 10 log unsigned int/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log unsigned int\endcsname##1{#1}},% % sets (changes) the actual log basis. set log basis/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ set log basis\endcsname##1{#1}},% % % The inverse to 'log e '. exp e/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ exp e\endcsname##1{#1}},% % % The inverse to 'log'. It also uses the correct log basis. exp/.code= {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp\endcsname##1{#1}},% % % A macro taking two parameters: % #1: the EXPONENT (as integer) % #2: the SHIFT (as fixed point number) % % After any change, \pgfplotscoordmathnotifydatascalesetfor{} 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) 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}, } \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}\pgfmathparse{#1}\pgfmath@smuggleone\pgfmathresult\endgroup, zero=\pgfmathfloatcreate{0}{0.0}{0},% one=\pgfmathfloatcreate{1}{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\pgfmathresult{% {\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% {\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}% }% },% 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 }% % Invokes '#1' if the axis contains the coordinate designated by % \pgfplots@current@point@[xyz] and '#2' if not. \def\pgfplotsaxisifcontainspoint#1#2{% \pgf@xa=\pgfplots@current@point@x pt % FIXME : SCOPE REGISTERS!? \pgf@ya=\pgfplots@current@point@y pt % \ifpgfplots@curplot@threedim \pgf@yb=\pgfplots@current@point@z pt % \fi \def\pgfplots@loc@TMPa{#2}% % % I assume that \pgfplots@[xyz]min@reg and min@reg are registers % containing the limits. \ifdim\pgf@xa<\pgfplots@xmin@reg \else \ifdim\pgf@xa>\pgfplots@xmax@reg \else \ifdim\pgf@ya<\pgfplots@ymin@reg \else \ifdim\pgf@ya>\pgfplots@ymax@reg \else \ifpgfplots@curplot@threedim \ifdim\pgf@yb<\pgfplots@zmin@reg \else \ifdim\pgf@yb>\pgfplots@zmax@reg \else \def\pgfplots@loc@TMPa{#1}% \fi \fi \else \def\pgfplots@loc@TMPa{#1}% \fi \fi \fi \fi \fi \pgfplots@loc@TMPa% } % Declares a routine which can be used to get point meta input. % % Such a routine is invoked in a context where point coordinates are % processed, i.e. during 'plot coordinates', 'plot table' or the like. % % The routine is called `#1'. It consists of several methods, which % are described below, in the key definitions. % % #1: the name of the input routine. % #2: a sequence of key-value pairs which can be used to overwrite % 'assign', 'initfor' or the other components. % See the definitions below for examples. \def\pgfplotsdeclarepointmetasource#1#2{% \expandafter\def\csname pgfpmeta@#1@assign\endcsname{\let\pgfplots@current@point@meta=\pgfutil@empty}% \expandafter\def\csname pgfpmeta@#1@initfor\endcsname##1{}% \expandafter\def\csname pgfpmeta@#1@issymbolic\endcsname{0}% \expandafter\def\csname pgfpmeta@#1@explicitinput\endcsname{0}% \expandafter\def\csname pgfpmeta@#1@activate\endcsname{}% \edef\pgfplotsdeclarepointmetasource@{#1}% \pgfqkeys{/pgfplots/@declare point meta src}{#2}% }% \pgfqkeys{/pgfplots/@declare point meta src}{% % % a macro used to initialise the point meta source when it is % selected. % This macro body is invoked by pgfplots when someone types % 'point meta=x' -> will invoke 'pgfpmeta@x@initfor{}'. % The first argument to initfor can be supplied by the user. % PRECONDITION for 'initfor': % - it will be invoked just before % '\pgfplotspointmetainputhandler' will be changed. % Default is to do nothing. initfor/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @initfor\endcsname##1{#1}},% % % Called during the survey phase before the first 'assign' call. % It is usually empty. activate/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @activate\endcsname{#1}},% % % During the survey phase, this macro is expected to assign % \pgfplots@current@point@meta % if it is a numeric input method, it should return a % floating point number. % It is allowed to return an empty string to say "there is no point % meta". % PRECONDITION for '@assign': % - the coordinate input method has already assigned its % '\pgfplots@current@point@meta' (probably as raw input string). % - the other input coordinates are already read. % POSTCONDITION for '@assign': % - \pgfplots@current@point@meta is ready for use: % - EITHER a parsed floating point number % - OR an empty string, % - OR a symbolic string (if the issymbolic boolean is true) % The default implementation is % \let\pgfplots@current@point@meta=\pgfutil@empty % assign/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @assign\endcsname{#1}},% % % expands to either '1' or '0' % A numeric source will be processed numerically in float % arithmetics. Thus, the output of the @assign routine should be % a macro \pgfplots@current@point@meta in float format. % % The output of a numeric point meta source will result in meta % limit updates and the final map to [0,1000] will be % initialised automatically. % % A symbolic input routine won't be processed. % Default is '0' % issymbolic/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @issymbolic\endcsname{#1}},% % % expands to either % '1' or '0'. In case '1', it expects explicit input from the % coordinate input routines. For example, 'plot file' will look for % further input after the x,y,z coordinates. % Default is '0' % explicitinput/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @explicitinput\endcsname{#1}},% }% % 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 }} \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 }} \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 }} \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% }% \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 }, }% \pgfkeyssetvalue{/pgfplots/point meta/expr}{}% \pgfplotsdeclarepointmetasource{f(x)}{% activate={% \ifpgfplots@curplot@threedim \def\pgfplotspointmetainputhandler{z}% \else \def\pgfplotspointmetainputhandler{y}% \fi \csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname }, }% \pgfplotsdeclarepointmetasource{TeX code}{% assign={% \begingroup \let\pgfplotspointmeta=\pgfutil@empty \pgfplots@invoke@pgfkeyscode{/pgfplots/point meta/code/.@cmd}{}% \pgfplotscoordmath{meta}{parsenumber}{\pgfplotspointmeta}% \let\pgfplots@current@point@meta=\pgfmathresult \pgfmath@smuggleone\pgfplots@current@point@meta \endgroup },% initfor={% \pgfkeysdef{/pgfplots/point meta/code}{#1}% }, }% \pgfplotsdeclarepointmetasource{TeX code symbolic}{% assign={% \begingroup \let\pgfplotspointmeta=\pgfutil@empty \pgfplots@invoke@pgfkeyscode{/pgfplots/point meta/code/.@cmd}{}% \let\pgfplots@current@point@meta=\pgfplotspointmeta \pgfmath@smuggleone\pgfplots@current@point@meta \endgroup },% initfor={% \pgfkeysdef{/pgfplots/point meta/code}{#1}% }, issymbolic=1% }% \pgfkeysdef{/pgfplots/point meta/code}{}% % Internal stream methods. % % Please overwrite % - \pgfplots@coord@stream@start@, % - \pgfplots@coord@stream@end@ and % - \pgfplots@coord@stream@coord@ % if you implement streams. % % REMARK: % - the stream methods automatically collect first and last % coordinates. % - I have experimented with global \addplot accumulation to reduce % copy operations. That experiment was not successfull (it was not % faster :-( ). However, the streaming methods still assign their % things globally... \def\pgfplots@coord@stream@start{% \let\pgfplots@current@point@x=\pgfutil@empty \let\pgfplots@current@point@y=\pgfutil@empty \let\pgfplots@current@point@z=\pgfutil@empty \let\pgfplots@current@point@meta=\pgfutil@empty \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \let\pgfplots@current@point@z@error=\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 results 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 \noexpand\pgfplotsplothandlernotifyscanlinecomplete }% \expandafter\let\expandafter\pgfplotsscanlinelengthcleanup \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @cleanup\endcsname \pgfplotsscanlinelength@initzero }% \newif\ifpgfplots@emptyline@compat % Invoked for 'empty line=auto'. % % @POSTCONDITION: '/pgfplots/empty line' is set to something useful % (not auto) \def\pgfplotsdetermineemptylinehandler{% \if n\pgfplots@meshmode % no mesh/surf plot: \pgfkeyssetvalue{/pgfplots/empty line}{jump}% \ifpgfplots@emptyline@compat \pgfkeyssetvalue{/pgfplots/empty line}{none}% do nothing for backwards compatibility with 2D processing. \fi \else % it is a mesh or surf plot; use scanline: \pgfkeyssetvalue{/pgfplots/empty line}{scanline}% \fi }% \def\pgfplotsscanlinedisablechanges{% \let\pgfplotsscanlinecomplete=\relax \let\pgfplotsscanlinelengthincrease=\relax \let\pgfplotsscanlinelengthcleanup=\relax \let\pgfplotsscanlinelengthinitzero=\relax \let\pgfplotsscanlineendofinput=\relax }% % ------------------------------------------------------------------------------- % empty line=scanline % class: \def\pgfplotsscanlinelength@scanline@initzero{% \c@pgfplots@scanlineindex=0 \def\pgfplots@scanlinelength{-1}% } \def\pgfplotsscanlinelength@scanline@increase{% \advance\c@pgfplots@scanlineindex by1 } \def\pgfplotsscanlinelength@scanline@complete{% \ifnum\pgfplots@scanlinelength>0 \ifnum\c@pgfplots@scanlineindex=0 % % \pgfplotsscanlinecomplete % \pgfplotsscanlinecomplete % \pgfplotsscanlinecomplete % should have the same effect as a single statement. Do % nothing here. \else \ifnum\pgfplots@scanlinelength=\c@pgfplots@scanlineindex\relax \else %\message{Found inconsistent scan line length: \pgfplots@scanlinelength\space vs. \the\c@pgfplots@scanlineindex\space near line \pgfplotstablelineno.}% % special marker which means 'inconsistent scan line length found' \def\pgfplots@scanlinelength{-2}% \fi \fi \else \ifnum\pgfplots@scanlinelength=-2 \else \edef\pgfplots@scanlinelength{\the\c@pgfplots@scanlineindex}% \fi \fi \c@pgfplots@scanlineindex=0 } \def\pgfplotsscanlinelength@scanline@cleanup{% \ifnum\c@pgfplots@scanlineindex=0 % I assume the last scan line is already complete. \else \pgfplotsscanlinecomplete \fi \let\pgfplotsscanlinelength=\pgfplots@scanlinelength } % ------------------------------------------------------------------------------- % % empty line=none class: % \let\pgfplotsscanlinelength@none@initzero=\pgfutil@empty \let\pgfplotsscanlinelength@none@increase=\relax \let\pgfplotsscanlinelength@none@complete=\relax \let\pgfplotsscanlinelength@none@cleanup=\relax % ------------------------------------------------------------------------------- % % empty line=nan class: \def\pgfplotsscanlinelength@nan@initzero{% \def\pgfplotsscanlinelength@nan@isfirst{1}% \let\pgfplotsscanlinelength@nan@pendingwork=\relax \pgfplotsifinaxis{}{\let\pgfplotsaxisserializedatapoint=\relax}% }% \def\pgfplotsscanlinelength@nan@increase{% \def\pgfplotsscanlinelength@nan@isfirst{0}% \pgfplotsscanlinelength@nan@pendingwork }% \def\pgfplotsscanlinelength@nan@complete{% \if1\pgfplotsscanlinelength@nan@isfirst \else \def\pgfplotsscanlinelength@nan@pendingwork{% % this will be executed when the next point has been % found. \def\pgfplots@current@point@x{}% \def\pgfplots@current@point@y{}% \def\pgfplots@current@point@z{}% % simply serialize an empty point. That works -- the % visualization phase checks if the coordinates are empty and % visualizes them as "jump" % % Note that \pgfplotsplothandlersurveypoint is not a good % choice here unless one employs its 'unbounded coords=jump' % feature \def\pgfplotsaxisplothasjumps{1}% \pgfplotsaxisserializedatapoint % \let\pgfplotsscanlinelength@nan@pendingwork=\relax }% \fi \def\pgfplotsscanlinelength@nan@isfirst{1}% }% \let\pgfplotsscanlinelength@nan@cleanup=\relax % % ------------------------------------------------------------------------------- \def\pgfplotsaxisfilteredcoordsaway{0}% \def\pgfplotsaxisplothasjumps{0}% \newif\ifpgfplotsaxisparsecoordinateok % Initialises % \pgfplots@coord@stream@start % \pgfplots@coord@stream@coord % \pgfplots@coord@stream@end % such that a following coordinate stream is processed properly. The % following coordinate stream may come from different input methods. % % This coordinate stream is the first time a coordinate will be % reported and processed by pgfplots. The task of this first pass is % to % - compute and update any axis limits, % - collect and prepare ranges for color data, % - handle stacked plots and error bars, % - store the complete state of the plot's preprocessing in an % internal datastructure for later completion. % This involves a serialization of all processed points (i.e. the % generation of a long coordinate list) % % Any \addplot command should issue \pgfplots@PREPARE@COORD@STREAM % eventually. % % Arguments: % #1: any trailing path commands after the 'plot' command as such, % for example \addplot plot coordinates {...} -- (0,0); % would yield #1 =' -- (0,0)' % % PRECONDITION: % - needs to be called inside of \addplot. % - \pgfplots@addplot@survey@@optionlist contains the % 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, % - recorded error bar commands: local, % - 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}% % \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\pgfplots@set@perpointmeta % \ifpgfplots@errorbars@enabled % This thing gets the 'current@point@...' context, % that means % \pgfplots@current@point@[xy] % \pgfplots@current@point@[xy]@error % \pgfplots@current@point@[xy]@unfiltered \E\pgfplots@PREPARE@errorbar@process@x% \E\pgfplots@PREPARE@errorbar@process@y% \E\pgfplots@PREPARE@errorbar@process@z% \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 }% \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{\pgfplots@set@perpointmeta}% % %\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}% \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 % \csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname \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}% % \pgfplots@prepare@visualization@dependencies % \ifpgfplots@errorbars@enabled % prepare error bar processing. % % The actual implementation stores every final drawing command % into a list. % % Prepare that list: \pgfplots@streamerrorbar@recordto{\pgfplots@recordederrorbar}% \pgfplots@streamerrorbarstart % % Now, prepare the coordinate processing for errorbars: \pgfplots@PREPARE@errorbar@processing@in@dir x% \pgfplots@PREPARE@errorbar@processing@in@dir y% \ifpgfplots@curplot@threedim \pgfplots@PREPARE@errorbar@processing@in@dir z% \else \let\pgfplots@PREPARE@errorbar@process@z=\relax \fi \else \let\pgfplots@recordederrorbar=\pgfutil@empty \fi \ifpgfplots@stackedmode \pgfplots@stacked@beginplot \fi % % Inside of math expressions, 'x', 'y' and 'z' expand to the % current x,y and z coords respectively. Introduce these (and some % more) shortcuts: \pgfplotsmathdeclarepseudoconstant{x}{\let\pgfmathresult=\pgfplots@current@point@x}% \pgfplotsmathdeclarepseudoconstant{y}{\let\pgfmathresult=\pgfplots@current@point@y}% \pgfplotsmathdeclarepseudoconstant{z}{\let\pgfmathresult=\pgfplots@current@point@z}% \pgfplotsmathdeclarepseudoconstant{rawx}{\let\pgfmathresult=\pgfplots@current@point@x@unfiltered}% \pgfplotsmathdeclarepseudoconstant{rawy}{\let\pgfmathresult=\pgfplots@current@point@y@unfiltered}% \pgfplotsmathdeclarepseudoconstant{rawz}{\let\pgfmathresult=\pgfplots@current@point@z@unfiltered}% \pgfplotsmathdeclarepseudoconstant{meta}{% \let\pgfmathresult=\pgfplots@current@point@meta \ifx\pgfmathresult\pgfutil@empty \pgfplotscoordmath{meta}{parsenumber}{0}% \fi }% % % %%%%%%%%%%%%%% % % Define \pgfplots@set@perpointmeta properly: \def\pgfplots@set@perpointmeta{% \if0\pgfplots@set@perpointmeta@done \csname pgfpmeta@\pgfplotspointmetainputhandler @assign\endcsname \def\pgfplots@set@perpointmeta@done{1}% \pgfplots@set@perpointmeta@limits \fi }% % append limit updating to \pgfplots@set@perpointmeta : \if0\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname % We need to work with per point meta data. % So, also compute the data range on a per-plot basis! % These limits are important later. \pgfkeysgetvalue{/pgfplots/point meta min}\pgfplots@metamin \t@pgfplots@tokb={}% \ifx\pgfplots@metamin\pgfutil@empty \global\let\pgfplots@metamin=\pgfplots@invalidrange@metamin \t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb \pgfplotscoordmath{meta}{min}{\pgfplots@metamin}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamin=\pgfmathresult }% \else \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamin}% \global\let\pgfplots@metamin=\pgfmathresult \fi \pgfkeysgetvalue{/pgfplots/point meta max}\pgfplots@metamax \ifx\pgfplots@metamax\pgfutil@empty \global\let\pgfplots@metamax=\pgfplots@invalidrange@metamax \t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb \pgfplotscoordmath{meta}{max}{\pgfplots@metamax}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamax=\pgfmathresult }% \else \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamax}% \global\let\pgfplots@metamax=\pgfmathresult \fi % \edef\pgfplots@set@perpointmeta@limits{% \noexpand\ifx\noexpand\pgfplots@current@point@meta\noexpand\pgfutil@empty \noexpand\else \the\t@pgfplots@tokb \noexpand\fi }% \def\pgfplotsaxisupdatelimitsforpointmeta##1{% \begingroup \def\pgfplots@current@point@meta{##1}% \pgfplots@set@perpointmeta@limits \endgroup }% \else % there is no point meta: \global\let\pgfplots@metamin=\pgfutil@empty \global\let\pgfplots@metamax=\pgfutil@empty \let\pgfplots@set@perpointmeta@limits=\relax \def\pgfplotsaxisupdatelimitsforpointmeta##1{}% \fi }% % This is the \pgfplots@coord@stream@end@ routine which is invoked by % \pgfplots@PREPARE@COORD@STREAM. % % It finalizes the first pass through the input coordinates and % remembers the preprocessed \addplot command. % % Technical note: The parameters provided to % \pgfplots@PREPARE@COORD@STREAM % are needed here. This doesn't fit directly into the framework of % coordinate streams, see \pgfplots@PREPARE@COORD@STREAM how this % invocation works. % % #1,#2: see \pgfplots@PREPARE@COORD@STREAM \def\pgfplots@PREPARE@COORD@STREAM@end@#1{% \pgfkeysvalueof{/pgfplots/execute at end survey}% \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@streamerrorbarend \fi \ifpgfplots@stackedmode \pgfplots@stacked@endplot \fi \ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty \pgfplots@warning{the current plot has no coordinates (or all have been filtered away)}% \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 \pgfplotspreparemeshkeydefaults% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting x% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting y% \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,% /pgfplots/.cd,/pgfplots/every axis plot post}% \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% \ifpgfplots@curplot@isirrelevant % for \label commands: \expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}% \else \expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@addplot@survey@@optionlist}% \fi % 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}% % 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 \noexpand\def\noexpand\plotnum{\the\pgfplots@numplots}% % % store \plotnumofactualtype \noexpand\def\noexpand\plotnumofactualtype{\numplotsofactualtype}% % ... 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 % % 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}}% % \noexpand\pgfplots@initzerolevelhandler % 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\pgfplotsaxisfilteredcoordsaway{\pgfplotsaxisfilteredcoordsaway}% \noexpand\def\noexpand\pgfplotsaxisplothasjumps{\pgfplotsaxisplothasjumps}% \noexpand\pgfkeyssetvalue{/pgfplots/on layer}{\pgfkeysvalueof{/pgfplots/on layer}}% }% {% draw command: \noexpand\path% }% }% \pgfplotsapplistXXlet\pgfplots@coord@stream@recorded \pgfplotsapplistXXclear \t@pgfplots@tokc=\expandafter{\pgfplots@coord@stream@recorded}% \t@pgfplots@tokb={#1;}% \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 normalized coordinates {\the\t@pgfplots@tokc}\the\t@pgfplots@tokb }% }% % % Ok, now assemble the POST COMMANDS. Error bar % commands will be append here (if any) \ifx\pgfplots@recordederrorbar\pgfutil@empty \pgfplots@glob@TMPa {% % Post commands are empty here. }% \else \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPa}% \t@pgfplots@tokb=\expandafter{\pgfplots@recordederrorbar}% \def\pgfplots@loc@TMPb{% \noexpand\pgfplots@errorbars@finishwithstyleoptions[current plot style]{\the\t@pgfplots@tokb}% }% \xdef\pgfplots@glob@TMPa{ \the\t@pgfplots@toka { % Post commands: append error bar commands. \pgfplots@loc@TMPb }% }% \pgfplots@glob@TMPa \fi %^^^^^^^^^^^^ ... END of \pgfplots@addplot@enqueue@coords HERE \fi \pgfplots@end@plot }% % 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% }% \def\pgfplotsaxisserializedatapoint{% \pgfplotsplothandlerserializepointto\pgfplotsaxisserializedatapoint@val \pgfplotsaxisserializedatapoint@private \t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@val}% \t@pgfplots@tokb=\expandafter{\pgfplotsretval}% \edef\pgfplots@loc@TMPa{{\the\t@pgfplots@tokb;\the\t@pgfplots@toka}}% \expandafter\pgfplotsapplistXXpushback\expandafter{\pgfplots@loc@TMPa}% }% \def\pgfplotsaxisserializedatapoint@private{% \let\pgfplotsretval=\pgfplots@current@point@meta }% \def\pgfplotsaxisdeserializedatapointfrom@private#1{% \def\pgfplots@current@point@meta{#1}% }% % Restores the variables serialized in '#1'. % % As a side--effect, the macro % \pgfplotsaxisdeserializedatapointfrom@private@lastvalue will contain % the serialized part which is specific to pgfplots (i.e. the private % parts which can be read with % \pgfplotsaxisdeserializedatapointfrom@private) \def\pgfplotsaxisdeserializedatapointfrom#1{% \expandafter\pgfplotsaxisdeserializedatapointfrom@#1\pgfplots@EOI }% \def\pgfplotsaxisdeserializedatapointfrom@#1;#2\pgfplots@EOI{% \def\pgfplotsaxisdeserializedatapointfrom@private@lastvalue{#1}% \pgfplotsaxisdeserializedatapointfrom@private{#1}% \pgfplotsplothandlerdeserializepointfrom{#2}% }% % Handle User-defined parts which should be serialized as well. % This preparation tool should be called at the start of both, survey % and visualization phase. % % @PRECONDITION % - the macros % \pgfplotsaxisserializedatapoint@private % \pgfplotsaxisdeserializedatapointfrom@private % are known and valid. % - '/pgfplots/visualization depends on' contains its correct value. % % @POSTCONDITION % Both, % \pgfplotsaxisserializedatapoint@private % and % \pgfplotsaxisdeserializedatapointfrom@private % have been patched to incorporate the '/pgfplots/visualization % depends on' feature. % \def\pgfplots@prepare@visualization@dependencies{% \pgfkeysgetvalue{/pgfplots/visualization depends on/list}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfutil@empty \else % SERIALIZATION format: % visualization depends on={{value1}\as \macro1, {}\as \macro2,...} % -> % {}<\macro1>{}<\macro2>{}...<\macroN>{} % % prepare % \t@pgfplots@tokb={<\macro1>{}<\macro2>{}...<\macroN>{}} \t@pgfplots@tokb={}% % % prepare % \t@pgfplots@tokc={<\macro1><\macro2><\macro3>...} \t@pgfplots@tokc={}% \expandafter\pgfplotsutilforeachcommasep\expandafter{\pgfplots@loc@TMPa}\as\pgfplots@loc@TMPa{% \ifx\pgfplots@loc@TMPa\pgfutil@empty \else \expandafter\pgfplots@prepare@visualization@depends@on\pgfplots@loc@TMPa\pgfplots@EOI% \fi }% % Step 1: modify the SERIALIZATION method: \t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@private}% \edef\pgfplotsaxisserializedatapoint@private{% \the\t@pgfplots@tokc \the\t@pgfplots@toka % nothing is expanded here, only \t@pgfplots@tokb \noexpand\t@pgfplots@toka=\noexpand\expandafter{\noexpand\pgfplotsretval}% \noexpand\edef\noexpand\pgfplotsretval{{\noexpand\the\t@pgfplots@toka},\the\t@pgfplots@tokb}% }% % Step 2: modify the DESERIALIZATION method: \let\pgfplotsaxisdeserializedatapointfrom@private@orig=\pgfplotsaxisdeserializedatapointfrom@private \let\pgfplotsaxisdeserializedatapointfrom@private=\pgfplotsaxisdeserializedatapointfrom@private@withdeplist \fi % \pgfkeysgetvalue{/pgfplots/execute for finished point}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key \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#2}% }% \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{% \def#2{% \pgfmathparse{#1}% \pgfmathfloattofixed{\pgfmathresult}% \expandafter\let\csname \string#2@value\endcsname=\pgfmathresult }% }{% \def#2{% \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{% \begingroup % remove spaces from #1: \pgfkeys@spdef\pgfplots@loc@TMPa{#1}% \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 \let#2=\pgfplots@glob@TMPa } \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}{-}}% }% % Prepares a macro \pgfplots@PREPARE@process@errorbar@for@dir##1 % which can then be used to process error bars. The macro will be % \relax if error bars are disabled for #1. % % #1: either x, y or z. % % POSTCONDITION: % the macro \pgfplots@PREPARE@errorbar@process@#1 will be defined. % It is supposed to be used inside of the pgfplots streaming methods % and depends on the arguments % \pgfplots@current@point@[xyz] % \pgfplots@current@point@[xyz]@unfiltered % \pgfplots@current@point@[xyz]@error % The '@unfilterered' arguments are needed for log plots. I do not % want to compute exp(current@point@[xyz]) again. \def\pgfplots@PREPARE@errorbar@processing@in@dir#1{% \if0\csname pgfplots@errorbars@#1direction\endcsname % no error bars. Ok. Do nothing here. \expandafter\let\csname pgfplots@PREPARE@errorbar@process@#1\endcsname=\relax \else % % Prepare a macro which invokes % \pgfplots@streamerrorbarcoords. % % This involves to assign point coordinates in the correct % ordering; prepare that: \if x#1% \ifpgfplots@curplot@threedim \t@pgfplots@toka={% {(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)}% {(\pgfplots@error@coord,\pgfplots@current@point@y,\pgfplots@current@point@z)} }% \else \t@pgfplots@toka={% {(\pgfplots@current@point@x,\pgfplots@current@point@y)}% {(\pgfplots@error@coord,\pgfplots@current@point@y)} }% \fi \else \if y#1% \ifpgfplots@curplot@threedim \t@pgfplots@toka={% {(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)}% {(\pgfplots@current@point@x,\pgfplots@error@coord,\pgfplots@current@point@z)} }% \else \t@pgfplots@toka={% {(\pgfplots@current@point@x,\pgfplots@current@point@y)}% {(\pgfplots@current@point@x,\pgfplots@error@coord)} }% \fi \else \t@pgfplots@toka={% {(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)}% {(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@error@coord)} }% \fi \fi \begingroup % now, assemble the macro which will invoke % \pgfplots@streamerrorbarcoords: \let\E=\noexpand \expandafter\xdef\csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname{% \E\ifx\E\pgfplots@error@coord\E\pgfutil@empty \E\else \E\let\E\pgfplots@current@point@@old\expandafter\E\csname pgfplots@current@point@#1\endcsname \E\let\expandafter\E\csname pgfplots@current@point@#1\endcsname=\E\pgfplots@error@coord \E\pgfplotsaxisupdatelimitsforcoordinate\E\pgfplots@current@point@x\E\pgfplots@current@point@y\E\pgfplots@current@point@z \E\let\expandafter\E\csname pgfplots@current@point@#1\endcsname=\E\pgfplots@current@point@@old \E\edef\E\pgfplots@loc@TMPa{\the\t@pgfplots@toka}% \E\expandafter\E\pgfplots@streamerrorbarcoords\E\pgfplots@loc@TMPa \E\fi }% \endgroup % % The routine which is invoked for every reported input % coordinate is \pgfplots@process@errorbar@for. % % This here prepares its helper macros for direction '#1': \pgfplots@if{pgfplots@#1islinear}{% \ifcase\csname pgfplots@errorbars@#1mode\endcsname\relax % fixed absolute error. \pgfplotscoordmath{#1}{parsenumber}{\csname pgfplots@errorbars@#1fixed\endcsname}% \expandafter\let\csname pgfplots@error@coord@#1\endcsname=\pgfmathresult \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \if +##1% \def\pgfplots@loc@TMPb{add}% \else \def\pgfplots@loc@TMPb{subtract}% \fi \pgfplotscoordmath{#1}{op}{\pgfplots@loc@TMPb}{% {\csname pgfplots@current@point@#1\endcsname}% {\csname pgfplots@error@coord@#1\endcsname}% }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% fixed relative error: \pgfplotscoordmath{#1}{parsenumber}{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: \pgfplotscoordmath{#1}{parsenumber}{1}% \let\pgfplots@loc@TMPa=\pgfmathresult % % Prepare '1 + err': \pgfplotscoordmath{#1}{op}{add}{% {\pgfplots@loc@TMPa}% {\pgfplots@loc@TMPb}% }% \expandafter\let\csname pgfplots@error@coord@#1@+\endcsname=\pgfmathresult % % Prepare '1 - err': \pgfplotscoordmath{#1}{op}{subtract}{% {\pgfplots@loc@TMPa}% {\pgfplots@loc@TMPb}% }% \expandafter\let\csname pgfplots@error@coord@#1@-\endcsname=\pgfmathresult % \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \pgfplotscoordmath{#1}{op}{multiply}{% {\csname pgfplots@current@point@#1\endcsname} {\csname pgfplots@error@coord@#1@##1\endcsname}% }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% explicit absolute: \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else \pgfplotscoordmath{#1}{parsenumber}{\pgfplots@error@coord}% \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% \let\pgfplots@error@coord=\pgfmathresult % remember result here - will be used in case % of '+' AND '-' error bars: \expandafter\let\csname pgfplots@current@point@#1@error\endcsname=\pgfmathresult \if +##1% \def\pgfplots@loc@TMPb{add}% \else \def\pgfplots@loc@TMPb{subtract}% \fi \pgfplotscoordmath{#1}{op}{\pgfplots@loc@TMPb}{% {\csname pgfplots@current@point@#1\endcsname}% {\pgfplots@error@coord}% }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }{% % input is unbounded. Skip it. }% \fi }% \or% explicit relative: \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else \pgfplotscoordmath{#1}{parsenumber}{\pgfplots@error@coord}% \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% \let\pgfplots@error@coord=\pgfmathresult % compute ' 1 + value' or '1-value': \pgfplotscoordmath{#1}{one}% \if +##1% \def\pgfplots@loc@TMPb{add}% \else \def\pgfplots@loc@TMPb{subtract}% \fi \pgfplotscoordmath{#1}{op}{\pgfplots@loc@TMPb}{% {\pgfmathresult}% {\pgfplots@error@coord}% }% \let\pgfplots@error@coord=\pgfmathresult \pgfplotscoordmath{#1}{multiply}{% {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }{% % input is unbounded. Skip it. }% \fi }% \fi }{% % LOGARITHMIC scaling. All errors are interpreted as % log(x +- e_x) % or % log( x*(1+-e_x) ) % % That means any input argument is % given in log base e and in fixed point. % Furthermore, we expect the '@unfiltered' keys to be % present (I don't want to apply 'exp' again!). % \ifcase\csname pgfplots@errorbars@#1mode\endcsname % fixed absolute, log( x +- e_x ) % \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@errorbars@#1fixed\endcsname}% \expandafter\let\csname pgfplots@error@coord@#1\endcsname=\pgfmathresult \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \def\pgfplots@loc@op{add}% \else \def\pgfplots@loc@op{subtract}% \fi \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% {\pgfplots@loc@TMPa}% {\csname pgfplots@error@coord@#1\endcsname}% }% \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% fixed relative, log( x ( 1+-e_x ) ) = log(x) + log(1+-e_x) \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: \pgfplotscoordmath{default}{one}% \let\pgfplots@loc@TMPa=\pgfmathresult % % Prepare '1 + err': \pgfplotscoordmath{default}{op}{add}{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}}% \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% }{% % 1 + err <= 0 and log(1+err) is undefined: \pgfplotscoordmath{default}{tostring}{\pgfplots@loc@TMPb}% \pgfplots@error{Sorry, log(1 + \pgfmathresult) is undefined. Please provide a different argument for '/pgfplots/error bar/#1 fixed relative'.}% \let\pgfmathresult=\pgfutil@empty }% \expandafter\let\csname pgfplots@error@coord@#1@+\endcsname=\pgfmathresult % % Prepare '1 - err': \pgfplotscoordmath{default}{op}{subtract}{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}}% \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% }{% % 1 - err <= 0 and log(1+err) is undefined: \pgfplotscoordmath{default}{tostring}{\pgfplots@loc@TMPb}% \pgfplots@error{Sorry, log(1 - \pgfmathresult) (\pgfplots@loc@TMPa - \pgfplots@loc@TMPb) is undefined. Please provide a different argument for '/pgfplots/error bar/#1 fixed relative'.}% \let\pgfmathresult=\pgfutil@empty }% \expandafter\let\csname pgfplots@error@coord@#1@-\endcsname=\pgfmathresult % \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \expandafter\ifx\csname pgfplots@current@point@#1@##1\endcsname\pgfutil@empty \else \pgfmath@basic@add@ {\csname pgfplots@current@point@#1\endcsname} {\csname pgfplots@error@coord@#1@##1\endcsname}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \fi }% \or% explicit absolute % log( x +- e_x ) \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else \pgfplotscoordmath{default}{parsenumber}{\pgfplots@error@coord}% \pgfplotscoordmath{default}{if is bounded}{\pgfmathresult}{% \let\pgfplots@error@coord=\pgfmathresult % remember result here - will be used in case % of '+' AND '-' error bars: \expandafter\let\csname pgfplots@current@point@#1@error\endcsname=\pgfmathresult \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \def\pgfplots@loc@op{add}% \else \def\pgfplots@loc@op{subtract}% \fi \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% }% \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }{% % input is unbounded. Skip it. }% \fi }% % \or% explicit relative: % log( x ( 1+-e_x ) ) = log(x) + log(1+-e_x) \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else \pgfplotscoordmath{default}{parsenumber}{\pgfplots@error@coord}% \pgfplotscoordmath{default}{if is bounded}{\pgfmathresult}{% \let\pgfplots@error@coord=\pgfmathresult % remember result here - will be used in case % of '+' AND '-' error bars: \expandafter\let\csname pgfplots@current@point@#1@error\endcsname=\pgfmathresult % \pgfplotscoordmath{default}{one}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \def\pgfplots@loc@op{add}% \else \def\pgfplots@loc@op{subtract}% \fi \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% }% \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% \pgfplotscoordmath{#1}{op}{add}{% {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }{% % -> log( <= 0 ) -> do nothing. }% }{% % input is unbounded - do nothing. }% \fi }% % \fi }% \ifcase\csname pgfplots@errorbars@#1direction\endcsname % none \or % plus \expandafter\edef\csname pgfplots@PREPARE@errorbar@process@#1\endcsname{% \expandafter\noexpand\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname+% }% \or % minus \expandafter\edef\csname pgfplots@PREPARE@errorbar@process@#1\endcsname{% \expandafter\noexpand\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname-% }% \or % both \expandafter\edef\csname pgfplots@PREPARE@errorbar@process@#1\endcsname{% \expandafter\noexpand\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname+% \expandafter\noexpand\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname-% }% \fi \fi } % 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}{% \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}% \pgfplots@warning{The per point meta data `\pgfmathresult' (##1) (and probably others as well) is unbounded - using the minimum value instead.}% \endgroup \gdef\pgfplots@perpointmeta@unboundedwarning@stop{1}% \fi }% \else \def\pgfplots@perpointmeta@unboundedwarning##1{}% \fi \if m\pgfplots@colormap@access % colormap access=map \ifx\pgfplots@metamax\pgfutil@empty \def\pgfplots@perpointmeta@trafo##1{% \pgfplotscoordmath{meta}{if is}{##1}{u} {% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##1}% }{% \pgfplotscoordmath{meta}{tofixed}{##1}% }% }% \def\pgfplots@perpointmeta@traforange{0:1000}% \edef\pgfplotspointmetarange{0:1000}% \else % The transformation is % % phi(m) = ( m- meta_min) * 1000/ (meta_max-meta_min). % % -> precompute the scaling factor! \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 \if\pgfplots@perpointmeta@rel@choice0% % point meta rel=axis wide: \pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@axiswide@}% \else \pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@}% \fi \fi \else % colormap access=direct \def\pgfplots@perpointmeta@trafo##1{% \pgfplotscoordmath{meta}{if is}{##1}{u}{% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##1}% }{% \pgfplotscoordmath{meta}{tofixed}{##1}% }% }% \def\pgfplots@perpointmeta@traforange{0:0}% \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% \fi \edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}% }{}% }% % Employs \csname #1metamin\endcsname and its metamax counterpart to % initialize the trafo. % % This unifies the approaches for \pgfplots@axiswide@metamax and % \pgfplots@metamax. \def\pgfplots@perpointmeta@preparetrafo@initfrom#1{% \edef\pgfplotspointmetarange{\csname #1metamin\endcsname:\csname #1metamax\endcsname}% % Now, prepare the trafo as such. % It assigns \pgfmathresult (in fixed point). \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 % % 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{% \ifx\pgfplots@current@point@meta\pgfutil@empty% \pgfplots@error{could not access the 'point meta' (used for example by scatter plots and color maps). Maybe you need to add '\string\addplot[point meta=y]' or something like that?}% \pgfplotscoordmath{meta}{one}% \let\pgfplotspointmeta=\pgfmathresult \def\pgfplotspointmetatransformed{1.0}% \else % prepare arguments: \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname \let\pgfplotspointmeta=\pgfplots@current@point@meta \let\pgfplotspointmetatransformed=\pgfplotspointmeta \else \let\pgfplotspointmeta=\pgfplots@current@point@meta \pgfplots@perpointmeta@trafo{\pgfplotspointmeta}% \let\pgfplotspointmetatransformed=\pgfmathresult \fi \fi }% % 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) [meta]' % or % '(x,y) +- (ex,ey) [meta]' % separated by white-space. % % The per-point meta is not implemented yet. \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 }% % A looping command to loop through plot coordinates. % For every point, #1{X}{Y} will be invoked. % % No scoping is used during this operation, so you can access outer % variables. \def\pgfplots@foreach@plot@coord@ITERATE{% \pgfutil@ifnextchar\pgfplots@EOI{% \pgfplots@foreach@plot@coord@FINISH% }{% \pgfutil@ifnextchar\par{% \pgfplotsscanlinecomplete \pgfplots@foreach@plot@coord@ITERATE@gobbleone }{% \pgfutil@ifnextchar({% \pgfplotsscanlinelengthincrease \pgfplots@foreach@plot@coord@NEXT% }{% \pgfplots@foreach@plot@coord@error }% }% }% } \long\def\pgfplots@foreach@plot@coord@error#1\pgfplots@EOI{% \pgfplots@error{Sorry, I could not read the plot coordinates near '#1'. Please check for format mistakes.}% }% \long\def\pgfplots@foreach@plot@coord@ITERATE@gobbleone#1{\pgfplots@foreach@plot@coord@ITERATE}% \def\pgfplots@foreach@plot@coord@NEXT(#1){% \edef\pgfmathresult{#1}% \expandafter\pgfplots@foreach@plot@coord@NEXT@\expandafter(\pgfmathresult)% } \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 \pgfutil@ifnextchar+{% \pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE% }{% \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \pgfutil@ifnextchar[{% \pgfplots@foreach@plot@coord@NEXT@meta }{% \let\pgfplots@current@point@meta=\pgfutil@empty \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 }% % processing something like '(x,y) +- (error_x,error_y)' \def\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE+-#1({% \pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@% } \def\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@#1,#2){% \ifpgfplots@plot@coords@mathparser \pgfmathparse{#1}\let\pgfplots@current@point@x@error=\pgfmathresult \pgfmathparse{#2}\let\pgfplots@current@point@y@error=\pgfmathresult \else \def\pgfplots@current@point@x@error{#1}% \def\pgfplots@current@point@y@error{#2}% \fi \pgfutil@ifnextchar[{% \pgfplots@foreach@plot@coord@NEXT@meta }{% \let\pgfplots@current@point@meta=\pgfutil@empty \pgfplots@coord@stream@coord \pgfplots@foreach@plot@coord@ITERATE }% } \def\pgfplots@foreach@plot@coord@FINISH\pgfplots@EOI{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%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{% \pgfutil@ifnextchar\pgfplots@EOI{% \pgfplots@foreach@plot@coord@FINISH% }{% \pgfutil@ifnextchar\par{% \pgfplotsscanlinecomplete \pgfplots@foreach@plot@coord@threedim@ITERATE@gobbleone }{% \pgfutil@ifnextchar({% \pgfplotsscanlinelengthincrease \pgfplots@foreach@plot@coord@threedim@NEXT% }{% \pgfplots@foreach@plot@coord@error }% }% }% } \long\def\pgfplots@foreach@plot@coord@threedim@ITERATE@gobbleone#1{\pgfplots@foreach@plot@coord@threedim@ITERATE}% \def\pgfplots@foreach@plot@coord@threedim@NEXT(#1){% \edef\pgfmathresult{#1}% \expandafter\pgfplots@foreach@plot@coord@threedim@NEXT@\expandafter(\pgfmathresult)% } \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 \pgfutil@ifnextchar+{% \pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE% }{% \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \let\pgfplots@current@point@z@error=\pgfutil@empty \pgfutil@ifnextchar[{% \pgfplots@foreach@plot@coord@threedim@NEXT@meta }{% \let\pgfplots@current@point@meta=\pgfutil@empty \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 }% % processing something like '(x,y) +- (error_x,error_y)' \def\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE+-#1({% \pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@% } \def\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@#1,#2,#3){% \ifpgfplots@plot@coords@mathparser \pgfmathparse{#1}\let\pgfplots@current@point@x@error=\pgfmathresult \pgfmathparse{#2}\let\pgfplots@current@point@y@error=\pgfmathresult \pgfmathparse{#3}\let\pgfplots@current@point@z@error=\pgfmathresult \else \def\pgfplots@current@point@x@error{#1}% \def\pgfplots@current@point@y@error{#2}% \def\pgfplots@current@point@z@error{#3}% \fi \pgfutil@ifnextchar[{% \pgfplots@foreach@plot@coord@threedim@NEXT@meta }{% \let\pgfplots@current@point@meta=\pgfutil@empty \pgfplots@coord@stream@coord \pgfplots@foreach@plot@coord@threedim@ITERATE }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%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 \pgfplotscoordstream@firstlast@update \expandafter\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE \fi } % A common routine which resets internal data structures for the % survey phase, i.e. it is the shared implementation for all \addplot % variations. % % It takes all options which are provided to \addplot, sets them (at % least partially) and remembers them for the command serialization. % % #1: arguments to \addplot plot[#1] % -> these are called 'behavior' options in the manual; they are set % immediately. % % PRECONDITION: % \pgfplots@addplotimpl@plot@withoptions has already been invoked % % POSTCONDITION: % - internal datastructures are initialised (coordinate indexing, fpu) % - all keys which are required for the current plot are determined % (and set if necessary). % They are stored into % \pgfplots@addplot@survey@@optionlist. % \def\pgfplots@start@plot@with@behavioroptions#1{% %\begingroup%<-- has been moved to \pgfplots@addplotimpl@plot@withoptions \c@pgfplots@coordindex=0 \def\pgfplots@current@point@coordindex{\the\c@pgfplots@coordindex}% can be used inside of coordinate filters. \def\coordindex{\pgfplots@current@point@coordindex}% valid inside of \addplot \def\pgfplots@addplot@running{1}% % \def\pgfplots@colorbar@set@src{0}% \pgfkeysdef{/pgfplots/colorbar source}{% \pgfplotsutilifstringequal{##1}{true}{% \def\pgfplots@colorbar@set@src{1}% }{% \pgfplotsutilifstringequal{##1}{false}{% \def\pgfplots@colorbar@set@src{0}% }{% \pgfplots@error{Sorry, I don't know the value `colorbar source={##1}' and I am going to ignore it. Maybe you misspelled it?}% }% }% }% % % 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: \pgfplotsset{/pgfplots/every axis plot,#1}% % \ifpgfplots@curplot@isirrelevant \def\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every forget plot}% \pgfplotsset{/pgfplots/every forget plot,/pgfplots/every axis plot post}% \else \edef\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% \pgfplotsset{/pgfplots/every axis plot no \the\pgfplots@numplots/.try,/pgfplots/every axis plot post}% \fi % % enable FPU after any \pgfplotsset operations. Otherwise things like % linewidth=... which use the math parser might fail. \ifpgfplots@usefpu \pgfkeys{/pgf/fpu=true}% \fi % % make sure it is reset, just in case it is not supported by the % input method. \pgfplotsscanlinelengthinitzero % \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler \pgfplotsresetplothandler \pgfplots@basiclevel@plothandler % \pgfplots@countplots@init % % hooks: \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% \pgfkeysvalueof{/pgfplots/execute at begin plot}% % \if1\pgfplots@colorbar@set@src \expandafter\def\expandafter\pgfplots@addplot@survey@@optionlist\expandafter{\pgfplots@addplot@survey@@optionlist,% /pgfplots/point meta rel=per plot}% \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@validate@plot@domain@arguments } \long\def\pgfplotsplothandlersurveyaddoptions#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% }% }% % 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 [