%-------------------------------------------- % % 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/2008 by Christian Feuersänger. % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % %-------------------------------------------- % 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 }% \let\pgfpointxy@orig=\pgfpointxy \let\pgfqpointxy@orig=\pgfqpointxy \let\pgfpointxyz@orig=\pgfpointxyz \let\pgfqpointxyz@orig=\pgfqpointxyz % % 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}}% }% }% \edef\pgfplotspointunitx{\global\pgf@x=\the\pgf@xx\space\global\pgf@y=\the\pgf@xy\space}% \edef\pgfplotspointunity{\global\pgf@x=\the\pgf@yx\space\global\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{\global\pgf@x=\the\pgf@zx\space\global\pgf@y=\the\pgf@zy\space}% \let\pgfplotsunitzlength=\pgfplots@z@veclength \let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength \fi % % 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{x}}}% \pgfkeysdef{/tikz/sloped like y axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection{y}}}% \pgfkeysdef{/tikz/sloped like z axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection{z}}}% % }% % 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: % \pgfplotspointonorientedsurfaceabsetupforxyz % \pgfplotspointonorientedsurfaceabsetupforsetz{}{0} % % -> % \pgfplotspointonorientedsurfaceA = x % \pgfplotspointonorientedsurfaceB = y % \pgfplotspointonorientedsurfaceN = z % \pgfplotspointonorientedsurfacespec = {ab0} % \pgfplotspointonorientedsurfacespecunordered = {vv0} % \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{3}{4}{} % % \pgfplotspointonorientedsurfaceabsetupforyxz % \pgfplotspointonorientedsurfaceabsetupforsetz{}{0} % -> % \pgfplotspointonorientedsurfaceA = y % \pgfplotspointonorientedsurfaceB = x % \pgfplotspointonorientedsurfaceN = z % \pgfplotspointonorientedsurfacespec = {ba0} % \pgfplotspointonorientedsurfacespecunordered = {vv0} % \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{4}{3}{} % % @see \pgfplotspointonorientedsurfaceabsetupforxyz \def\pgfplotspointonorientedsurfaceab#1#2{% \pgfplots@error{Internal logic error: \string\pgfplotspointonorientedsurfaceab\ used although surface has not been declared! You need to call \string\pgfplotspointonorientedsurfaceabsetupforxyz\ or its friends to do so.}% }% % 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} % 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\pgfplotspointonorientedsurfaceabsetupforxyz{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforyxz{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforxzy{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforzxy{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforyzx{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforzyx{% \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}% }% % Fixes 'x' to #1 for use in % \pgfplotspointonorientedsurfaceabsetupforzyx and % \pgfplotspointonorientedsurfaceabsetupforyzx. % % #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\pgfplotspointonorientedsurfaceabsetupforxy{% \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}% }% \def\pgfplotspointonorientedsurfaceabsetupforyx{% \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}% }% % 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: % \pgfplotspointonorientedsurfaceabsetupforxyz % \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 }% % Returns either '' (empty) or '-' (minus) for each of the two variing sides of the % oriented surface described by #1. % % The output value #2 = '' means that the positive b axis points to % the direction of the convex hull of the projected figure. % % The output value #2 = '-' means that the NEGATIVE b axis points to % the direction of the convex hull of the projected figure. % % The output value #3 is also either '' or '-'. It refers to the % direction of the 'n' axis of the surface which points to the convex % hull of the projected figure. % % The returned values are used to decide how to align tick labels such % that they are always outside of the convex hull of the projected % axis. % % #1: three characters denoting an oriented surface. % #2: a macro name. Will be filled either with '' (empty string) or % '-', encoding the direction of the 'b' axis of surface #1 which % points to the convex hull. % #3: a macro name. It takes the same values as '#2', but it refers to % the 'n' axis of surface #1. \def\pgfplotsgetdirectionstoconvexhullforsurf#1#2#3{% \pgfplotsgetdirectionstoconvexhullforsurf@#1\relax{#2}{#3}% } % 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} % \pgfplotspointonorientedsurfaceabsetupforyxz % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be 'v' because 'x=v' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsety{\ymin}{0} % \pgfplotspointonorientedsurfaceabsetupforxzy % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be '1' because 'z=1' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsety{\ymax}{1} % \pgfplotspointonorientedsurfaceabsetupforxzy % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be empty because 'y=0' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsetx{\xmax}{1} % \pgfplotspointonorientedsurfaceabsetupforyzx % \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 \pgfplots@error{The character '#1' is no valid element for a three-character axis line or surface description!}% \fi \fi \fi }% % 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). \def\pgfplotspointouternormalvectorofaxis#1{% \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 }% % 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 \if0\pgfplots@loc@char@for@baxis% % 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{-}% \else % in this case, the OUTSIDE area requires a plus sign - the b % axis already points to the inside. \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: \if0\pgfplots@loc@char@for@naxis% % 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{-}% \else % in this case, the OUTSIDE area requires a plus sign - the n % axis already points to the inside. \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% \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: one 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 \fi \fi }% % Installs a rotation transformation matrix such that labels or % whatever are aligned precisely in direction of one of the two/three % coordinate directions. % % #1: 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 assumes \ifpgfallowupsidedownattime = false and % \ifpgfresetnontranslationattime = true \def\pgfplotstransformtoaxisdirection#1{% \pgftransformresetnontranslations % % compute unit length vector pointing into the direction of % '#1#2#3': \pgfqpointscale{\csname pgfplotsunit#1invlength\endcsname}{\csname pgfplotspointunit#1\endcsname}% % % do not allow upside down labels: \ifdim\pgf@x<0pt% \global\pgf@x=-\pgf@x% \global\pgf@y=-\pgf@y% \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}% } % 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. % #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 % \edef\pgfplots@LEQ{% % solve linear system {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xa}% {\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@ya}% }% % % apply inverse matrix to right-hand-side (and compute RHS): \pgf@sh@reanchor{#3}{center}% \edef\pgfplots@loc@center{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% \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}}% %\message{==========>>>>>>>>>> I got finally (\the\pgf@x,\the\pgf@y). <<<<<<<<<===================}% \pgf@process{}% <- transport outside of group \endgroup }% % Takes azimuth (horizontal angle) '#1' and elongation (vertical % angle) '#2' (both in degrees) and computes % x,y and z vectors which define the view in the direction % defined by '#1' and '#2'. % % 'azimuth' means a rotation around the viewport's x axis. 'elongation' means % a rotation around the original coordinate system's z axis. % % The method works by computing % Az = [ cos(azimuth) -sin(azimuth) 0; ... % sin(azimuth) cos(azimuth) 0; ... % 0 0 1 ]; % % % Ax = [ 1 0 0; ... % 0 cos(elevation) -sin(elevation) ;... % 0 sin(elevation) cos(elevation) ]; % % v= Ax * Az; % = [ ... % cosaz -sinaz cosel sinaz sinel; ... % sinaz cosaz cosel -sinel cosaz; ... % 0 sinel cosel ]; % % Then, we use the rotated XZ plane as viewport, that means % xvec = v * [1 0 0]' = % zvec = v * [0 0 1]' = % and we define the projection onto the twodimensional surface % spanned by 'xvec' and 'zvec' as % P( q ) = [ q^T xvec, q^T zvec ]' % for q in R^3. % As a consequence, we compute the three unit vectors as % x = P( [1 0 0] ) % = [ cosaz, sinaz sinel ]' % y = P( [0 1 0] ) % = [ sinaz, -sinel cosaz ]' % z = P( [0 0 1] ) % = [ 0, cosel]' % % Furthermore, the 3D view vector which points into the direction of the view % is % n = v * [0 1 0 ]' = = [-sinaz cosel, cosaz cosel, sinel]' % because the normal view point was the XZ plane with y as its normal % vector. % The 3D vector n is returned by this routine as well - it is % necessary for some kind of z buffering (determining what is % foreground and what is background). % % INPUT: % - #1 : azimuth ("yaw") % - #2 : elevation ("pitch") % OUTPUT: % - #3 : a macro which will be set to '1' if and only if % the viewport is the standard XY axis (i.e. azimuth=0, elevation=90). % - [xyz] vectors, % \pgfplots@[xyz]@veclength, % \pgfplots@[xyz]@inverseveclength % are set properly % \pgfplots@view@dir@threedim@[xyz] will contain the three components % of 'n' (without the suffix 'pt', but in units of 'pt'). \def\pgfplotssetaxesfromazel#1#2#3{% \begingroup \pgfmathparse{#1}% \let\pgfplots@az=\pgfmathresult \pgfmathparse{#2}% \edef\pgfplots@el{-\pgfmathresult}% \pgfmathsin@{\pgfplots@az}% \let\sinaz=\pgfmathresult \pgfmathcos@{\pgfplots@az}% \let\cosaz=\pgfmathresult \pgfmathsin@{\pgfplots@el}% \let\sinel=\pgfmathresult \pgfmathcos@{\pgfplots@el}% \let\cosel=\pgfmathresult % x: \pgfmathmultiply@{\sinaz}{\sinel}% \xdef\pgfplots@glob@TMPa{\noexpand\pgfqpoint{\cosaz pt}{\pgfmathresult pt}}% % y: \pgfmathmultiply@{-\sinel}{\cosaz}% \xdef\pgfplots@glob@TMPb{\noexpand\pgfqpoint{\sinaz pt}{\pgfmathresult pt}}% % z: \xdef\pgfplots@glob@TMPc{\noexpand\pgfqpoint{0pt}{\cosel pt}}% % \pgfkeysgetvalue{/pgfplots/x dir/value}\pgfplots@loc@dirvalue@x \pgfkeysgetvalue{/pgfplots/y dir/value}\pgfplots@loc@dirvalue@y \pgfkeysgetvalue{/pgfplots/z dir/value}\pgfplots@loc@dirvalue@z \if r\pgfplots@loc@dirvalue@x \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPa}% \xdef\pgfplots@glob@TMPa{\noexpand\pgfqpointscale{-1}{\the\t@pgfplots@toka}}% \fi \if r\pgfplots@loc@dirvalue@y \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPb}% \xdef\pgfplots@glob@TMPb{\noexpand\pgfqpointscale{-1}{\the\t@pgfplots@toka}}% \fi \if r\pgfplots@loc@dirvalue@z \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPc}% \xdef\pgfplots@glob@TMPc{\noexpand\pgfqpointscale{-1}{\the\t@pgfplots@toka}}% \fi % \def\pgfplots@extract@plot@box@ratio##1##2##3##4\pgfplots@EOI{% \pgfmathparse{##1}\let\pgfplots@plotboxratio@x=\pgfmathresult \pgfmathparse{##2}\let\pgfplots@plotboxratio@y=\pgfmathresult \pgfmathparse{##3}\let\pgfplots@plotboxratio@z=\pgfmathresult }% \pgfkeysgetvalue{/pgfplots/plot box ratio}\pgfplots@loc@TMPa \expandafter\pgfplots@extract@plot@box@ratio\pgfplots@loc@TMPa{1}{1}{1}\pgfplots@EOI \ifdim\pgfplots@plotboxratio@x pt=1pt \else \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPa}% \xdef\pgfplots@glob@TMPa{\noexpand\pgfqpointscale{\pgfplots@plotboxratio@x}{\the\t@pgfplots@toka}}% \fi \ifdim\pgfplots@plotboxratio@y pt=1pt \else \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPb}% \xdef\pgfplots@glob@TMPb{\noexpand\pgfqpointscale{\pgfplots@plotboxratio@y}{\the\t@pgfplots@toka}}% \fi \ifdim\pgfplots@plotboxratio@z pt=1pt \else \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPc}% \xdef\pgfplots@glob@TMPc{\noexpand\pgfqpointscale{\pgfplots@plotboxratio@z}{\the\t@pgfplots@toka}}% \fi % % n (3D!) \pgfmathmultiply@{-\sinaz}{\cosel}% \let\pgfmathresultNx=\pgfmathresult \pgfmathmultiply@{\cosaz}{\cosel}% \xdef\pgfplots@glob@TMPd{{\pgfmathresultNx}{\pgfmathresult}{\sinel}}% \endgroup %\message{Setting x,y and z from {#1}{#2} to x = \meaning\pgfplots@glob@TMPa, y = \meaning\pgfplots@glob@TMPb, z = \meaning\pgfplots@glob@TMPc...n = \pgfplots@glob@TMPd.}% \pgfsetxvec{\pgfplots@glob@TMPa}% \pgfsetyvec{\pgfplots@glob@TMPb}% \pgfsetzvec{\pgfplots@glob@TMPc}% \def\pgfplots@loc@TMPa##1##2##3{% \def\pgfplots@view@dir@threedim@x{##1}% \def\pgfplots@view@dir@threedim@y{##2}% \def\pgfplots@view@dir@threedim@z{##3}% }% \expandafter\pgfplots@loc@TMPa\pgfplots@glob@TMPd\relax \def#3{0}% \pgfplots@initsizes@get@width@withoutlabels \let\pgfplots@loc@TMPa=\pgfmathresult \pgfplots@initsizes@get@height@withoutlabels \edef\pgfplots@loc@TMPa{{\pgfplots@loc@TMPa}{\pgfmathresult}}% \expandafter\pgfplots@scaleaxes@to@BB\pgfplots@loc@TMPa %\message{After scaling: % x = (\the\pgf@xx,\the\pgf@xy), % y = (\the\pgf@yx,\the\pgf@yy), % z = (\the\pgf@zx,\the\pgf@zy).}% }% % Takes the current PGF x,y and z unit vectors and scales them such % that the bounding box of the final image has width #1 and height #2. % % The relative length of the input vectors is important for the 3D case: it % will be scaled as-is. % % PRECONDITION % - the x, y and z unit vectors have been set to the proper % DIRECTIONS. Their relative vector lengths are set-up properly % (i.e. y is twice as large as x and half as large as z or so). % - \pgfplots@[xyz]@veclength and % \pgfplots@[xyz]@inverseveclength % are set correctly. % - the \ifpgfplots@threedim boolean is set. % - the data limits have been initialised and transformed according % to the data transformation. % % POSTCONDITION % - the unit vectors have been re-scaled such that the final plot % has the desired dimensions. % - the @veclength and @inverseveclength have been re-scaled as % well. \def\pgfplots@scaleaxes@to@BB#1#2{% \begingroup \pgfinterruptboundingbox % STEP 1: compute the bounding box for UNITS. We just need the % relative sizes: \ifpgfplots@threedim \pgfpathmoveto{\pgfqpointxyz000}% \pgfpathmoveto{\pgfqpointxyz001}% \pgfpathmoveto{\pgfqpointxyz010}% \pgfpathmoveto{\pgfqpointxyz011}% \pgfpathmoveto{\pgfqpointxyz100}% \pgfpathmoveto{\pgfqpointxyz101}% \pgfpathmoveto{\pgfqpointxyz110}% \pgfpathmoveto{\pgfqpointxyz111}% \else \pgfpathmoveto{\pgfqpointxy00}% \pgfpathmoveto{\pgfqpointxy01}% \pgfpathmoveto{\pgfqpointxy10}% \pgfpathmoveto{\pgfqpointxy11}% \fi % TMPa = width \pgf@xa=\pgf@pathmaxx \advance\pgf@xa by-\pgf@pathminx % TMPb = height \pgf@xb=\pgf@pathmaxy \advance\pgf@xb by-\pgf@pathminy \pgf@ya=#1\relax \pgf@yb=#2\relax %\message{PGFPLOTS: the current unit vectors result in a UNIT BB of (\the\pgf@xa,\the\pgf@xb). Scaling it to (\the\pgf@ya,\the\pgf@yb)...}% % STEP 2: compute the scales for x and y such % that the UNIT-BB will have size #1,#2: \pgfplotsutil@edef@invoke\pgfmathdivide@{% {\pgf@sys@tonumber\pgf@ya}% {\pgf@sys@tonumber\pgf@xa}% }% % TMPa = scalex \global\let\pgfplots@glob@TMPa=\pgfmathresult \pgfplotsutil@edef@invoke\pgfmathdivide@{% {\pgf@sys@tonumber\pgf@yb}% {\pgf@sys@tonumber\pgf@xb}% }% % TMPb = scaley \global\let\pgfplots@glob@TMPb=\pgfmathresult \pgfusepath{discard}% \endpgfinterruptboundingbox \endgroup %\message{got scalex = \pgfplots@glob@TMPa\space and scaley = \pgfplots@glob@TMPb.}% \pgfmathsubtract@{\pgfplots@xmax}{\pgfplots@xmin}% % compute 1/(xmax - xmin) in float. % I observed that it is much more accurate (lead to scaling differences of up to 10pt!) \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloatreciprocal@\pgfmathresult \pgfmathfloattofixed\pgfmathresult %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% %\message{and 1/(xmax-xmin) = 1/(\pgfplots@xmax-\pgfplots@xmin) = \pgfmathresult.}% \pgf@xx=\pgfplots@glob@TMPa\pgf@xx \pgf@xy=\pgfplots@glob@TMPb\pgf@xy \pgf@xx=\pgfmathresult\pgf@xx \pgf@xy=\pgfmathresult\pgf@xy % \pgfmathsubtract@{\pgfplots@ymax}{\pgfplots@ymin}% \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloatreciprocal@\pgfmathresult \pgfmathfloattofixed\pgfmathresult %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% %\message{and 1/(ymay-ymin) = 1/(\pgfplots@ymax-\pgfplots@ymin) = \pgfmathresult.}% \pgf@yx=\pgfplots@glob@TMPa\pgf@yx \pgf@yy=\pgfplots@glob@TMPb\pgf@yy \pgf@yx=\pgfmathresult\pgf@yx \pgf@yy=\pgfmathresult\pgf@yy % \ifpgfplots@threedim \pgfmathsubtract@{\pgfplots@zmax}{\pgfplots@zmin}% \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloatreciprocal@\pgfmathresult \pgfmathfloattofixed\pgfmathresult %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% %\message{and 1/(zmaz-zmin) = 1/(\pgfplots@zmax-\pgfplots@zmin) = \pgfmathresult.}% \pgf@zx=\pgfplots@glob@TMPa\pgf@zx \pgf@zy=\pgfplots@glob@TMPb\pgf@zy \pgf@zx=\pgfmathresult\pgf@zx \pgf@zy=\pgfmathresult\pgf@zy \fi \pgfplots@computeunitvectorlengths }% \def\pgfplots@computeunitvectorlengths{% \pgfplotsutil@edef@invoke\pgfmathveclen@{% {\pgf@sys@tonumber\pgf@xx}% {\pgf@sys@tonumber\pgf@xy}% }% \let\pgfplots@x@veclength=\pgfmathresult \pgfplotsmath@ifzero{\pgfplots@x@veclength}{% \def\pgfmathresult{infty}% % this case will be caught in \pgfplots@initsizes }{% \expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% }% \let\pgfplots@x@inverseveclength=\pgfmathresult % \pgfplotsutil@edef@invoke\pgfmathveclen@{% {\pgf@sys@tonumber\pgf@yx}% {\pgf@sys@tonumber\pgf@yy}% }% \let\pgfplots@y@veclength=\pgfmathresult \pgfplotsmath@ifzero{\pgfplots@y@veclength}{% \def\pgfmathresult{infty}% % this case will be caught in \pgfplots@initsizes }{% \expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% }% \let\pgfplots@y@inverseveclength=\pgfmathresult % \ifpgfplots@threedim \pgfplotsutil@edef@invoke\pgfmathveclen@{% {\pgf@sys@tonumber\pgf@zx}% {\pgf@sys@tonumber\pgf@zy}% }% \let\pgfplots@z@veclength=\pgfmathresult \pgfplotsmath@ifzero{\pgfplots@z@veclength}{% \def\pgfmathresult{infty}% % this case will be caught in \pgfplots@initsizes }{% \expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% }% \let\pgfplots@z@inverseveclength=\pgfmathresult \fi }% % #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{} % 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: % - \csname pgfpmeta@#1@assign\endcsname{} % 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 % % - \csname pgfpmeta@#1@issymbolic\endcsname -> 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' % % - \csname pgfpmeta@#1@explicitinput\endcsname -> 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' % % - \csname pgfpmeta@#1@initfor\endcsname##1{....} % 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. % % #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}{% assign/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @assign\endcsname{#1}},% 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}},% issymbolic/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @issymbolic\endcsname{#1}},% 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 \ifpgfplots@xislinear \else \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% \let\pgfplots@current@point@meta=\pgfmathresult \fi}} \pgfplotsdeclarepointmetasource{y}{assign={% \let\pgfplots@current@point@meta=\pgfplots@current@point@y \ifpgfplots@yislinear \else \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% \let\pgfplots@current@point@meta=\pgfmathresult \fi}} \pgfplotsdeclarepointmetasource{z}{assign={% \let\pgfplots@current@point@meta=\pgfplots@current@point@z \ifpgfplots@zislinear \else \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% \let\pgfplots@current@point@meta=\pgfmathresult \fi}} \pgfplotsdeclarepointmetasource{explicit}{% assign={% \ifx\pgfplots@current@point@meta\pgfutil@empty \else \pgfmathfloatparsenumber{\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}% \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}{}% \pgfmathfloatparsenumber{\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... \newif\ifpgfplots@coord@stream@isfirst \def\pgfplots@coord@stream@start{% \global\pgfplots@coord@stream@isfirsttrue \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 \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@% \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 \ifpgfplots@coord@stream@isfirst \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 \global\pgfplots@coord@stream@isfirstfalse \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 allow a simple syntax % to provide matrix input - by means of scanlines. % % 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 following methods allow to update the scanline computation. % % Usage: % % \pgfplotsscanlinelengthinitzero % % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinecomplete % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinecomplete % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinelengthincrease % \pgfplotsscanlinecomplete % % \pgfplotsscanlinelengthcleanup % % 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{% \c@pgfplots@scanlineindex=0 \def\pgfplots@scanlinelength{-1}% } \def\pgfplotsscanlinelengthincrease{% \advance\c@pgfplots@scanlineindex by1 } \def\pgfplotsscanlinecomplete{% \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\pgfplotsscanlinelengthcleanup{% \ifnum\c@pgfplots@scanlineindex=0 % I assume the last scan line is already complete. \else \pgfplotsscanlinecomplete \fi \let\pgfplotsscanlinelength=\pgfplots@scanlinelength } \def\pgfplotsscanlinedisablechanges{% \let\pgfplotsscanlinecomplete=\relax \let\pgfplotsscanlinelengthincreas=\relax \let\pgfplotsscanlinelengthcleanup=\relax \let\pgfplotsscanlinelengthinitzero=\relax }% % 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. % \long\def\pgfplots@PREPARE@COORD@STREAM#1{% \ifpgfplots@curplot@threedim \global\pgfplots@threedimtrue \fi % \begingroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \let\E=\noexpand % % Setup Just-In-Time-Macro Compilation: % I compile a set of macros which is highly optimized for this % particular plot. % % 1.\pgfplots@update@limits@for@one@point % Updates the current x and y limits for point (#1,#2). % % To eliminate all those case distinctions, it is created with % 'edef' and a lot of '\noexpand' calls here: % % % The point coordinates may be given in floating point format, see % below. % % Please note that if user specified limits are given, automatic % limits are only applied to points which fall into the user specified % clipping region. % % PRECONDITIONS: % - the input coordinates have been parsed correctly (floating point % format for linear axis, log applied for logarithmic ones) % % Arguments: % \pgfplots@current@point@[xyz] \xdef\pgfplots@update@limits@for@one@point{% %\E\tracingmacros=2\E\tracingcommands=2 %\E\pgfplots@message{Updating limits for (\E\pgfplots@current@point@x,\E\pgfplots@current@point@y) ...}% % % VIM SEARCH PATTERN: % [^E]\zs\\\ze[^E] % -> this finds '\' which is neither '\E' nor is it prefixed % by 'E'. % % % \E\pgfplots@update@limits@for@one@point@ISCLIPPEDfalse % check whether we need to clip limits: \ifpgfplots@clip@limits \ifpgfplots@autocompute@xmin \else \ifpgfplots@xislinear \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@x}{\E\pgfplots@xmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@current@point@x}{\E\pgfplots@xmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@autocompute@xmax \else \ifpgfplots@xislinear \E\pgfmathfloatlessthan@{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@autocompute@ymin \else \ifpgfplots@yislinear \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@y}{\E\pgfplots@ymin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@current@point@y}{\E\pgfplots@ymin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@autocompute@ymax \else \ifpgfplots@yislinear \E\pgfmathfloatlessthan@{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@curplot@threedim \ifpgfplots@autocompute@zmin \else \ifpgfplots@zislinear \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@z}{\E\pgfplots@zmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@current@point@z}{\E\pgfplots@zmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@autocompute@zmax \else \ifpgfplots@zislinear \E\pgfmathfloatlessthan@{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \fi \fi % % % % Update limits: \E\ifpgfplots@update@limits@for@one@point@ISCLIPPED \E\else \ifpgfplots@autocompute@xmin \ifpgfplots@xislinear \E\pgfplotsmathfloatmin{\E\pgfplots@xmin}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@xmin}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@xmax \ifpgfplots@xislinear \E\pgfplotsmathfloatmax{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@ymin \ifpgfplots@yislinear \E\pgfplotsmathfloatmin{\E\pgfplots@ymin}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@ymin}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@ymax \ifpgfplots@yislinear \E\pgfplotsmathfloatmax{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult \fi \fi \ifpgfplots@curplot@threedim \ifpgfplots@autocompute@zmin \ifpgfplots@zislinear \E\pgfplotsmathfloatmin{\E\pgfplots@zmin}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@zmin}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@zmax \ifpgfplots@zislinear \E\pgfplotsmathfloatmax{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@zmax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@zmax=\E\pgfmathresult \fi \fi \fi \E\fi % % Compute data range: \ifpgfplots@autocompute@all@limits % the data range will be acquired simply from the axis % range, see below! \else % Attention: it is only done for linear axis! \ifpgfplots@xislinear \E\pgfplotsmathfloatmin{\E\pgfplots@data@xmin}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@data@xmin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@xmax}{\E\pgfplots@current@point@x}% \E\global\E\let\E\pgfplots@data@xmax=\E\pgfmathresult \fi \ifpgfplots@yislinear \E\pgfplotsmathfloatmin{\E\pgfplots@data@ymin}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@data@ymin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@ymax}{\E\pgfplots@current@point@y}% \E\global\E\let\E\pgfplots@data@ymax=\E\pgfmathresult \fi \ifpgfplots@curplot@threedim \ifpgfplots@zislinear \E\pgfplotsmathfloatmin{\E\pgfplots@data@zmin}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@data@zmin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@zmax}{\E\pgfplots@current@point@z}% \E\global\E\let\E\pgfplots@data@zmax=\E\pgfmathresult \fi \fi \fi %\E\pgfplots@message{Updated limits: (\E\pgfplots@xmin,\E\pgfplots@ymin) rectangle (\E\pgfplots@xmax,\E\pgfplots@ymax).}% %\E\tracingmacros=0\E\tracingcommands=0 }% %\message{Assembled update-limits \ifpgfplots@curplot@threedim 3D\else 2D\fi macro to {\meaning\pgfplots@update@limits@for@one@point}}% \ifpgfplots@bb@isactive \else % we are inside of % \pgfplotsinterruptdatabb % .. % \endpgfinterruptboundingbox % -> don't change data limits! \global\let\pgfplots@update@limits@for@one@point=\relax \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This here is the MAIN code of \pgfplots@process@one@point . % It is inserted below into the right, into one of two prepared % places. \def\pgfplots@loc@surveypoint{% \ifpgfplots@apply@datatrafo \ifpgfplots@datascaletrafo@initialised % apply data transformation directly. \ifpgfplots@apply@datatrafo@x \E\pgfplots@datascaletrafo@x\E\pgfplots@current@point@x \E\let\E\pgfplots@current@point@x=\E\pgfmathresult \fi \ifpgfplots@apply@datatrafo@y \E\pgfplots@datascaletrafo@y\E\pgfplots@current@point@y \E\let\E\pgfplots@current@point@y=\E\pgfmathresult \fi \ifpgfplots@curplot@threedim \ifpgfplots@apply@datatrafo@z \E\pgfplots@datascaletrafo@z\E\pgfplots@current@point@z \E\let\E\pgfplots@current@point@z=\E\pgfmathresult \fi \fi \fi \fi % All following routines (limit updating/stacking/error % bars) will use float numerics if necessary (controlled % by ifs). \ifpgfplots@stackedmode \E\pgfplots@stacked@preparepoint@inmacro% \ifpgfplots@datascaletrafo@initialised% is also true if there is no scale trafo. \E\pgfplots@stacked@finishpoint \else % the finishpoint routine will be invoked at % \endaxis. \fi \fi % % Prepare \pgfplots@current@point@meta (see the preparation % routine above): \E\pgfplots@set@perpointmeta % % update also axis / data limits: % Arguments: \pgfplots@current@point@[xy] \E\pgfplots@update@limits@for@one@point \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 % }% \def\pgfplots@loc@performserizalization{% % Store normalized point for list: % We need % xi,yi,zi,mi; % where zi and mi may be empty. mi is the per-point meta % information. It is used for per-coordinate marker % modifications (like colormaps for scatter plots). \E\edef\E\pgfplots@loc@TMPa{\E\pgfplots@current@point@x,\E\pgfplots@current@point@y,\E\pgfplots@current@point@z,\E\pgfplots@current@point@meta;}% \E\expandafter\E\pgfplotsapplistXXpushback\E\expandafter{\E\pgfplots@loc@TMPa}% }% % The following code assembles the command which is executed for % each coordinate. % % To eliminate all those case distinctions, it is created with % 'edef' and a lot of '\noexpand' calls here: % % Arguments: % \pgfplots@current@point@[xyz] % \pgfplots@current@point@[xyz]@error (if in argument list) \xdef\pgfplots@process@one@point{% % These things are necessary for error bars and are available % as public results in math parser invocations (for meta and % filters) \E\let\E\pgfplots@current@point@x@unfiltered=\E\pgfplots@current@point@x \E\let\E\pgfplots@current@point@y@unfiltered=\E\pgfplots@current@point@y \E\let\E\pgfplots@current@point@z@unfiltered=\E\pgfplots@current@point@z \E\def\E\pgfplots@unbounded@dir{}% % \E\pgfplots@prepare@xcoord{\E\pgfplots@current@point@x}% \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{x}% \E\let\E\pgfplots@current@point@x=\E\pgfmathresult % \E\pgfplots@prepare@ycoord{\E\pgfplots@current@point@y}% \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{y}% \E\let\E\pgfplots@current@point@y=\E\pgfmathresult % \ifpgfplots@curplot@threedim \E\pgfplots@prepare@zcoord{\E\pgfplots@current@point@z}% \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{z}% \E\let\E\pgfplots@current@point@z=\E\pgfmathresult \fi % \E\pgfplots@invoke@filter@xyz % \ifpgfplots@xislinear % NOTE: this handling of unbounded coords in the case of % LOG coords is performed directly by % \pgfplots@prepare@ycoord! \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty \E\else \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@x}% \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta \E\ifnum\E\c@pgf@counta>2 % this clears nan, inf and -inf points. \E\let\E\pgfplots@current@point@x=\E\pgfutil@empty \E\def\E\pgfplots@unbounded@dir{x}% \E\else \E\let\E\pgfplots@current@point@x=\E\pgfmathresult \E\fi \E\fi \fi % \ifpgfplots@yislinear \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty \E\else \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@y}% \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta \E\ifnum\E\c@pgf@counta>2 \E\let\E\pgfplots@current@point@y=\E\pgfutil@empty \E\def\E\pgfplots@unbounded@dir{y}% \E\else \E\let\E\pgfplots@current@point@y=\E\pgfmathresult \E\fi \E\fi \fi % \ifpgfplots@curplot@threedim % \ifpgfplots@zislinear \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty \E\else \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@z}% \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta \E\ifnum\E\c@pgf@counta>2 \E\let\E\pgfplots@current@point@z=\E\pgfutil@empty \E\def\E\pgfplots@unbounded@dir{z}% \E\else \E\let\E\pgfplots@current@point@z=\E\pgfmathresult \E\fi \E\fi \fi \fi % % check if coordinates are bounded: \E\pgfplots@loc@tmptrue \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty \E\pgfplots@loc@tmpfalse \E\else \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty \E\pgfplots@loc@tmpfalse \E\else \ifpgfplots@curplot@threedim \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty \E\pgfplots@loc@tmpfalse \E\fi \fi \E\fi \E\fi % \E\ifpgfplots@loc@tmp % coordinate is bounded AND non-empty, ok. % insert the main 2d/3d code here: \pgfplots@loc@surveypoint \pgfplots@loc@performserizalization \E\else % 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 \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 \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 \pgfplots@loc@performserizalization \E\fi \fi \E\fi % % increase \pgfplots@current@point@coordindex: \E\advance\E\c@pgfplots@coordindex by1 }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endgroup %\message{Prepared macro \string\pgfplots@update@limits@for@one@point: {\meaning\pgfplots@update@limits@for@one@point}}% %\message{Prepared macro \string\pgfplots@process@one@point: {\meaning\pgfplots@process@one@point}}% % \let\pgfplots@coord@stream@start@=\pgfplots@PREPARE@COORD@STREAM@start@ \let\pgfplots@coord@stream@coord@=\pgfplots@process@one@point \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 % % \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 \pgfmathfloatcreate{0}{0.0}{0}% \fi }% \csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname % % %%%%%%%%%%%%%% % % Define \pgfplots@set@perpointmeta properly: \def\pgfplots@set@perpointmeta{% \csname pgfpmeta@\pgfplotspointmetainputhandler @assign\endcsname }% \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 \pgfplotsmathfloatmin{\pgfplots@metamin}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamin=\pgfmathresult }% \else \pgfmathfloatparsenumber{\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 \pgfplotsmathfloatmax{\pgfplots@metamax}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamax=\pgfmathresult }% \else \pgfmathfloatparsenumber{\pgfplots@metamax}% \global\let\pgfplots@metamax=\pgfmathresult \fi % \t@pgfplots@toka=\expandafter{\pgfplots@set@perpointmeta}% \edef\pgfplots@set@perpointmeta{% \the\t@pgfplots@toka \noexpand\ifx\noexpand\pgfplots@current@point@meta\noexpand\pgfutil@empty \noexpand\else \the\t@pgfplots@tokb \noexpand\fi }% \else % there is no point meta: \global\let\pgfplots@metamin=\pgfutil@empty \global\let\pgfplots@metamax=\pgfutil@empty \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{% \ifx\pgfplots@metamin\pgfutil@empty \else \if\pgfplots@axiswide@metamin@autocompute1% \pgfplotsmathfloatmin{\pgfplots@axiswide@metamin}{\pgfplots@metamin}% \global\let\pgfplots@axiswide@metamin=\pgfmathresult \fi \if\pgfplots@axiswide@metamax@autocompute1% \pgfplotsmathfloatmax{\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 \ifpgfplots@coord@stream@isfirst \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 \pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfplots@current@point@coordindex}% \pgfplotspreparemeshkeydefaults% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting x% \pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting y% \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! % \ifpgfplots@datascaletrafo@initialised \pgfplots@addplot@get@named@startendpoints@command\pgfplots@loc@TMPa \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% \else \t@pgfplots@tokc={}% \fi % 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}}% % 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 \the\t@pgfplots@tokc% named start/end points (if already available) \noexpand\pgfplots@define@currentplotstyle@as{\the\t@pgfplots@toka}% remember 'current plot style' % 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}% }% {% 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 }% % 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{% \pgfplots@if{pgfplots@#1islinear}{% \pgfmathfloatlessthan@ {\csname pgfplots@currentplot@firstcoord@#1\endcsname} {\csname pgfplots@currentplot@lastcoord@#1\endcsname}% }{% \pgfplotsmathlessthan {\csname pgfplots@currentplot@firstcoord@#1\endcsname} {\csname pgfplots@currentplot@lastcoord@#1\endcsname}% }% \ifpgfmathfloatcomparison \pgfkeyssetvalue{/pgfplots/#1 coord sorting}{+}% \else \pgfkeyssetvalue{/pgfplots/#1 coord sorting}{-}% \fi }% % Assigns default values to 'rows' and 'cols' in case % their values are empty. % % PRECONDITION: % The values of % - '/pgfplots/mesh/rows' % - '/pgfplots/mesh/cols' % - '/pgfplots/mesh/num points' % - \pgfplotsscanlinelength % - '/pgfplots/mesh/ordering' % are assigned properly. % % POSTCONDITION: % 'rows' and 'cols' now incorporates \pgfplotsscanlinelength if % their values had been empty. However, there may still be empty % values. % % @see \pgfplotsautocompletemeshkeys \def\pgfplotspreparemeshkeydefaults{% \pgfplots@autocomplete@meshkeys0% }% % Completes and sanitizes 'mesh/rows' and 'mesh/cols' such that they % have useful integer values afterwards. % % This method works similarly to \pgfplotspreparemeshkeydefaults. % However, it really completes values and issues error messages if % that proves to be impossible. % % PRECONDITION: % The values of % - '/pgfplots/mesh/rows' % - '/pgfplots/mesh/cols' % - '/pgfplots/mesh/num points' % - '/pgfplots/mesh/ordering' % are assigned properly. % If % - \pgfplotsscanlinelength % exists and is positive, it may also be used. % % POSTCONDITION: % 'rows' and 'cols' have useful integer values. \def\pgfplotsautocompletemeshkeys{% \pgfplots@autocomplete@meshkeys1% }% \def\pgfplots@autocomplete@meshkeys#1{% \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsplothandlermesh@rows \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsplothandlermesh@cols \pgfkeysgetvalue{/pgfplots/mesh/num points}\pgfplotsplothandlermesh@numpoints \edef\pgfplotsplothandlermesh@numpoints{\pgfplotsplothandlermesh@numpoints}% \edef\pgfplotsplothandlermesh@cols{\pgfplotsplothandlermesh@cols}% \edef\pgfplotsplothandlermesh@rows{\pgfplotsplothandlermesh@rows}% \ifpgfplots@curplot@threedim \ifx\pgfplotsplothandlermesh@rows\pgfutil@empty \ifx\pgfplotsplothandlermesh@cols\pgfutil@empty \pgfutil@ifundefined{pgfplotsscanlinelength}{\def\pgfplotsscanlinelength{-1}}{}% \ifpgfplots@scanline@verbose \ifnum\pgfplotsscanlinelength>0 % we have scanlinelength set! Use it: \message{PGFPlots: Scanline length is \pgfplotsscanlinelength.}% \else \ifnum\pgfplotsscanlinelength=-2 \message{PGFPlots: Scanline length could not be determined since multiple, different scan line lengths have been found.}% \else \message{PGFPlots: No end-of-scanline marker found in input stream.}% \fi \fi \fi \ifnum\pgfplotsscanlinelength>0 % we have scanlinelength set! Use it: \if\pgfplots@plot@mesh@ordering0% % ordering = x varies= rowwise -> scanline is cols! \edef\pgfplotsplothandlermesh@cols{\pgfplotsscanlinelength}% \else % ordering = y varies = colwise: scanline is rows! \edef\pgfplotsplothandlermesh@rows{\pgfplotsscanlinelength}% \fi \else \if1#1% % try to get reasonable values: \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty \pgfplots@error{Sorry, 'plot mesh' needs either '[mesh/rows=]' or '[mesh/cols=]' set - or at least '[mesh/num points=]'. But it did not find any of them...}% \def\pgfplotsplothandlermesh@cols{5}% \def\pgfplotsplothandlermesh@rows{5}% \else % We don't have rows/cols. Well, try using % sqrt(num points) for both of them! \ifnum\pgfplotsplothandlermesh@numpoints<16380 \pgfmath@basic@sqrt@{\pgfplotsplothandlermesh@numpoints}% \else \pgfmathfloatparsenumber{\pgfplotsplothandlermesh@numpoints}% \pgfmathfloatsqrt@{\pgfmathresult}% \pgfmathfloattofixed{\pgfmathresult}% \fi \begingroup % Try whether this rows*rows yields numpoints: \afterassignment\pgfplots@gobble@until@relax \c@pgf@counta=\pgfmathresult\relax \c@pgf@countb=\c@pgf@counta \multiply\c@pgf@counta by\c@pgf@counta \def\pgfplotsretval{1}% \ifnum\c@pgf@counta=\pgfplotsplothandlermesh@numpoints\relax % ok, rows*rows = numpoints. \xdef\pgfplots@glob@TMPa{\the\c@pgf@countb}% \else % oh. Did not work. Check for rounding errors: \c@pgf@counta=\c@pgf@countb \advance\c@pgf@counta by1 \c@pgf@countb=\c@pgf@counta \multiply\c@pgf@counta by\c@pgf@counta \ifnum\c@pgf@counta=\pgfplotsplothandlermesh@numpoints % ok, (rows+1)*(rows+1) = numpoints. \xdef\pgfplots@glob@TMPa{\the\c@pgf@countb}% \else % no... did not work. num points doesn't % appear to be a squared number. \def\pgfplotsretval{0}% \xdef\pgfplots@glob@TMPa{5}% \fi \fi \if\pgfplotsretval1 \pgfplots@warning{% 'plot mesh' did not find '[mesh/rows=]' or '[mesh/cols=]'. Assuming [mesh/rows=\pgfplots@glob@TMPa,mesh/cols=\pgfplots@glob@TMPa] as sqrt(num points) = sqrt(\pgfplotsplothandlermesh@numpoints) [ = \pgfmathresult].}% \else \pgfplots@error{Sorry, 'plot mesh' needs either '[mesh/rows=]' or '[mesh/cols=]' set, but it did not find any of them. I also tried rows = sqrt(num points) = sqrt(\pgfplotsplothandlermesh@numpoints) = \pgfmathresult\space without success.}% \fi \endgroup \let\pgfplotsplothandlermesh@rows=\pgfplots@glob@TMPa \let\pgfplotsplothandlermesh@cols=\pgfplots@glob@TMPa \fi \else % #1=0 -> leave them empty. \fi \fi \fi \fi \if1#1% \ifx\pgfplotsplothandlermesh@rows\pgfutil@empty \ifx\pgfplotsplothandlermesh@cols\pgfutil@empty \else % Compute 'rows' out of 'num points' and 'cols': \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty \pgfplots@error{Sorry, matrix input needs a valid '[mesh/num points=]' variable if only one of '[mesh/rows=]' or '[mesh/cols=]' is given.}% \def\pgfplotsplothandlermesh@numpoints{100}% \fi \begingroup \c@pgf@counta=\pgfplotsplothandlermesh@numpoints\relax \divide\c@pgf@counta by\pgfplotsplothandlermesh@cols\relax \xdef\pgfplots@glob@TMPa{\the\c@pgf@counta}% \endgroup \let\pgfplotsplothandlermesh@rows=\pgfplots@glob@TMPa \fi \else \ifx\pgfplotsplothandlermesh@cols\pgfutil@empty % Compute 'cols' out of 'num points' and 'rows': \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty \pgfplots@error{Sorry, matrix input needs a valid '[mesh/num points=]' variable if only one of '[mesh/cols=]' or '[mesh/rows=]' is given.}% \def\pgfplotsplothandlermesh@numpoints{100}% \fi \begingroup \c@pgf@counta=\pgfplotsplothandlermesh@numpoints\relax \divide\c@pgf@counta by\pgfplotsplothandlermesh@rows\relax \xdef\pgfplots@glob@TMPa{\the\c@pgf@counta}% \endgroup \let\pgfplotsplothandlermesh@cols=\pgfplots@glob@TMPa \fi \fi \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@rows\relax \multiply\c@pgfplots@scanlineindex by \pgfplotsplothandlermesh@cols\relax \edef\pgfplotsplothandlermesh@numpoints{\the\c@pgfplots@scanlineindex}% \fi % \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@rows\relax \multiply\c@pgfplots@scanlineindex by\pgfplotsplothandlermesh@cols\relax \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@numpoints\relax \else \ifcase\pgfplots@mesh@checkmode\relax % mesh/check=false \def\pgfplots@loc@TMPa##1{}% \or % mesh/check=warning \def\pgfplots@loc@TMPa##1{\pgfplots@warning{##1}}% \or % mesh/check=error \def\pgfplots@loc@TMPa##1{\pgfplots@error{##1}}% \fi \pgfplots@loc@TMPa{the arguments of [mesh/rows=\pgfplotsplothandlermesh@rows,mesh/cols=\pgfplotsplothandlermesh@cols] assume \the\c@pgfplots@scanlineindex\space points, but I got actually N = \pgfplotsplothandlermesh@numpoints\space points! The data matrix appears to be incomplete or overcomplete!? [Use mesh/check=false to disable this message]}% \fi \fi \else % 2d visualization has no mesh: \edef\pgfplotsplothandlermesh@rows{\pgfplotsplothandlermesh@numpoints}% \def\pgfplotsplothandlermesh@cols{1}% \fi % \def\pgfplots@loc@TMPa{\pgfkeyssetvalue{/pgfplots/mesh/rows}}% \expandafter\pgfplots@loc@TMPa\expandafter{\pgfplotsplothandlermesh@rows}% \def\pgfplots@loc@TMPa{\pgfkeyssetvalue{/pgfplots/mesh/cols}}% \expandafter\pgfplots@loc@TMPa\expandafter{\pgfplotsplothandlermesh@cols}% }% % 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 % no, 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\pgfplots@update@limits@for@one@point \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. \pgfmathfloatparsenumber{\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% \pgfmathfloatadd@ {\csname pgfplots@current@point@#1\endcsname}% {\csname pgfplots@error@coord@#1\endcsname}% \else \pgfmathfloatsubtract@ {\csname pgfplots@current@point@#1\endcsname}% {\csname pgfplots@error@coord@#1\endcsname}% \fi \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% fixed relative error: \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: \pgfmathfloatcreate{1}{1.0}{0}% \let\pgfplots@loc@TMPa=\pgfmathresult % % Prepare '1 + err': \pgfmathfloatadd@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% \expandafter\let\csname pgfplots@error@coord@#1@+\endcsname=\pgfmathresult % % Prepare '1 - err': \pgfmathfloatsubtract@{\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{% \pgfmathfloatmultiply@ {\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 \pgfmathfloatparsenumber{\pgfplots@error@coord}% \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% \pgfmathfloatadd@ {\csname pgfplots@current@point@#1\endcsname}% {\pgfplots@error@coord}% \else \pgfmathfloatsubtract@ {\csname pgfplots@current@point@#1\endcsname}% {\pgfplots@error@coord}% \fi \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \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 \pgfmathparse{1##1\pgfplots@error@coord}% \let\pgfplots@error@coord=\pgfmathresult \pgfmathfloatmultiply@ {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \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 ) \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1fixed\endcsname}% \expandafter\let\csname pgfplots@error@coord@#1\endcsname=\pgfmathresult \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \pgfmathfloatparsenumber{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \pgfmathfloatadd@ {\pgfplots@loc@TMPa}% {\csname pgfplots@error@coord@#1\endcsname}% \else \pgfmathfloatsubtract@ {\pgfplots@loc@TMPa}% {\csname pgfplots@error@coord@#1\endcsname}% \fi \csname pgfplotsmathlog@#1@float\endcsname{\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) \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: \pgfmathfloatcreate{1}{1.0}{0}% \let\pgfplots@loc@TMPa=\pgfmathresult % % Prepare '1 + err': \pgfmathfloatadd@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% \ifx\pgfmathresult\pgfutil@empty % 1 + err <= 0 and log(1+err) is undefined: \pgfmathfloattofixed{\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 \fi \expandafter\let\csname pgfplots@error@coord@#1@+\endcsname=\pgfmathresult % % Prepare '1 - err': \pgfmathfloatsubtract@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% \ifx\pgfmathresult\pgfutil@empty % 1 + err <= 0 and log(1+err) is undefined: \pgfmathfloattofixed{\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 \fi \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 \pgfmathfloatparsenumber{\pgfplots@error@coord}% \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 \pgfmathfloatparsenumber{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \pgfmathfloatadd@ {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% \else \pgfmathfloatsubtract@ {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% \fi \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \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 \pgfmathfloatparsenumber{\pgfplots@error@coord}% \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 % \pgfmathfloatcreate{1}{1.0}{0}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% \pgfmathfloatadd@ {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% \else \pgfmathfloatsubtract@ {\pgfplots@loc@TMPa}% {\pgfplots@error@coord}% \fi \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \ifx\pgfplots@error@coord\pgfutil@empty % -> log( <= 0 ) -> do nothing. \else \pgfmath@basic@add@ {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \fi \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. \def\pgfplots@perpointmeta@preparetrafo{% \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 \pgfmathfloattofixed{##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{% \pgfmathfloatiffinite{##1}{% \pgfmathfloattofixed@{##1}% }{% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##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: \edef\pgfplotspointmetarange{\pgfplots@axiswide@metamin:\pgfplots@axiswide@metamax}% % Now, prepare the trafo as such. % It assigns \pgfmathresult (in fixed point). \def\pgfplots@perpointmeta@trafo##1{% \pgfmathfloatiffinite{##1}{% \pgfmathfloatsubtract@{##1}{\pgfplots@axiswide@metamin}% \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}% \expandafter\pgfmathfloattofixed@\expandafter{\pgfmathresult}% }{% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##1}% }% }% \pgfmathfloatsubtract@{\pgfplots@axiswide@metamax}{\pgfplots@axiswide@metamin}% \else % point meta rel=per plot: \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% % Now, prepare the trafo as such. % It assigns \pgfmathresult (in fixed point). \def\pgfplots@perpointmeta@trafo##1{% \pgfmathfloatiffinite{##1}{% \pgfmathfloatsubtract@{##1}{\pgfplots@metamin}% \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}% \expandafter\pgfmathfloattofixed@\expandafter{\pgfmathresult}% }{% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##1}% }% }% \pgfmathfloatsubtract@{\pgfplots@metamax}{\pgfplots@metamin}% \fi \let\pgfplots@loc@TMPa=\pgfmathresult \pgfmathfloatcreate{1}{1.0}{3}% \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfplots@loc@TMPa}% \let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult % % Expands to the transformation range as 'a:b': \def\pgfplots@perpointmeta@traforange{0:1000}% \fi \else % colormap access=direct \def\pgfplots@perpointmeta@trafo##1{ \pgfmathfloatiffinite{##1}{% \pgfmathfloattofixed@{##1}% }{% \def\pgfmathresult{0}% \pgfplots@perpointmeta@unboundedwarning{##1}% }% }% \def\pgfplots@perpointmeta@traforange{0:0}% \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% \fi \edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}% }% \def\pgfplots@perpointmeta@trafo@APPLY{% \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?}% \pgfmathfloatcreate{1}{1.0}{0}% \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,#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,#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 % % The same in normalized coordinates of the form % x1,y1,z1,m1;x2,y2,z2,m2;...;xN,yN,zN,mN; % if the plot is not threedim, zi is empty. % % The mi are Meta Values associated to point coordinates. They are % usually empty, but can be used to realize per-point marker % modifications (scatter plots, especially for colormaps). \long\def\pgfplots@coord@stream@foreach@NORMALIZED#1{% \pgfplots@coord@stream@start \pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1\pgfplots@EOI \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@NORMALIZED@ITERATE{% \pgfutil@ifnextchar\pgfplots@EOI{% \pgfplots@foreach@plot@coord@FINISH% }{% \pgfplots@foreach@plot@coord@NORMALIZED@NEXT% }% } \def\pgfplots@foreach@plot@coord@NORMALIZED@NEXT#1,#2,#3,#4;{% \def\pgfplots@current@point@x{#1}% \def\pgfplots@current@point@y{#2}% \def\pgfplots@current@point@z{#3}% \def\pgfplots@current@point@meta{#4}% \pgfplots@coord@stream@coord \pgfplots@foreach@plot@coord@NORMALIZED@ITERATE } \newif\ifpgfplots@curplot@threedim % 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 [