diff options
author | Karl Berry <karl@freefriends.org> | 2010-01-03 01:14:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-01-03 01:14:11 +0000 |
commit | 98837e31bcd7413ffa40c85ebbce9aa3ff3fdbed (patch) | |
tree | 1ed7f18cb8a81bb3f209bf158a38f5b624c2d607 /Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex | |
parent | 080069f58e2325db5ab0ac5f5ea584f3021bc383 (diff) |
pgfplots 1.3 (2jan10)
git-svn-id: svn://tug.org/texlive/trunk@16576 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex | 5337 |
1 files changed, 4419 insertions, 918 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex index 7d08f6667cb..e69591d0683 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex @@ -30,6 +30,215 @@ % - 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{\pgf@x=\the\pgf@xx\space\pgf@y=\the\pgf@xy\space}% + \edef\pgfplotspointunity{\pgf@x=\the\pgf@yx\space\pgf@y=\the\pgf@yy\space}% + \let\pgfplotsunitxlength=\pgfplots@x@veclength + \let\pgfplotsunitylength=\pgfplots@y@veclength + \let\pgfplotsunitxinvlength=\pgfplots@x@inverseveclength + \let\pgfplotsunityinvlength=\pgfplots@y@inverseveclength + \ifpgfplots@threedim + \edef\pgfplotspointunitz{\pgf@x=\the\pgf@zx\space\pgf@y=\the\pgf@zy\space}% + \let\pgfplotsunitzlength=\pgfplots@z@veclength + \let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength + \fi + % + % 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 (<x>,<y>) without units should use +% relative axis coordinate system. +% +% 2. Any other point coordinate should not be altered. +% +% Former versions installed a shift and changed e_x, e_y and +% e_z. However, that was misleading as it disabled point 2). +% So, my idea here is to replace \pgfpointxy and \pgfqpointxy +% such that they install the correct coordinate system before +% doing anything else. +\def\pgfplots@change@pgfpoints@to@descriptioncs{% + % + \let\pgfpointxy=\pgfplotspointdescriptionxy + \let\pgfqpointxy=\pgfplotsqpointdescriptionxy + % e_z is zero, so the xyz variants ignore z: + \def\pgfpointxyz##1##2##3{\pgfpointxy{##1}{##2}}% + \def\pgfqpointxyz##1##2##3{\pgfqpointxy{##1}{##2}}% + % +}% + +% \pgfplotspointticklabelcs{<axis>}{<coordinate>} +% or +% \pgfplotspointticklabelcs[<default shift>]{<axis>}{<coordinate>} +% +% Yields a point in the '<axis>ticklabel cs'. +% +% The 'xticklabel cs' is a coordinate system which expects either one +% or two coordinates. The first is the coordinate on the axis where +% x tick label will be placed (or would be placed). The first +% coordinate '0' means the lower aixs site and the value '1' the upper +% range. The second (optional) coordinate of 'xticklabel cs' is a +% shift in direction of the outer normal vector of the axis. The +% minimum shift is the largest' tick labels dimensions. If the second +% argument is omitted, the <default shift> will be used (0pt if this +% argument has been omitted as well). +% +% \pgfplotspointticklabelcs#1#2: +% #1 is the axis (either x,y or z) +% #2 is the coordinate (either <relative coord> or <relative coord>,<shift>) +% +% @see \pgfplotsvalueoflargesttickdimen +% +% This command actually boils down to a +% \pgfplotsqpointoutsideofticklabelaxisrel +% invocation which. Thus, you *can* get the *same* effect by using +% basic level commands -- and you are not restricted to the tick label +% axis. +% @see \pgfplotsqpointoutsideofaxisrel +\def\pgfplotspointticklabelcs{\pgfutil@ifnextchar[% + {\pgfplotspointticklabelcs@opt}% + {\pgfplotspointticklabelcs@opt[0pt]}% +}% +\def\pgfplotspointticklabelcs@opt[#1]#2#3{% + \pgfutil@in@{,}{#3}% + \ifpgfutil@in@ + \edef\pgfplots@loc@TMPa{#3}% + \else + \edef\pgfplots@loc@TMPa{#3,#1}% + \fi + \def\pgfplots@loc@TMPb##1,##2\relax{% + % invoke + % \pgfplotsqpointoutsideofticklabelaxisrel{#2}{##1}{ticklabel dimen + ##2}: + \begingroup + \pgfmathparse{##2}% + \pgf@xa=\pgfmathresult pt\relax + \advance\pgf@xa by\pgfplotsvalueoflargesttickdimen{#2} %<- keep this space! + \xdef\pgfplots@glob@TMPa{\pgf@sys@tonumber\pgf@xa}% + \endgroup + \def\pgfplots@loc@TMPa{\pgfplotsqpointoutsideofticklabelaxisrel{#2}{##1}}% + \expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@glob@TMPa}% + }% + \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\relax +}% + + +% 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. @@ -44,19 +253,26 @@ % \pgfplotspointonorientedsurfaceN. % % Example: -% \pgfplotspointonorientedsurfaceabsetupforxyz{0} +% \pgfplotspointonorientedsurfaceabsetupforxyz +% \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} +% % -> % \pgfplotspointonorientedsurfaceA = x % \pgfplotspointonorientedsurfaceB = y % \pgfplotspointonorientedsurfaceN = z -% \pgfplotspointonorientedsurfaceab{3}{4} = \pgfqpointxyz{3}{4}{0} +% \pgfplotspointonorientedsurfacespec = {ab0} +% \pgfplotspointonorientedsurfacespecunordered = {vv0} +% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{3}{4}{<lower z limit>} % -% \pgfplotspointonorientedsurfaceabsetupforyxz{0} +% \pgfplotspointonorientedsurfaceabsetupforyxz +% \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} % -> % \pgfplotspointonorientedsurfaceA = y % \pgfplotspointonorientedsurfaceB = x % \pgfplotspointonorientedsurfaceN = z -% \pgfplotspointonorientedsurfaceab{3}{4} = \pgfqpointxyz{4}{3}{0} +% \pgfplotspointonorientedsurfacespec = {ba0} +% \pgfplotspointonorientedsurfacespecunordered = {vv0} +% \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{4}{3}{<lower z limit>} % % @see \pgfplotspointonorientedsurfaceabsetupforxyz \def\pgfplotspointonorientedsurfaceab#1#2{% @@ -86,6 +302,12 @@ % 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{}. @@ -187,6 +409,18 @@ }% +% 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' @@ -194,9 +428,27 @@ % - b=2: 'v02' % % To check which of them should be drawn, this macro here converts 'a' -% to 'v' and 'b' to '#1'. +% 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{<lower z limit>}{0} +% -> the oriented surface is 'ab0' +% ... +% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{0}\pgfplotsretval +% -> \pgfplotsretval = 'v00' +% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{1}\pgfplotsretval +% -> \pgfplotsretval = 'v10' +% \pgfplotspointonorientedsurfaceabgetcontainedaxisline{2}\pgfplotsretval +% -> \pgfplotsretval = 'v20' \def\pgfplotspointonorientedsurfaceabgetcontainedaxisline#1#2{% \expandafter\pgfplotspointonorientedsurfaceabgetcontainedaxisline@\pgfplotspointonorientedsurfacespec\relax{#1}% \let#2=\pgfplots@loc@TMPa @@ -252,6 +504,106 @@ \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. @@ -264,24 +616,79 @@ % \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% + }% +}% + +% 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{% +\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 - \if1\csname pgfplots@surfenabled@\pgfplots@loc@TMPb\endcsname - #2% - \else - \if1\csname pgfplots@surfenabled@\pgfplots@loc@TMPc\endcsname - #2% - \else + \pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPb}{% + \pgfplotsifaxissurfaceisforeground{\pgfplots@loc@TMPc}{% #3% - \fi - \fi + }{% + #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{0}{% + % remark: this is ALWAYS true for 2D plots. + \pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn{1}{% + #1% + }{% + #2% + }% + }{% + #2% + }% +}% % Checks whether the line specified by a three-character-string '#1' % is inside of the currently set-up oriented surface. @@ -351,7 +758,7 @@ % 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 integer into the macro #3 as +% #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'. @@ -427,113 +834,643 @@ \fi }% -% Takes Pitch '#1' and Yaw '#2' (both in degrees) and computes +% 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{\pgf@x=\the\pgf@x\space\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% + \pgf@x=-\pgf@x% + \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}{% + \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{\pgf@x=\the\pgf@x\space\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@pos@transform\pgf@x\pgf@y + % + \edef\pgfplots@LEQ{% + % solve linear system + {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@x}% + {\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@y}% + }% + % + % apply inverse matrix to right-hand-side (and compute RHS): + \pgf@sh@reanchor{##1}{center}% + \edef\pgfplots@loc@center{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + \pgfpointdiff% {<start>}{<end>} -> computes <end> - <start> + {\pgfplots@loc@center}% + {\pgf@sh@reanchor{##1}{\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 + }% + % + % 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 + }% + }% + }% +}% + +% 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'. % -% 'Pitch' means a rotation around the viewport's x axis. 'Yaw' means +% '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(yaw) -sin(yaw) 0; ... -% sin(yaw) cos(yaw) 0; ... +% Az = [ cos(azimuth) -sin(azimuth) 0; ... +% sin(azimuth) cos(azimuth) 0; ... % 0 0 1 ]; +% +% % Ax = [ 1 0 0; ... -% 0 cos(pitch) -sin(pitch) ;... -% 0 sin(pitch) cos(pitch) ]; -% v= Ax * Az; +% 0 cos(elevation) -sin(elevation) ;... +% 0 sin(elevation) cos(elevation) ]; % +% v= Ax * Az; % = [ ... -% cosy -siny cosp siny sinp; ... -% siny cosy cosp -sinp cosy; ... -% 0 sinp cosp ]; +% cosaz -sinaz cosel sinaz sinel; ... +% sinaz cosaz cosel -sinel cosaz; ... +% 0 sinel cosel ]; % -% Then, we use the rotated XY plane as viewport, that means -% xvec = v * [1 0 0]' -% yvec = v * [0 1 0]' +% Then, we use the rotated XZ plane as viewport, that means +% xvec = v * [1 0 0]' = <first column of v> +% zvec = v * [0 0 1]' = <third column of v> % and we define the projection onto the twodimensional surface -% spanned by 'xvec' and 'yvec' as -% P( q ) = [ q^T xvec, q^T yvec ]' +% 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] ) -% and get thus in matlab notation: +% = [ 0, cosel]' % -% proj = 1:2; -% x = v(1,proj); -% y = v(2,proj); -% z = v(3,proj); +% Furthermore, the 3D view vector which points into the direction of the view +% is +% n = v * [0 1 0 ]' = <second column of v> = [-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 : pitch -% - #2 : yaw +% - #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. pitch=0,yaw=0). +% the viewport is the standard XY axis (i.e. azimuth=0, elevation=90). % - [xyz] vectors, % \pgfplots@[xyz]@veclength, % \pgfplots@[xyz]@inverseveclength % are set properly -\def\pgfplotssetaxesfrompitchyaw#1#2#3{% +% \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 \pgfmathsin@{#1}% - \let\sinp=\pgfmathresult - \pgfmathsin@{#2}% - \let\siny=\pgfmathresult + \let\sinaz=\pgfmathresult \pgfmathcos@{#1}% - \let\cosp=\pgfmathresult - \pgfmathcos@{#2}% - \let\cosy=\pgfmathresult + \let\cosaz=\pgfmathresult + \pgfmathsin@{-#2}% + \let\sinel=\pgfmathresult + \pgfmathcos@{-#2}% + \let\cosel=\pgfmathresult % x: - \pgfmathmultiply@{\siny}{-1}% - \expandafter\pgfmathmultiply@\expandafter{\pgfmathresult}{\cosp}% - \xdef\pgfplots@glob@TMPa{\noexpand\pgfqpoint{\cosy pt}{\pgfmathresult pt}}% + \pgfmathmultiply@{\sinaz}{\sinel}% + \xdef\pgfplots@glob@TMPa{\noexpand\pgfqpoint{\cosaz pt}{\pgfmathresult pt}}% % y: - \pgfmathmultiply@{\cosy}{\cosp}% - \xdef\pgfplots@glob@TMPb{\noexpand\pgfqpoint{\siny pt}{\pgfmathresult pt}}% + \pgfmathmultiply@{-\sinel}{\cosaz}% + \xdef\pgfplots@glob@TMPb{\noexpand\pgfqpoint{\sinaz pt}{\pgfmathresult pt}}% % z: - \xdef\pgfplots@glob@TMPc{\noexpand\pgfqpoint{0pt}{\sinp pt}}% + \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...}% +%\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}% - \def\pgfplots@x@veclength{1.0}% - \def\pgfplots@y@veclength{1.0}% - \def\pgfplots@z@veclength{1.0}% - \def\pgfplots@x@inverseveclength{1.0}% - \def\pgfplots@y@inverseveclength{1.0}% - \def\pgfplots@z@inverseveclength{1.0}% -\iftrue - \pgfplots@scaleaxes@to@BB{\pgfplots@width}{\pgfplots@height}% FIXME : width and height is wrong: labels missing -\else - % FIXME : - \def\pgfplots@x@veclength{200}% - \pgfmathreciprocal@{\pgfplots@x@veclength}% - \let\pgfplots@x@inverseveclength=\pgfmathresult - \def\pgfplots@y@veclength{200}% - \pgfmathreciprocal@{\pgfplots@y@veclength}% - \let\pgfplots@y@inverseveclength=\pgfmathresult - \def\pgfplots@z@veclength{200}% - \pgfmathreciprocal@{\pgfplots@z@veclength}% - \let\pgfplots@z@inverseveclength=\pgfmathresult - \pgfsetxvec{\pgfpointscale{\pgfplots@x@veclength}{\pgfplots@glob@TMPa}}% - \pgfsetyvec{\pgfpointscale{\pgfplots@y@veclength}{\pgfplots@glob@TMPb}}% - \pgfsetzvec{\pgfpointscale{\pgfplots@z@veclength}{\pgfplots@glob@TMPc}}% -\fi -\message{After scaling: - x = (\the\pgf@xx,\the\pgf@xy), - y = (\the\pgf@yx,\the\pgf@yy), - z = (\the\pgf@zx,\the\pgf@zy).}% + \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 length of the input vectors is important for the 3D case: it +% The relative length of the input vectors is important for the 3D case: it % will be scaled as-is. % % PRECONDITION @@ -555,7 +1492,8 @@ \def\pgfplots@scaleaxes@to@BB#1#2{% \begingroup \pgfinterruptboundingbox - % STEP 1: compute the bounding box for UNITS: + % STEP 1: compute the bounding box for UNITS. We just need the + % relative sizes: \ifpgfplots@threedim \pgfpathmoveto{\pgfqpointxyz000}% \pgfpathmoveto{\pgfqpointxyz001}% @@ -579,7 +1517,7 @@ \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)...}% +%\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@{% @@ -597,18 +1535,18 @@ \pgfusepath{discard}% \endpgfinterruptboundingbox \endgroup -\message{got scalex = \pgfplots@glob@TMPa\space and scaley = \pgfplots@glob@TMPb.}% +%\message{got scalex = \pgfplots@glob@TMPa\space and scaley = \pgfplots@glob@TMPb.}% \pgfmathsubtract@{\pgfplots@xmax}{\pgfplots@xmin}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% -\message{and 1/(xmax-xmin) = 1/(\pgfplots@xmax-\pgfplots@xmin) = \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}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% -\message{and 1/(ymay-ymin) = 1/(\pgfplots@ymax-\pgfplots@ymin) = \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 @@ -616,8 +1554,8 @@ % \ifpgfplots@threedim \pgfmathsubtract@{\pgfplots@zmax}{\pgfplots@zmin}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% -\message{and 1/(zmaz-zmin) = 1/(\pgfplots@zmax-\pgfplots@zmin) = \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 @@ -632,7 +1570,12 @@ {\pgf@sys@tonumber\pgf@xy}% }% \let\pgfplots@x@veclength=\pgfmathresult - \expandafter\pgfmathreciprocal@\expandafter{\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@{% @@ -640,7 +1583,12 @@ {\pgf@sys@tonumber\pgf@yy}% }% \let\pgfplots@y@veclength=\pgfmathresult - \expandafter\pgfmathreciprocal@\expandafter{\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 @@ -649,12 +1597,162 @@ {\pgf@sys@tonumber\pgf@zy}% }% \let\pgfplots@z@veclength=\pgfmathresult - \expandafter\pgfmathreciprocal@\expandafter{\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 +% This method should prepare everything which is needed to invoke +% the postprocessors, i.e. it prepares the input for point meta +% transformations to [0,1000] or the scatter plot things. In other +% words: 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 #3=symbolic) +% 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, i.e. the final map +% to [0,1000] will be initialised and meta limits will be updated. +% 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}% + \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}},% + 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}% + \let\pgfpmeta@expr@origchoice\pgfplotspointmetainputhandler + }, +}% +\pgfkeyssetvalue{/pgfplots/point meta/expr}{}% + % Internal stream methods. % % Please overwrite @@ -699,21 +1797,104 @@ % \pgfplots@current@point@meta \def\pgfplots@coord@stream@coord{% \pgfplots@coord@stream@coord@% - % FIXME : needs to be updated for 3D - % FIXME : reduce \if's \ifx\pgfplots@current@point@x\pgfutil@empty + % only one \if is enough as ONE empty coordinate results all + % others to be reset as well. \else - \ifx\pgfplots@current@point@y\pgfutil@empty + \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 - \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\pgfplots@coord@stream@isfirstfalse + \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 - \global\let\pgfplots@currentplot@lastcoord@x=\pgfplots@current@point@x - \global\let\pgfplots@currentplot@lastcoord@y=\pgfplots@current@point@y \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 @@ -723,18 +1904,34 @@ % 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: all options of \addplot[...] (the plot style) -% #2: any trailing path commands after the 'plot' command as such, +% #1: any trailing path commands after the 'plot' command as such, % for example \addplot plot coordinates {...} -- (0,0); -% would yield #2 =' -- (0,0)' +% would yield #1 =' -- (0,0)' % % PRECONDITION: % - needs to be called inside of \addplot. +% - \pgfplots@addplot@survey@@optionlist contains the <options> +% provided to \addplot (all of them, including automatically +% determined ones) % % REMARK: % The following code is permissable: -% \pgfplots@PREPARE@COORD@STREAM{..}{...} +% \pgfplots@PREPARE@COORD@STREAM{...} % \pgfplots@coord@stream@start % ... % \pgfplots@coord@stream@coord @@ -751,123 +1948,18 @@ % - 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#2{% +\long\def\pgfplots@PREPARE@COORD@STREAM#1{% \ifpgfplots@curplot@threedim \global\pgfplots@threedimtrue \fi - \def\pgfplots@coord@stream@start@{% - \pgfplotsapplistXXnewempty - \ifpgfplots@errorbars@enabled - \pgfplots@streamerrorbar@recordto{\pgfplots@recordederrorbar}% - \pgfplots@streamerrorbarstart - \else - \let\pgfplots@recordederrorbar=\pgfutil@empty - \fi - \ifpgfplots@stackedmode - \pgfplots@stacked@beginplot - \fi - % - %\let\pgfplots@coord@stream@recorded=\pgfutil@empty - % - \pgfplots@perpointmeta@usesfloattrue - % %%%%%%%%%%%%%% - % - % Define \pgfplots@set@perpointmeta properly: - \ifcase\pgfplots@perpointmeta@choice - % disabled. - \def\pgfplots@set@perpointmeta{% - \let\pgfplots@current@point@meta=\pgfutil@empty - }% - \or - % point meta/x - \def\pgfplots@set@perpointmeta{% - \let\pgfplots@current@point@meta=\pgfplots@current@point@x - }% - \ifpgfplots@xislinear - \else - \pgfplots@perpointmeta@usesfloatfalse - \fi - \or - % point meta/y - \def\pgfplots@set@perpointmeta{% - \let\pgfplots@current@point@meta=\pgfplots@current@point@y - }% - \ifpgfplots@yislinear - \else - \pgfplots@perpointmeta@usesfloatfalse - \fi - \or - % point meta/z - \def\pgfplots@set@perpointmeta{% - \let\pgfplots@current@point@meta=\pgfplots@current@point@z - }% - \ifpgfplots@zislinear - \else - \pgfplots@perpointmeta@usesfloatfalse - \fi - \or - % point meta/explicit : parse the information found - % somewhere: - \def\pgfplots@set@perpointmeta{% - \ifx\pgfplots@current@point@meta\pgfutil@empty - \else - \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% - \fi - \let\pgfplots@current@point@meta=\pgfmathresult - }% - \or - % point meta/explicit symbolic : simply collect the - % information, no math. - \def\pgfplots@set@perpointmeta{}% - \fi - \ifnum\pgfplots@perpointmeta@choice=0 - \global\let\pgfplots@metamin=\pgfutil@empty - \global\let\pgfplots@metamax=\pgfutil@empty - \else - \ifnum\pgfplots@perpointmeta@choice=5 - \global\let\pgfplots@metamin=\pgfutil@empty - \global\let\pgfplots@metamax=\pgfutil@empty - \else - % We need to work with per point meta data. - % So, also compute the data range on a per-stream basis! - % These limits are important later. - \ifpgfplots@perpointmeta@usesfloat - \pgfmathfloatcreate{1}{1.0}{2147483645}% - \let\pgfplots@invalidrange@metamin=\pgfmathresult - \pgfmathfloatcreate{2}{1.0}{2147483645}% - \let\pgfplots@invalidrange@metamax=\pgfmathresult - \global\let\pgfplots@metamin=\pgfplots@invalidrange@metamin - \global\let\pgfplots@metamax=\pgfplots@invalidrange@metamax - \expandafter\def\expandafter\pgfplots@set@perpointmeta\expandafter{% - \pgfplots@set@perpointmeta - \ifx\pgfplots@current@point@meta\pgfutil@empty - \else - \pgfplotsmathfloatmin{\pgfplots@metamin}{\pgfplots@current@point@meta}% - \global\let\pgfplots@metamin=\pgfmathresult - \pgfplotsmathfloatmax{\pgfplots@metamax}{\pgfplots@current@point@meta}% - \global\let\pgfplots@metamax=\pgfmathresult - \fi - }% - \else - \def\pgfplots@invalidrange@metamin{16300}% - \def\pgfplots@invalidrange@metamax{-16300}% - \global\let\pgfplots@metamin=\pgfplots@invalidrange@metamin - \global\let\pgfplots@metamax=\pgfplots@invalidrange@metamax - \expandafter\def\expandafter\pgfplots@set@perpointmeta\expandafter{% - \pgfplots@set@perpointmeta - \ifx\pgfplots@current@point@meta\pgfutil@empty - \else - \pgfplotsmathmin{\pgfplots@metamin}{\pgfplots@current@point@meta}% - \global\let\pgfplots@metamin=\pgfmathresult - \pgfplotsmathmax{\pgfplots@metamax}{\pgfplots@current@point@meta}% - \global\let\pgfplots@metamax=\pgfmathresult - \fi - }% - \fi - \fi - \fi - }% + % \begingroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \let\E=\noexpand @@ -967,7 +2059,6 @@ \fi \fi \ifpgfplots@curplot@threedim - \else \ifpgfplots@autocompute@zmin \else \ifpgfplots@zislinear @@ -1092,7 +2183,7 @@ %\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 macro to {\meaning\pgfplots@update@limits@for@one@point}}% +%\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 @@ -1107,7 +2198,7 @@ % 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@TMPa{% + \def\pgfplots@loc@surveypoint{% \ifpgfplots@apply@datatrafo \ifpgfplots@datascaletrafo@initialised % apply data transformation directly. @@ -1153,18 +2244,11 @@ % \pgfplots@current@point@[xy] % \pgfplots@current@point@[xy]@error % \pgfplots@current@point@[xy]@unfiltered - \E\pgfplots@process@errorbar@for% + \E\pgfplots@PREPARE@errorbar@process@x% + \E\pgfplots@PREPARE@errorbar@process@y% + \E\pgfplots@PREPARE@errorbar@process@z% \fi % - % 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}% - % \ifpgfplots@collect@firstplot@astick \ifnum\pgfplots@numplots=0 \E\ifx\E\pgfplots@firstplot@coords@x\E\pgfutil@empty @@ -1190,6 +2274,17 @@ \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. @@ -1201,12 +2296,13 @@ % \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: + % 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 - \ifpgfplots@curplot@threedim \E\let\E\pgfplots@current@point@z@unfiltered=\E\pgfplots@current@point@z - \fi + \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}% @@ -1216,13 +2312,25 @@ \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 + \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 @@ -1236,6 +2344,7 @@ \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 @@ -1243,10 +2352,6 @@ \fi % \ifpgfplots@curplot@threedim - \E\let\E\pgfplots@current@point@z@unfiltered=\E\pgfplots@current@point@z - \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 % \ifpgfplots@zislinear \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty @@ -1255,6 +2360,7 @@ \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 @@ -1262,157 +2368,879 @@ \fi \fi % + % check if coordinates are bounded: + \E\pgfplots@loc@tmptrue \E\ifx\E\pgfplots@current@point@x\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 the x-coordinate filter.}% - \fi + \E\pgfplots@loc@tmpfalse \E\else \E\ifx\E\pgfplots@current@point@y\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 the y-coordinate filter.}% - \fi + \E\pgfplots@loc@tmpfalse \E\else \ifpgfplots@curplot@threedim \E\ifx\E\pgfplots@current@point@z\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,\E\pgfplots@current@point@z@unfiltered) has been dropped because of the z-coordinate filter.}% - \fi - \E\else - % insert the main 3d code here: - \pgfplots@loc@TMPa + \E\pgfplots@loc@tmpfalse \E\fi - \else - % insert the main 2d code here: - \pgfplots@loc@TMPa \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\begingroup - \E\c@pgf@counta=\E\pgfplots@current@point@coordindex - \E\advance\E\c@pgf@counta by1\E\relax - \E\xdef\E\pgfplots@glob@TMPc{\E\the\E\c@pgf@counta}% - \E\endgroup - \E\let\E\pgfplots@current@point@coordindex=\E\pgfplots@glob@TMPc + \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 % - \def\pgfplots@coord@stream@end@{% - \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 + % + \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 - \ifpgfplots@errorbars@enabled - \pgfplots@streamerrorbarend + \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 - \ifpgfplots@stackedmode - \pgfplots@stacked@endplot + }% + % + % %%%%%%%%%%%%%% + % + % 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 - \ifpgfplots@coord@stream@isfirst - \pgfplots@warning{the current plot has no coordinates (left?)}% - \fi -% \else - % Idea: use - % \scope[plot specification] - % <any paths for error bars> - % \endscope - % \draw plot coordinates {...}; - % to share plot specifications between error bars and plot - % coordinates. Unfortunately, it is NOT sufficient to use - % \tikzset{#1} - \ifpgfplots@curplot@isirrelevant - \edef\pgfplots@addplot@preoptionsTMP{/pgfplots/every axis plot,/pgfplots/every forget plot/.try}% + \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 + \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] + % <any paths for error bars> + % \endscope + % \draw plot coordinates {...}; + % to share plot specifications between error bars and plot + % coordinates. Unfortunately, it is NOT sufficient to use + % \tikzset + \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}% + \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\draw% + }% + }% + \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 as 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=<N>]' or '[mesh/cols=<N>]' set - or at least '[mesh/num points=<N>]'. 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=<N>]' or '[mesh/cols=<N>]'. + 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=<N>]' or '[mesh/cols=<N>]' 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=<N>]' variable if only one of '[mesh/rows=<N>]' or '[mesh/cols=<N>]' 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 - \edef\pgfplots@addplot@preoptionsTMP{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% - \expandafter\pgfplots@rememberplotspec\expandafter{\pgfplots@addplot@preoptionsTMP,#1,/pgfplots/every axis plot post}% - \fi - % warning: rememberplotspec calls list macros which - % overwrite \t@pgfplots@toka - \t@pgfplots@toka=\expandafter{\pgfplots@addplot@preoptionsTMP,#1,/pgfplots/every axis plot post}% - \xdef\pgfplots@last@plot@style{\the\t@pgfplots@toka}% store it for \label commands. - % ATTENTION: do NOT call list macros from here on! + \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=<N>]' variable if only one of '[mesh/cols=<N>]' or '[mesh/rows=<N>]' 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 % - \ifpgfplots@datascaletrafo@initialised - \pgfplots@addplot@get@named@startendpoints@command\pgfplots@loc@TMPa - \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% + \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@rows\relax + \multiply\c@pgfplots@scanlineindex by\pgfplotsplothandlermesh@cols\relax + \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@numpoints\relax \else - \t@pgfplots@tokc={}% - \fi - % assembe 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}% - \noexpand\pgfplots@initzerolevelhandler - \the\t@pgfplots@tokc% named start/end points (if already available) - \noexpand\pgfkeysdef{/tikz/current plot style}{\noexpand\pgfkeysalso{\the\t@pgfplots@toka}}% - % per-point meta data ranges: - \noexpand\xdef\noexpand\pgfplots@metamin{\pgfplots@metamin}% - \noexpand\xdef\noexpand\pgfplots@metamax{\pgfplots@metamax}% - \ifpgfplots@perpointmeta@usesfloat - \noexpand\pgfplots@perpointmeta@usesfloattrue + \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 - \noexpand\pgfplots@perpointmeta@usesfloatfalse + \pgfmathfloatsubtract@ + {\csname pgfplots@current@point@#1\endcsname}% + {\csname pgfplots@error@coord@#1\endcsname}% \fi - \noexpand\def\noexpand\pgfplots@perpointmeta@choice{\pgfplots@perpointmeta@choice}% + \let\pgfplots@error@coord=\pgfmathresult + \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% - {% draw command: - \noexpand\draw% + \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 }% - }% - \pgfplotsapplistXXlet\pgfplots@coord@stream@recorded - \pgfplotsapplistXXclear - \t@pgfplots@tokc=\expandafter{\pgfplots@coord@stream@recorded}% - \t@pgfplots@tokb={#2;}% - \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 + \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) ) % - % 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}% + % 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 }% - \xdef\pgfplots@glob@TMPa{ - \the\t@pgfplots@toka - { - % Post commands: append error bar commands. - \pgfplots@loc@TMPb - }% + \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 }% - \pgfplots@glob@TMPa + % + \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 - %^^^^^^^^^^^^ ... END of \pgfplots@addplot@enqueue@coords HERE -% \fi - \pgfplots@end@plot - }% -}% + }% + \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, % @@ -1422,63 +3250,126 @@ % 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 \pgfplotscolormapfind. Thus, the 10^k is chosen to be +% 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 now data range (for example because meta information is +% 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{% - \ifx\pgfplots@metamax\pgfutil@empty - \def\pgfplots@perpointmeta@trafo##1{\def\pgfmathresult{##1}}% - \def\pgfplots@perpointmeta@traforange{0:0}% - \else - % The transformation is - % - % phi(m) = ( m- meta_min) * 1000/ (meta_max-meta_min). - % - % -> precompute the scaling factor! - \ifpgfplots@perpointmeta@usesfloat - \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.}% + \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 - \pgfmathfloatsubtract@{\pgfplots@metamax}{\pgfplots@metamin}% - \let\pgfplots@loc@TMPa=\pgfmathresult - \pgfmathfloatcreate{1}{1.0}{3}% - \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfplots@loc@TMPa}% - \let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult - % - % Now, setup the trafo as such. - % It assigns \pgfmathresult (in fixed point). + }% + \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{% - \pgfmathfloatsubtract@{##1}{\pgfplots@metamin}% - \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}% - \expandafter\pgfmathfloattofixed@\expandafter{\pgfmathresult}% + \pgfmathfloatiffinite{##1}{% + \pgfmathfloattofixed@{##1}% + }{% + \def\pgfmathresult{0}% + \pgfplots@perpointmeta@unboundedwarning{##1}% + }% }% - % Expands to the transformation range as 'a:b': \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 - \pgfmathsubtract@{\pgfplots@metamax}{\pgfplots@metamin}% + \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 - \expandafter\pgfmathdivide@\expandafter{\pgfplotscolormaprange}{\pgfplots@loc@TMPa}% + \pgfmathfloatcreate{1}{1.0}{3}% + \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfplots@loc@TMPa}% \let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult % - % Now, setup the trafo as such. - % It assigns \pgfmathresult (in fixed point). - \def\pgfplots@perpointmeta@trafo##1{% - \pgfmathsubtract@{##1}{\pgfplots@metamin}% - \expandafter\pgfmathmultiply@\expandafter{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}% - }% % 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 }% @@ -1504,7 +3395,9 @@ % 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 }% @@ -1518,9 +3411,11 @@ \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 @@ -1533,8 +3428,13 @@ }% \long\def\pgfplots@foreach@plot@coord@ITERATE@gobbleone#1{\pgfplots@foreach@plot@coord@ITERATE}% \def\pgfplots@foreach@plot@coord@NEXT(#1,#2){% - \def\pgfplots@current@point@x{#1}% - \def\pgfplots@current@point@y{#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% }{% @@ -1559,8 +3459,13 @@ \pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@% } \def\pgfplots@foreach@plot@coord@NEXT@WITH@ERRORRANGE@#1,#2){% - \def\pgfplots@current@point@x@error{#1}% - \def\pgfplots@current@point@y@error{#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 }{% @@ -1576,7 +3481,9 @@ % 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{% @@ -1584,9 +3491,11 @@ \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 @@ -1596,9 +3505,15 @@ } \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){% - \def\pgfplots@current@point@x{#1}% - \def\pgfplots@current@point@y{#2}% - \def\pgfplots@current@point@z{#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% }{% @@ -1624,9 +3539,15 @@ \pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@% } \def\pgfplots@foreach@plot@coord@threedim@NEXT@WITH@ERRORRANGE@#1,#2,#3){% - \def\pgfplots@current@point@x@error{#1}% - \def\pgfplots@current@point@y@error{#2}% - \def\pgfplots@current@point@z@error{#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 }{% @@ -1746,7 +3667,7 @@ } \long\def\pgfplots@addplotimplAPPEND+[{% - \expandafter\pgfplots@addplotimpl\expandafter[\nextplotspec, + \expandafter\pgfplots@addplotimpl\expandafter[\nextplotspec,% } \long\def\pgfplots@addplotimpl[#1]{% @@ -1768,6 +3689,10 @@ \def\pgfplots@addplotimpl@plot@withoptions#1[#2]{ \begingroup% <-- This groups ends in \pgfplots@end@plot % + % make sure it is reset, just in case it is not supported by the + % input method. + \pgfplotsscanlinelengthinitzero + % \pgfutil@ifnextchar c{% \pgfplots@addplotimpl@coordinates{#1}{#2}plot }{% @@ -1775,8 +3700,8 @@ \pgfplots@addplotimpl@f{#1}{#2}% }{% \pgfutil@ifnextchar t{% - \pgfplots@start@plot@with@behavioroptions{#2}% - \pgfplots@addplotimpl@table{#1}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@addplotimpl@table{#1,#2}% }{% \pgfutil@ifnextchar ({% \pgfplots@addplotimpl@expression{#1}{#2}% @@ -1790,8 +3715,13 @@ \pgfutil@ifnextchar g{% \pgfplots@addplotimpl@g{#1}{#2}% }{% - \pgfplots@error{Sorry, the supplied plot command is unknown or unsupported by pgfplots! Ignoring it.}% - \pgfplots@gobble@until@semicolon + \pgfutil@ifnextchar s{% + \pgfplots@addplotimpl@shell{#1}{#2}% + }{% + + \pgfplots@error{Sorry, the supplied plot command is unknown or unsupported by pgfplots! Ignoring it.}% + \pgfplots@gobble@until@semicolon + }% }% }% }% @@ -1810,6 +3740,85 @@ \def\pgfplots@gobble@until@semicolon#1;{} +% PRECONDITION: +% the key-value sets have all been set in the current scope. +% +% POSTCONDITION: +% 1. the following macros are initialised and sanitized: +% \pgfplots@plot@domain +% \pgfplots@plot@ydomain (will be set to \pgfplots@plot@domain if empty) +% \pgfplots@plot@samples@at +% \pgfplots@plot@samples@y (will be set to the x variant if empty) +% \tikz@plot@var +% \pgfplots@plot@var@nonmacro +% \pgfplots@plot@var@y +% \pgfplots@plot@var@y@nonmacro +% 2. the following key-value things are set: +% /pgfplots/mesh/rows +% /pgfplots/mesh/cols +% /pgfplots/samples y (will contain a value ) +% 3. the macro +% \b@pgfplots@should@sample@LINE +% will be +% \def\b@pgfplots@should@sample@LINE{1} +% if the expression plotter should sample a line +% and +% \def\b@pgfplots@should@sample@LINE{0} +% if it should samples a mesh. +\def\pgfplots@plot@expression@preparekeys{% + \pgfkeysgetvalue{/pgfplots/domain}\pgfplots@plot@domain + \pgfkeysgetvalue{/pgfplots/samples y}\pgfplots@plot@samples@y + \pgfkeysgetvalue{/pgfplots/samples at}\pgfplots@plot@samples@at + \pgfkeysgetvalue{/pgfplots/variable y}\pgfplots@plot@var@y + % + % \tikz@plot@var is '\x' be default: + \pgfplots@gettikzinternal@keyval{variable}{tikz@plot@var}{\x}% + % + {% + \escapechar=-1 + \xdef\pgfplots@glob@TMPa{\expandafter\string\tikz@plot@var}% + \xdef\pgfplots@glob@TMPb{\expandafter\string\pgfplots@plot@var@y}% + }% + % \pgfplots@plot@var@nonmacro is the value '\tikz@plot@var' + % without the '\', i.e. 'x' by default: + \let\pgfplots@plot@var@nonmacro=\pgfplots@glob@TMPa + \let\pgfplots@plot@var@y@nonmacro=\pgfplots@glob@TMPb + % + % Check if we have to sample a line. + \def\b@pgfplots@should@sample@LINE{0}% + \ifpgfplots@curplot@threedim + \pgfkeysgetvalue{/pgfplots/y domain}{\pgfplots@plot@ydomain}% + \edef\pgfplots@plot@ydomain{\pgfplots@plot@ydomain}% + \def\pgfplots@loc@TMPa{0:0}% + \ifx\pgfplots@plot@ydomain\pgfplots@loc@TMPa + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \ifx\pgfplots@plot@ydomain\pgfutil@empty + \let\pgfplots@plot@ydomain=\pgfplots@plot@domain + \pgfkeyssetvalue{/pgfplots/y domain}{\pgfkeysvalueof{/pgfplots/domain}}% + \fi + \ifx\pgfplots@plot@samples@y\pgfutil@empty + \else + \ifnum\pgfplots@plot@samples@y<2 + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \fi + \else + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \ifx\pgfplots@plot@samples@y\pgfutil@empty + \pgfkeyssetvalue{/pgfplots/samples y}{\pgfkeysvalueof{/pgfplots/samples}}% + \pgfkeysgetvalue{/pgfplots/samples y}\pgfplots@plot@samples@y + \fi + % + \pgfkeyssetvalue{/pgfplots/mesh/rows}{\pgfkeysvalueof{/pgfplots/samples y}}% + \pgfkeyssetvalue{/pgfplots/mesh/cols}{\pgfkeysvalueof{/pgfplots/samples}}% + \if1\b@pgfplots@should@sample@LINE + \pgfkeyssetvalue{/pgfplots/mesh/cols}{1}% + \fi + % +}% + % Plot expression. It invokes the pgf math parser and a customized % pgfplots point sampling routine. Combined with the 'fixed point % library' of pgf, it results in highly accurate plots. @@ -1818,18 +3827,10 @@ \long\def\pgfplots@addplotimpl@expression#1#2(#3,#4)#5;{\pgfplots@addplotimpl@expression@{#1}{#2}{#3}{#4}{#5}}% % \addplot[#1] [#2] (#3,#4) #5; \long\def\pgfplots@addplotimpl@expression@#1#2#3#4#5{% - \ifpgfplots@usefpu - \def\pgfplots@loc@TMPa{/pgf/fpu=true}% - \else - \let\pgfplots@loc@TMPa=\pgfutil@empty - \fi - \expandafter\pgfplots@start@plot@with@behavioroptions\expandafter{\pgfplots@loc@TMPa,#2}% - \pgfplots@PREPARE@COORD@STREAM{#1}{#5}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/mesh/ordering/x varies}% + \pgfplots@plot@expression@preparekeys % - \pgfplots@validate@plot@domain@arguments - \pgfkeysgetvalue{/pgfplots/domain}\pgfplots@plot@domain - \pgfkeysgetvalue{/pgfplots/samples at}\pgfplots@plot@samples@at - \pgfplots@gettikzinternal@keyval{variable}{tikz@plot@var}{\x}% + \pgfplots@PREPARE@COORD@STREAM{#5}% % % Determine whether the x range is parameterized or uniform and % prepare a macro which assigns \pgfplots@current@point@x: @@ -1858,52 +3859,52 @@ }% \fi % - % Define a "function" x which sets \pgfmathresult := \x : - \pgfutil@ifundefined{pgfmathdeclarefunction}{% - % We have PGF 2.00 : - \def\pgfmath@parsefunction@x{\edef\pgfmathresult{\tikz@plot@var}\pgfmath@postfunction}% - \def\pgfmath@parsefunction@y{\let\pgfmathresult=\y\pgfmath@postfunction}% - }{% - % We have PGF > 2.00 : - \pgfmathdeclarefunction{x}{0}{\edef\pgfmathresult{\tikz@plot@var}}% - \pgfmathdeclarefunction{y}{0}{\let\pgfmathresult=\y}% - }% % % Now, prepare the loops. % % I am using \pgfplotsforeachungrouped in favor of % \foreach because \foreach does NOT allow extended - % precision. Besided, \pgfplotsforeachungrouped avoids + % precision. Besides, \pgfplotsforeachungrouped avoids % scoping problems. % \ifpgfplots@curplot@threedim - \pgfkeysgetvalue{/pgfplots/y domain}{\pgfplots@plot@ydomain}% \def\pgfplots@addplotimpl@expression@split@yz##1,##2\pgfplots@EOI{% \def\pgfplots@addplotimpl@expression@yEXPR{##1}% \def\pgfplots@addplotimpl@expression@zEXPR{##2}% }% \pgfplots@addplotimpl@expression@split@yz#4\pgfplots@EOI% - \ifx\pgfplots@plot@ydomain\pgfutil@empty - \def\pgfplots@plot@ydomain{0:0}% - \fi - \ifx\pgfplots@plot@samples@at\pgfutil@empty - % we don't have 'samples at' -> use domain! - \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax - \let\pgfplots@loc@TMPa=\pgfplotslocretval + % + % we don't have 'samples at' for 3D plots -> use domain! + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax{\pgfplots@plot@samples}% + \let\pgfplots@expression@xdomain=\pgfplotsretval + % + \if0\b@pgfplots@should@sample@LINE + % Samples twodimensionally (a lattice): + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@ydomain\relax{\pgfplots@plot@samples@y}% + \let\pgfplots@expression@ydomain=\pgfplotsretval + % + % Assemble a + % \pgfplots@plot@data##1 -> + % \foreach \y in {-5,-4.6,...,5} {##1}; + % \foreach \x in {-5,-4.6,...,5} + % macro: + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\pgfplots@plot@var@y in {\pgfplots@expression@ydomain} + {\noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@expression@xdomain} {##1}}}% \else - % use 'samples at': - \let\pgfplots@loc@TMPa=\pgfplots@plot@samples@at + % sample a line: + \def\pgfplots@plot@ydomain{0:0}% + \edef\pgfplots@plot@data##1{% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@expression@xdomain} {##1}}% + % + % If we have (\x,\y,f(x)), use (\x,0,f(x)) instead and + % suppress the error message which would occur for \y. + \expandafter\pgfplotsutilifstringequal\expandafter{\pgfplots@addplotimpl@expression@yEXPR}{\pgfplots@plot@var@y}{% + \def\pgfplots@addplotimpl@expression@yEXPR{0}% + }{% + \expandafter\edef\pgfplots@plot@var@y{\pgfplots@plot@var@y@nonmacro}% this provides an error message, see above. + }% \fi - \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@ydomain\relax - \let\pgfplots@loc@TMPb=\pgfplotslocretval - % Assemble a - % \pgfplots@plot@data##1 -> - % \foreach \x in {-5,-4.6,...,5} - % \foreach \y in {-5,-4.6,...,5} {##1}; - % macro: - \edef\pgfplots@plot@data##1{% - \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@loc@TMPa} - {\noexpand\pgfplotsforeachungrouped\noexpand\y in {\pgfplots@loc@TMPb} {##1}}}% \else % Assemble a % \pgfplots@plot@data##1 -> \foreach \x in {-5,-4.6,...,5} {##1} macro: @@ -1927,7 +3928,7 @@ \if\pgfplots@samples@logarithmically1% % sample logarithmically: \edef\pgfplots@plot@data##1{% - \noexpand\pgfplotsforeachlogarithmicungrouped + \noexpand\pgfplotsforeachlogarithmicungrouped[\pgfplots@plot@samples] \expandafter\noexpand\tikz@plot@var/\noexpand\pgfplots@current@point@x@log in {\pgfplots@plot@domain} {##1}}% % we have a logarithmic sampling sequence, @@ -1953,8 +3954,8 @@ \else \ifx\pgfplots@plot@samples@at\pgfutil@empty % we don't have 'samples at' -> use domain! - \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax - \let\pgfplots@loc@TMPa=\pgfplotslocretval + \expandafter\pgfplots@domain@to@foreach\pgfplots@plot@domain\relax{\pgfplots@plot@samples}% + \let\pgfplots@loc@TMPa=\pgfplotsretval \else % use 'samples at': \let\pgfplots@loc@TMPa=\pgfplots@plot@samples@at @@ -1962,12 +3963,43 @@ \edef\pgfplots@plot@data##1{ \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@loc@TMPa} {##1}}% \fi - \def\y{0}% + \expandafter\def\pgfplots@plot@var@y{0}% \def\pgfplots@addplotimpl@expression@yEXPR{#4}% \def\pgfplots@current@point@z{}% \fi + % + % START: + % (NOTE: this does also define 'x', 'y', and 'z' math + % expressions!) \pgfplots@coord@stream@start + % + % create a backup of the 'x' and 'y' math expressions which + % have been defined in \pgfplots@coord@stream@start: + \let\pgfplots@addplotimpl@expression@pseudoconst@old@x=\pgfmathx@ + \let\pgfplots@addplotimpl@expression@pseudoconst@old@y=\pgfmathy@ + % + % Prepare 'x' and 'y' as pseudo constants in expressions: + \gdef\pgfplots@noy@error{% + \pgfplots@error{Sorry, you can't use 'y' in this context. PGFPlots expected to sample a line, not a mesh. Please use the [mesh] option combined with [samples y>0] and [domain y!=0:0] to indicate a twodimensional input domain}% + \global\let\pgfplots@noy@error=\relax + }% + % Define a "function" x which sets \pgfmathresult := \x : + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@nonmacro}{\edef\pgfmathresult{\tikz@plot@var}}% + \if0\b@pgfplots@should@sample@LINE + % surface: + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@y@nonmacro}{\edef\pgfmathresult{\pgfplots@plot@var@y}}% + \else + \pgfplotsmathdeclarepseudoconstant{\pgfplots@plot@var@y@nonmacro}{\pgfplots@noy@error\def\pgfmathresult{0.0}}% + \fi + % remember them here: + \let\pgfplots@addplotimpl@expression@pseudoconst@x=\pgfmathx@ + \let\pgfplots@addplotimpl@expression@pseudoconst@y=\pgfmathy@ + % + % \pgfplots@plot@data{% + \let\pgfmathx@=\pgfplots@addplotimpl@expression@pseudoconst@x + \let\pgfmathy@=\pgfplots@addplotimpl@expression@pseudoconst@y + % eval expressions: \pgfplots@addplotimpl@expression@prepare@x% \pgfmathparse{\pgfplots@addplotimpl@expression@yEXPR}% \let\pgfplots@current@point@y=\pgfmathresult @@ -1975,6 +4007,11 @@ \pgfmathparse{\pgfplots@addplotimpl@expression@zEXPR}% \let\pgfplots@current@point@z=\pgfmathresult \fi + % restore 'x' and 'y': + \let\pgfmathx@=\pgfplots@addplotimpl@expression@pseudoconst@old@x + \let\pgfmathy@=\pgfplots@addplotimpl@expression@pseudoconst@old@y + % + % process coords as usual: \pgfplots@coord@stream@coord }% \pgfplots@coord@stream@end @@ -1983,8 +4020,22 @@ \long\def\pgfplots@addplotimpl@expression@curly#1#2#3#4;{\pgfplots@addplotimpl@expression@curly@{#1}{#2}{#3}{#4}}% \long\def\pgfplots@addplotimpl@expression@curly@#1#2#3#4{% \pgfplots@gettikzinternal@keyval{variable}{tikz@plot@var}{\x}% - \def\pgfplots@loc@TMPa{\pgfplots@addplotimpl@expression@{#1}{#2}}% - \expandafter\pgfplots@loc@TMPa\expandafter{\tikz@plot@var}{#3}{#4}% + \ifpgfplots@curplot@threedim + \t@pgfplots@toka={,#3}% + \def\pgfplots@loc@TMPa{\pgfplots@addplotimpl@expression@{#1}{#2}}% + % the \pgfplots@plot@var@y will expand to the current value of + % '/pgfplots/variable y'. + % Keep it this way, \pgfplots@addplotimpl@expression@ checks + % for that special string. + \edef\pgfplots@loc@TMPb{% + {\expandafter\noexpand\tikz@plot@var}% + {\noexpand\pgfplots@plot@var@y\the\t@pgfplots@toka}% + }% + \expandafter\pgfplots@loc@TMPa\pgfplots@loc@TMPb{#4}% + \else + \def\pgfplots@loc@TMPa{\pgfplots@addplotimpl@expression@{#1}{#2}}% + \expandafter\pgfplots@loc@TMPa\expandafter{\tikz@plot@var}{#3}{#4}% + \fi }% % \addplot[#1] [#2] expression[#3] {#4} #5; \def\pgfplots@addplotimpl@expression@e#1#2expression{% @@ -2025,15 +4076,7 @@ % |\addplot gnuplot| is an alias to |\addplot function| \def\pgfplots@addplotimpl@gnuplot#1#2nuplot{\pgfplots@addplotimpl@function{#1}{#2}unction}% -% \addplot[<style options>] -% plot[<behavior opts>] -% function[<further behavior opts>] -% {gnuplot code} -% #3; -% #1: args of \addplot[...] -% #2: optional arguments after function[] -% #3: gnuplot code to generate coordinates -% #4: trailing path commands until ';' +% \addplot[#1] plot[#2] function[#3] {#4} #5; \def\pgfplots@addplotimpl@function#1#2unction{% \pgfutil@ifnextchar[{% \pgfplots@addplotimpl@function@opt{#1}{#2}% @@ -2044,28 +4087,34 @@ \def\pgfplots@addplotimpl@function@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@function@opt@{#1}{#2}{#3}{#4}{#5}}% % \addplot[#1] [#2] function[#3] {#4} #5; \def\pgfplots@addplotimpl@function@opt@#1#2#3#4#5{% - \pgfplots@start@plot@with@behavioroptions{% - #2,#3}% + % FIXME : what about the key search paths if the user changes + % them!? + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3,/pgfplots/mesh/ordering/x varies}% + % \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-plot}% \pgfplots@gettikzinternal@keyval{raw gnuplot}{iftikz@plot@raw@gnuplot}{\iffalse}% \pgfplots@gettikzinternal@keyval{parametric}{iftikz@plot@parametric}{\iffalse}% - \pgfplots@validate@plot@domain@arguments - \pgfkeysgetvalue{/pgfplots/domain}\pgfplots@plot@domain - \pgfkeysgetvalue{/pgfplots/y domain}{\pgfplots@plot@ydomain}% - \ifx\pgfplots@plot@domain\pgfutil@empty - % this is a potential problem: 'plot gnuplot' doesn't support - % the 'samples at' framework which should be in effect now. - % -> acquire the /tikz/domain value! - \pgfplots@gettikzinternal@keyval{domain}{tikz@plot@domain}{-5:5}% - \let\pgfplots@plot@domain=\tikz@plot@domain - \fi % - \def\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + \pgfplots@plot@expression@preparekeys + % + % FIXME: what with 'samples at'!? + \edef\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + % \def\pgfplots@addplotimpl@gnuplotresult@isthreedim@withtwocoords{0}% + % + \edef\pgfplots@gnuplotcode{#4}% + \ifpgfplots@translategnuplot + \def\pgfplots@loc@TMPa{\pgfplotsutilstrreplace{^}{**}}% + \expandafter\pgfplots@loc@TMPa\expandafter{\pgfplots@gnuplotcode}% + \let\pgfplots@gnuplotcode=\pgfplotsretval + \fi + % + % \iftikz@plot@raw@gnuplot% - \def\pgfplots@plot@data{\pgfplotgnuplot[\pgfplots@plot@filename]{#4}}% + \def\pgfplots@plot@data{\pgfplotgnuplot[\pgfplots@plot@filename]{\pgfplots@gnuplotcode}}% \else% + % collect logs: \def\pgfplots@gnuplot@logdirs{}% \ifpgfplots@xislinear \else @@ -2084,42 +4133,94 @@ \fi \pgfplots@disablelogfilter@xtrue \pgfplots@disablelogfilter@ytrue - \ifpgfplots@curplot@threedim - \ifx\pgfplots@plot@ydomain\pgfutil@empty - \pgfplots@error{Sorry, '\string\addplot3 plot function{}' can't be processed correctly because 'y domain' is empty.}% - \def\pgfplots@plot@ydomain{0:1}% + \ifpgfplots@curplot@threedim + \if1\b@pgfplots@should@sample@LINE + \pgfplots@error{Sorry, I do not know how to sample 3D LINE plots with gnuplot... I only know 2D line and 3D mesh. You may want to help the author of pgfplots to improve this feature.}% \fi \fi \def\pgfplots@plot@data{\pgfplotgnuplot[\pgfplots@plot@filename]{% \pgfplots@gnuplot@format; - set samples \pgfkeysvalueof{/pgfplots/samples}; + set samples \pgfkeysvalueof{/pgfplots/samples}\if0\b@pgfplots@should@sample@LINE, \pgfkeysvalueof{/pgfplots/samples y}\fi; \ifx\pgfplots@gnuplot@logdirs\pgfutil@empty \else set logscale \pgfplots@gnuplot@logdirs\space 2.71828182845905; \fi \iftikz@plot@parametric set parametric;\fi \ifpgfplots@curplot@threedim - splot [x=\pgfplots@plot@domain] [y=\pgfplots@plot@ydomain] #4;% + \if0\b@pgfplots@should@sample@LINE + % Samples twodimensionally (a lattice): + % and the isosamples thing confuses me. + set isosamples \pgfkeysvalueof{/pgfplots/samples}\if0\b@pgfplots@should@sample@LINE, \pgfkeysvalueof{/pgfplots/samples y}\fi; + splot [x=\pgfplots@plot@domain] [y=\pgfplots@plot@ydomain] \pgfplots@gnuplotcode;% + \else + % *should* sample a line, but I don't know how. + splot [x=\pgfplots@plot@domain] \pgfplots@gnuplotcode;% + \fi \else - plot [x=\pgfplots@plot@domain] #4;% + plot [x=\pgfplots@plot@domain] \pgfplots@gnuplotcode;% \fi }}% \fi% - \def\pgfplotxyfile{\pgfplots@addplotimpl@gnuplotresult{#1}{#5}}% + \def\pgfplotxyfile{\pgfplots@addplotimpl@gnuplotresult{#5}}% + \pgfplots@plot@data + \let\pgfplotxyfile=\pgfplots@backupof@pgfplotxyfile +}% + +\def\pgfplots@addplotimpl@gnuplotresult#1#2{% + \begingroup + \openin\r@pgfplots@reada=#2 + \ifeof\r@pgfplots@reada + \pgfplots@error{Sorry, the gnuplot-result file '#2' could not be found. Maybe you need to enable the shell-escape feature? For pdflatex, this is '>> pdflatex -shell-escape'. You can also invoke '>> gnuplot <file>.gnuplot' manually on the respective gnuplot file.}% + \aftergroup\pgfplots@loop@CONTINUEfalse + \else + \aftergroup\pgfplots@loop@CONTINUEtrue + \fi + \closein\r@pgfplots@reada + \endgroup + \ifpgfplots@loop@CONTINUE + % Now, invoke 'plot file'. + % + % I invoke the private '@opt@' method because the semicolon ';' + % character may cause problems due to catcode mismatches. + % *sigh*. + \pgfplots@addplotimpl@file@opt@@{}{}{#2}{#1}% this does not invoke the \pgfplots@start@plot@with@behavioroptions method. + \else + \expandafter\pgfplots@end@plot + \fi +} + +% \addplot[#1] plot[#2] shell[#3] {#4} #5; +\def\pgfplots@addplotimpl@shell#1#2shell{% + \pgfutil@ifnextchar[{% + \pgfplots@addplotimpl@shell@opt{#1}{#2}% + }{% + \pgfplots@addplotimpl@shell@opt{#1}{#2}[]% + }% +}% +\def\pgfplots@addplotimpl@shell@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@shell@opt@{#1}{#2}{#3}{#4}{#5}}% +% \addplot[#1] [#2] shell[#3] {#4} #5; +\def\pgfplots@addplotimpl@shell@opt@#1#2#3#4#5{% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3}% + \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% + \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-shell}% + % + \def\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + \def\pgfplots@plot@data{\pgfshell[\pgfplots@plot@filename]{#4}\pgfplotxyfile{\pgfplots@plot@filename.out}}% + \def\pgfplotxyfile{\pgfplots@addplotimpl@shellresult{#5}}% \pgfplots@plot@data \let\pgfplotxyfile=\pgfplots@backupof@pgfplotxyfile }% -\def\pgfplots@addplotimpl@gnuplotresult#1#2#3{% +\def\pgfplots@addplotimpl@shellresult#1#2{% \begingroup - \openin1=#3 - \ifeof1 - \pgfplots@error{Sorry, the gnuplot-result file '#3' could not be found. Maybe you need to enable the shell-escape feature? For pdflatex, this is '>> pdflatex -shell-escape'. You can also invoke '>> gnuplot <file>.gnuplot' manually on the respective gnuplot file.}% + \openin\r@pgfplots@reada=#2 + \ifeof\r@pgfplots@reada + \pgfplots@error{Sorry, the shell-result file '#2' could not be found. Maybe you need to enable the shell-escape feature? For pdflatex, this is '>> pdflatex -shell-escape'. You can also invoke '>> sh <file>.sh > <file>.out' manually on the respective shell file.}% \aftergroup\pgfplots@loop@CONTINUEfalse \else \aftergroup\pgfplots@loop@CONTINUEtrue \fi - \closein1 + \closein\r@pgfplots@reada \endgroup \ifpgfplots@loop@CONTINUE % Now, invoke 'plot file'. @@ -2127,7 +4228,7 @@ % I invoke the private '@opt@' method because the semicolon ';' % character may cause problems due to catcode mismatches. % *sigh*. - \pgfplots@addplotimpl@file@opt@@{#1}{}{#3}{#2}% + \pgfplots@addplotimpl@file@opt@@{}{}{#2}{#1}% \else \expandafter\pgfplots@end@plot \fi @@ -2145,8 +4246,10 @@ % \addplot[#1] [#2] file[#3] {#4} #5; \def\pgfplots@addplotimpl@file@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@file@opt@{#1}{#2}{#3}{#4}{#5}}% \def\pgfplots@addplotimpl@file@opt@#1#2#3#4#5{% - \pgfplots@start@plot@with@behavioroptions{#2}% - \pgfplots@addplotimpl@file@opt@@{#1}{#3}{#4}{#5}% + % invoke this here - allows to share the 'plot file' impl with + % 'plot gnuplot'. + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@addplotimpl@file@opt@@{#1,#2}{#3}{#4}{#5}% } \def\pgfplots@addplotimpl@file@opt@@#1#2#3#4{% \begingroup @@ -2155,42 +4258,37 @@ \else \pgfqkeys{/pgfplots/plot file}{#2}% \fi - \pgfplots@PREPARE@COORD@STREAM{#1}{#4}% + \pgfplots@PREPARE@COORD@STREAM{#4}% \pgfplots@coord@stream@start + \pgfplotsscanlinelengthinitzero \pgfplots@logfileopen{#3}% - \openin1=#3 - \ifeof1 - \pgfplots@warning{sorry, plot file{#3} could not be opened!?}% + \openin\r@pgfplots@reada=#3 + \ifeof\r@pgfplots@reada + \pgfplots@error{sorry, plot file{#3} could not be opened}% \else \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \let\pgfplots@current@point@z@error=\pgfutil@empty + \let\pgfplots@current@point@meta=\pgfutil@empty \ifpgfplots@curplot@threedim \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@threedim - \ifnum\pgfplots@perpointmeta@choice=4 + \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @explicitinput\endcsname \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@threedim@andmeta - \else - \ifnum\pgfplots@perpointmeta@choice=5 - \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@threedim@andmeta - \fi \fi \else \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@twodim - \ifnum\pgfplots@perpointmeta@choice=4 + \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @explicitinput\endcsname \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@twodim@andmeta - \else - \ifnum\pgfplots@perpointmeta@choice=5 - \let\pgfplots@addplotimpl@file@parsesingle=\pgfplots@addplotimpl@file@parsesingle@twodim@andmeta - \fi \fi \fi \pgfplots@addplotimpl@file@readall \fi + \pgfplotsscanlinelengthcleanup \pgfplots@coord@stream@end \endgroup }% \def\pgfplots@addplotimpl@file@readall{% - \read1 to\pgfplots@file@LINE + \read\r@pgfplots@reada to\pgfplots@file@LINE \expandafter\pgfplotstableread@checkspecial@line\pgfplots@file@LINE\pgfplotstable@EOI \ifpgfplotstableread@skipline \else @@ -2198,10 +4296,11 @@ % Silently skip first data row, assuming it is a header. \pgfplots@plot@file@skipfirstfalse \else - \expandafter\pgfplots@addplotimpl@file@parsesingle\pgfplots@file@LINE\pgfplots@EOI + \pgfplotsscanlinelengthincrease + \expandafter\pgfplots@addplotimpl@file@parsesingle\pgfplots@file@LINE 0 0 0 0 0\pgfplots@EOI \fi \fi - \ifeof1 + \ifeof\r@pgfplots@reada \else \expandafter \pgfplots@addplotimpl@file@readall @@ -2244,8 +4343,13 @@ % \addplot[#1] plot[#2] graphics[#3] {#4} #5; \def\pgfplots@addplotimpl@graphics@#1#2[#3]#4#5;{\pgfplots@addplotimpl@graphics@@{#1}{#2}{#3}{#4}{#5}}% \def\pgfplots@addplotimpl@graphics@@#1#2#3#4#5{% - \pgfplots@start@plot@with@behavioroptions{#2,/pgfplots/plot graphics/.cd,#3,/pgfplots/plot graphics/src={#4}}% - \pgfplots@PREPARE@COORD@STREAM{#1,/pgfplots/plot graphics,/tikz/mark=}{#5}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,% + /pgfplots/plot graphics,% + /pgfplots/plot graphics/.cd,% + #3,% + /pgfplots/plot graphics/src={#4},% + /tikz/mark=}% + \pgfplots@PREPARE@COORD@STREAM{#5}% \pgfplots@coord@stream@start \pgfkeysgetvalue{/pgfplots/plot graphics/xmin}{\pgfplots@current@point@x}% \pgfkeysgetvalue{/pgfplots/plot graphics/ymin}{\pgfplots@current@point@y}% @@ -2278,6 +4382,55 @@ +% \addplot[#1] table[#2] [from] {<\macro>} #4; +% or +% \addplot[#1] table[#2] {<filename>} #4; +% +% The distinction between <\macro> and <filename> is done +% automatically. +% +% Input options can be provided in '#2' using +% - column names, +% for example '/pgfplots/table/x=firstcol' or just 'x=firstcol' +% +% - column indices, +% for example '/pgfplots/table/x index=3' or just 'x index=3' +% +% - expressions involving any of the table's data cells in the +% currently processed cell, +% for example '/pgfplots/table/x expr={\columnx * \columny + \thisrow{columnxxx}/2}' +% During expr, the following (non-exhaustive) list of macros is +% available: +% - \columnx, \columny, \columnz, \columnmeta, \columnerrorx, +% \columnerrory, \columnerrorz +% Provide access to the cell content which would be used without +% 'expr'. +% The first three access the input coordinate columns, \meta the meta column +% (if any) and the last three the error data (if any). +% +% That means it is allowed to provide both, 'x' and 'x expr': +% 'x expr' can use the (old) value stored in 'x'. the final x +% coordinate will be that returned of 'x expr'. +% +% - \coordindex +% +% - \lineno (physical line numbers including comments etc) +% +% - \thisrow{<colname>} +% allows access to any columns. +% +% - \getthisrow{<colname>}{<\macro>} +% this is a fragile command! Don't use it directly inside of +% a math expression, prefer \thisrow. +% +% The FPU will be used to evaluate any expressions. +% +% @REMARKS the implementation for '* expr' differs for the '<\macro>' +% and '<filename>' input types: +% - for '{<filename>}', only the current row is available. +% - for '{<\macro>}', the `create on use' framework of the table +% package is used - with all its features, including comfortable +% access to the previous and next row and accumulation features. \def\pgfplots@addplotimpl@table#1table{% \pgfutil@ifnextchar[{% \pgfplots@addplotimpl@table@getopts{#1}% @@ -2287,10 +4440,14 @@ }% \def\pgfplots@addplotimpl@table@getopts#1[#2]{% - \pgfutil@ifnextchar f{% - \pgfplots@addplotimpl@table@fromstructure{#1}{#2}% + \pgfutil@ifnextchar s{% + \pgfplots@addplotimpl@table@fromshell{#1}{#2}% }{% - \pgfplots@addplotimpl@table@fromfile{#1}{#2}% + \pgfutil@ifnextchar f{% + \pgfplots@addplotimpl@table@fromstructure{#1}{#2}% + }{% + \pgfplots@addplotimpl@table@fromfile{#1}{#2}% + }% }% } @@ -2320,6 +4477,7 @@ \pgfplots@addplotimpl@table@installkeypath \pgfplotstableset{#2}% \begingroup + \pgfplotstablegetscanlinelength{#3}{\pgfplotsscanlinelength}% % FIXME : this thing here has runtime O(N^2) ! % I fear it is faster to simply reload the data .... !? % @@ -2334,36 +4492,56 @@ \pgfkeysgetvalue{/pgfplots/table/z index}{\pgfplots@plot@tbl@zindex}% \pgfkeysgetvalue{/pgfplots/table/meta}{\pgfplots@plot@tbl@meta}% \pgfkeysgetvalue{/pgfplots/table/meta index}{\pgfplots@plot@tbl@metaindex}% + % \ifx\pgfplots@plot@tbl@x\pgfutil@empty - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@xindex\of\pgfplots@table\to\addplot@tbl@x - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@x\of\pgfplots@table\to\addplot@tbl@x + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@xindex\of\pgfplots@table\to\pgfplots@plot@tbl@x \fi \ifx\pgfplots@plot@tbl@y\pgfutil@empty - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@yindex\of\pgfplots@table\to\addplot@tbl@y - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@y\of\pgfplots@table\to\addplot@tbl@y + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@yindex\of\pgfplots@table\to\pgfplots@plot@tbl@y \fi \ifpgfplots@curplot@threedim \ifx\pgfplots@plot@tbl@z\pgfutil@empty - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@zindex\of\pgfplots@table\to\addplot@tbl@z - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@z\of\pgfplots@table\to\addplot@tbl@z + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@zindex\of\pgfplots@table\to\pgfplots@plot@tbl@z \fi \fi - \let\addplot@tbl@meta=\pgfutil@empty \ifx\pgfplots@plot@tbl@meta\pgfutil@empty \ifx\pgfplots@plot@tbl@metaindex\pgfutil@empty \else - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@metaindex\of\pgfplots@table\to\addplot@tbl@meta + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@metaindex\of\pgfplots@table\to\pgfplots@plot@tbl@meta \fi + \fi + % + % + % high level user interface functions: + \def\coordindex{\pgfplotstablerow}% + \let\lineno=\coordindex% is the same here + % + % modify \pgfplots@plot@tbl@{x,y,z,meta} if there are + % corresponding '#1 expr' statements: + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for x\columnx% + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for y\columny% + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for {meta}\columnmeta% + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for z\columnz% + \fi + % + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@x\of\pgfplots@table\to\addplot@tbl@x + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@y\of\pgfplots@table\to\addplot@tbl@y + \ifpgfplots@curplot@threedim + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@z\of\pgfplots@table\to\addplot@tbl@z + \fi + % + \let\addplot@tbl@meta=\pgfutil@empty + \ifx\pgfplots@plot@tbl@meta\pgfutil@empty \else \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@meta\of\pgfplots@table\to\addplot@tbl@meta \fi % + % + \let\addplot@tbl@error@x=\pgfutil@empty + \let\addplot@tbl@error@y=\pgfutil@empty + \let\addplot@tbl@error@z=\pgfutil@empty \ifpgfplots@errorbars@enabled - \let\addplot@tbl@error@x=\pgfutil@empty - \let\addplot@tbl@error@z=\pgfutil@empty \pgfkeysgetvalue{/pgfplots/table/x error index}\pgfplots@plot@tbl@error@xindex \pgfkeysgetvalue{/pgfplots/table/x error}\pgfplots@plot@tbl@error@x \pgfkeysgetvalue{/pgfplots/table/y error index}\pgfplots@plot@tbl@error@yindex @@ -2373,39 +4551,57 @@ \ifx\pgfplots@plot@tbl@error@x\pgfutil@empty \ifx\pgfplots@plot@tbl@error@xindex\pgfutil@empty \else - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@error@xindex\of\pgfplots@table\to\addplot@tbl@error@x + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@error@xindex\of\pgfplots@table\to\pgfplots@plot@tbl@error@x \fi - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@x\of\pgfplots@table\to\addplot@tbl@error@x \fi + % \ifx\pgfplots@plot@tbl@error@y\pgfutil@empty \ifx\pgfplots@plot@tbl@error@yindex\pgfutil@empty \else - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@error@yindex\of\pgfplots@table\to\addplot@tbl@error@y + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@error@yindex\of\pgfplots@table\to\pgfplots@plot@tbl@error@y \fi - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@y\of\pgfplots@table\to\addplot@tbl@error@y \fi + % \ifpgfplots@curplot@threedim \ifx\pgfplots@plot@tbl@error@z\pgfutil@empty \ifx\pgfplots@plot@tbl@error@zindex\pgfutil@empty \else - \pgfplotstablegetcolumnbyindex\pgfplots@plot@tbl@error@zindex\of\pgfplots@table\to\addplot@tbl@error@z + \pgfplotstablegetcolumnnamebyindex\pgfplots@plot@tbl@error@zindex\of\pgfplots@table\to\pgfplots@plot@tbl@error@z \fi - \else - \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@z\of\pgfplots@table\to\addplot@tbl@error@z \fi + \else + \let\pgfplots@plot@tbl@error@z=\pgfutil@empty \fi - \fi - % - \ifpgfplots@errorbars@enabled + % + % modify \pgfplots@plot@tbl@{x error,y error,z error} if there are + % corresponding '#1 expr' statements: + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for {x error}\columnerrorx% + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for {y error}\columnerrory% + \ifpgfplots@curplot@threedim + \pgfplots@addplotimpl@table@fromstructure@prepareexpr@for {z error}\columnerrorz% + \fi + % + % now: load the columns: + \ifx\pgfplots@plot@tbl@error@x\pgfutil@empty + \else + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@x\of\pgfplots@table\to\addplot@tbl@error@x + \fi + \ifx\pgfplots@plot@tbl@error@y\pgfutil@empty + \else + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@y\of\pgfplots@table\to\addplot@tbl@error@y + \fi + \ifx\pgfplots@plot@tbl@error@z\pgfutil@empty + \else + \pgfplotstablegetcolumnbyname\pgfplots@plot@tbl@error@z\of\pgfplots@table\to\addplot@tbl@error@z + \fi + % \else \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \let\pgfplots@current@point@z@error=\pgfutil@empty \fi - \let\pgfplots@current@point@meta=\pgfutil@empty - \pgfplots@PREPARE@COORD@STREAM{#1}{#4}% + % + \pgfplots@PREPARE@COORD@STREAM{#4}% \pgfplots@coord@stream@start \pgfutil@loop \pgfplotslistcheckempty\addplot@tbl@x @@ -2443,22 +4639,62 @@ \else \pgfplotslistpopfront\addplot@tbl@error@y\to\pgfplots@current@point@y@error \fi - \ifpgfplots@errorbars@enabled - \ifx\addplot@tbl@error@z\pgfutil@empty - \let\pgfplots@current@point@z@error=\pgfutil@empty - \else - \pgfplotslistpopfront\addplot@tbl@error@z\to\pgfplots@current@point@z@error - \fi + \ifx\addplot@tbl@error@z\pgfutil@empty + \let\pgfplots@current@point@z@error=\pgfutil@empty + \else + \pgfplotslistpopfront\addplot@tbl@error@z\to\pgfplots@current@point@z@error \fi - \pgfplots@coord@stream@coord - \else - \pgfplots@coord@stream@coord \fi + \pgfplots@coord@stream@coord \pgfutil@repeat \pgfplots@coord@stream@end + \pgfmath@smuggleone\pgfplotsscanlinelength \endgroup } +% A private helper macro which initialises the '#1 expr' keys for plot +% table from structure. +% +% PRECONDITION: +% \pgfplots@plot@tbl@#1 contains the column name which would be used +% if '#1 expr' is empty. +% +% POSTCONDITION: +% \pgfplots@plot@tbl@#1 will be CHANGED to use the 'expr' column (a +% temporary name). +% The old value of \pgfplots@plot@tbl@#1 is available as column +% alias. +% the high level user interface command '#2' will be set correctly. +\def\pgfplots@addplotimpl@table@fromstructure@prepareexpr@for#1#2{% + % get old column name into a register: + \t@pgfplots@tokb=\expandafter\expandafter\expandafter{\csname pgfplots@plot@tbl@#1\endcsname}% + % + % high level user interface command: + \edef#2{\noexpand\thisrow{\the\t@pgfplots@tokb}}% + % + \pgfkeysgetvalue{/pgfplots/table/#1 expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + % get expression into register: + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% + % + % + % assemble pgfkeys statement which expands the names above + % just one time: + \edef\pgfplots@loc@TMPa{% + /pgfplots/table/create on use/#1expr@tempcol/.style={% + /pgfplots/table/create col/expr={\the\t@pgfplots@toka}% + },% + /pgfplots/table/alias/#1/.initial={\the\t@pgfplots@tokb}% + }% + \expandafter\pgfkeysalso\expandafter{\pgfplots@loc@TMPa}% + % + % tell `plot table' which column should be used for '#1': the + % temporary column. + \expandafter\def\csname pgfplots@plot@tbl@#1\endcsname{#1expr@tempcol}% + \fi +}% + % \addplot[#1] table[#2] {#3} #4; % @@ -2471,6 +4707,7 @@ % #2: arguments to table[...] % #3: the argument of plot table{...} % #4: trailing path arguments after plot table{...}#4; +% \long\def\pgfplots@addplotimpl@table@fromfile#1#2#3#4;{\pgfplots@addplotimpl@table@startprocessing{#1}{#2}{#3}{#4}}% % \addplot[#1] table[#2] {#3} {#4}; \long\def\pgfplots@addplotimpl@table@fromfile@#1#2#3#4{% @@ -2485,165 +4722,292 @@ % \pgfplots@addplotimpl@table@fromstructure{#1}{}from{\pgfplots@table}{#4};% % \endgroup %-------------------------------------------------- - \begingroup + %\begingroup \ifpgfplots@addplotimpl@readcompletely \pgfplotstableread{#3}\pgfplots@table \pgfplots@addplotimpl@table@fromstructure@{#1}{}{\pgfplots@table}{#4}% - \endgroup + % \pgfmath@smuggleone\pgfplotsscanlinelength + % \endgroup + % \pgfplotsscanlinedisablechanges \else \pgfplotsapplistXXglobalnewempty - \pgfkeysgetvalue{/pgfplots/table/x}{\pgfplots@plot@tbl@x}% - \pgfkeysgetvalue{/pgfplots/table/x index}{\pgfplots@plot@tbl@xindex}% - \pgfkeysgetvalue{/pgfplots/table/y}{\pgfplots@plot@tbl@y}% - \pgfkeysgetvalue{/pgfplots/table/y index}{\pgfplots@plot@tbl@yindex}% - \pgfkeysgetvalue{/pgfplots/table/z}{\pgfplots@plot@tbl@z}% - \pgfkeysgetvalue{/pgfplots/table/z index}{\pgfplots@plot@tbl@zindex}% - \pgfkeysgetvalue{/pgfplots/table/meta}{\pgfplots@plot@tbl@meta}% - \pgfkeysgetvalue{/pgfplots/table/meta index}{\pgfplots@plot@tbl@metaindex}% + % + % these data pointers will be prepared to allow fast access + % into the current row while we read rows succesively from + % disk. + % Note: their initialisation must be postponed until + % \pgfplotstableread is running - otherwise, we can't query + % pointers into the table. See below. \let\pgfplots@table@PTR@x=\pgfutil@empty \let\pgfplots@table@PTR@y=\pgfutil@empty \let\pgfplots@table@PTR@z=\pgfutil@empty \let\pgfplots@table@PTR@meta=\pgfutil@empty + % + % \let\pgfplots@current@point@meta=\pgfutil@empty \let\pgfplots@current@point@z=\pgfutil@empty + % + % high level user interface functions: + \def\lineno{\pgfplotstablelineno}% + \def\columnx{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@x}}% + \def\columny{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@y}}% + \def\columnz{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@z}}% + \def\columnmeta{\pgfplotstablereadvalueofptr{\pgfplots@table@PTR@meta}}% + % + \pgfplots@PREPARE@COORD@STREAM{#4}% + \pgfplots@coord@stream@start \ifpgfplots@errorbars@enabled + % more fast-access pointers for error data: \let\pgfplots@table@ERRPTR@x=\pgfutil@empty \let\pgfplots@table@ERRPTR@y=\pgfutil@empty \let\pgfplots@table@ERRPTR@z=\pgfutil@empty - \pgfkeysgetvalue{/pgfplots/table/x error index}\pgfplots@plot@tbl@error@xindex - \pgfkeysgetvalue{/pgfplots/table/x error}\pgfplots@plot@tbl@error@x - \pgfkeysgetvalue{/pgfplots/table/y error index}\pgfplots@plot@tbl@error@yindex - \pgfkeysgetvalue{/pgfplots/table/y error}\pgfplots@plot@tbl@error@y - \pgfkeysgetvalue{/pgfplots/table/z error index}\pgfplots@plot@tbl@error@zindex - \pgfkeysgetvalue{/pgfplots/table/z error}\pgfplots@plot@tbl@error@z - \pgfplotstableread{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL + % + % prepare: + \let\pgfplots@current@point@x@error=\pgfutil@empty + \let\pgfplots@current@point@y@error=\pgfutil@empty + \let\pgfplots@current@point@z@error=\pgfutil@empty + % + % high level user interface functions: + \def\columnerrorx{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@x}}% + \def\columnerrory{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@y}}% + \def\columnerrorz{\pgfplotstablereadvalueofptr{\pgfplots@table@ERRPTR@z}}% + % + \pgfplotstableread*{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL \else - \pgfplotstableread{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@COLLECTNORMALIZED + \pgfplotstableread*{#3} to listener\pgfplots@addplotimpl@table@fromfile@listener@COLLECTNORMALIZED \fi - \endgroup + \pgfplots@coord@stream@end + % FIXME : i'd be glad if I could save this group: check why not + % perhaps because \pgfplotstableread uses several pgf + % variables? + %\pgfmath@smuggleone\pgfplotsscanlinelength + %\endgroup + %\pgfplotsscanlinedisablechanges % - \pgfplots@PREPARE@COORD@STREAM{#1}{#4}% - \pgfplotsapplistXXgloballet\pgfplots@coordlist - \pgfplotsapplistXXglobalclear - \ifpgfplots@errorbars@enabled - \ifpgfplots@curplot@threedim - \expandafter\pgfplots@coord@stream@foreach@threedim\expandafter{\pgfplots@coordlist}%% - \else - \expandafter\pgfplots@coord@stream@foreach\expandafter{\pgfplots@coordlist}%% - \fi - \else + %\pgfplots@PREPARE@COORD@STREAM{#4}% + %\pgfplotsapplistXXgloballet\pgfplots@coordlist + %\pgfplotsapplistXXglobalclear + %\ifpgfplots@errorbars@enabled + % \pgfplots@plot@coords@mathparserfalse + % \ifpgfplots@curplot@threedim + % \expandafter\pgfplots@coord@stream@foreach@threedim\expandafter{\pgfplots@coordlist}%% + % \else + % \expandafter\pgfplots@coord@stream@foreach\expandafter{\pgfplots@coordlist}%% + % \fi + %\else % this here is the usual case; it is faster than the error bar % stuff. - \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@coordlist}% - \fi + % \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@coordlist}% + %\fi \fi } \def\pgfplots@addplotimpl@table@fromfile@listener@COLLECTNORMALIZED{% \pgfplots@addplotimpl@table@fromfile@listener@ - \edef\pgfplots@current@point{% - \pgfplots@current@point@x,% - \pgfplots@current@point@y,% - \pgfplots@current@point@z,% - \pgfplots@current@point@meta% - ;% - }% - \expandafter\pgfplotsapplistXXglobalpushback\expandafter{\pgfplots@current@point}% + \pgfplots@coord@stream@coord } -\def\pgfplots@addplotimpl@table@fromfile@listener@{% - \ifx\pgfplots@table@PTR@x\pgfutil@empty - % this here is only evaluated ONCE. - \ifx\pgfplots@plot@tbl@x\pgfutil@empty - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@xindex}{\pgfplots@table@PTR@x}% +\def\pgfplots@addplotimpl@table@fromfile@listener@PREPARE{% + % this here is only evaluated ONCE. + \pgfkeysgetvalue{/pgfplots/table/x}{\pgfplots@plot@tbl@x}% + \pgfkeysgetvalue{/pgfplots/table/x index}{\pgfplots@plot@tbl@xindex}% + \pgfkeysgetvalue{/pgfplots/table/y}{\pgfplots@plot@tbl@y}% + \pgfkeysgetvalue{/pgfplots/table/y index}{\pgfplots@plot@tbl@yindex}% + \pgfkeysgetvalue{/pgfplots/table/z}{\pgfplots@plot@tbl@z}% + \pgfkeysgetvalue{/pgfplots/table/z index}{\pgfplots@plot@tbl@zindex}% + \pgfkeysgetvalue{/pgfplots/table/meta}{\pgfplots@plot@tbl@meta}% + \pgfkeysgetvalue{/pgfplots/table/meta index}{\pgfplots@plot@tbl@metaindex}% + % + \pgfkeysgetvalue{/pgfplots/table/x expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@x{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@x\pgfplots@current@point@x + }% + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@x{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/x expr}}% + \let\pgfplots@current@point@x=\pgfmathresult + }% + \fi + % + \pgfkeysgetvalue{/pgfplots/table/y expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@y{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@y\pgfplots@current@point@y + }% + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@y{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/y expr}}% + \let\pgfplots@current@point@y=\pgfmathresult + }% + \fi + % + \ifx\pgfplots@plot@tbl@x\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@xindex}{\pgfplots@table@PTR@x}% + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@x}{\pgfplots@table@PTR@x}% + \fi + \ifx\pgfplots@plot@tbl@y\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@yindex}{\pgfplots@table@PTR@y}% + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@y}{\pgfplots@table@PTR@y}% + \fi + \ifpgfplots@curplot@threedim + % + \pgfkeysgetvalue{/pgfplots/table/z expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \def\pgfplots@dereferencepointer@and@ASSIGN@z{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@z\pgfplots@current@point@z + }% \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@x}{\pgfplots@table@PTR@x}% + \def\pgfplots@dereferencepointer@and@ASSIGN@z{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/z expr}}% + \let\pgfplots@current@point@z=\pgfmathresult + }% \fi - \ifx\pgfplots@plot@tbl@y\pgfutil@empty - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@yindex}{\pgfplots@table@PTR@y}% + \ifx\pgfplots@plot@tbl@z\pgfutil@empty + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@zindex}{\pgfplots@table@PTR@z}% \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@y}{\pgfplots@table@PTR@y}% - \fi - \ifpgfplots@curplot@threedim - \ifx\pgfplots@plot@tbl@z\pgfutil@empty - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@zindex}{\pgfplots@table@PTR@z}% - \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@z}{\pgfplots@table@PTR@z}% - \fi + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@z}{\pgfplots@table@PTR@z}% \fi - \ifx\pgfplots@plot@tbl@meta\pgfutil@empty - \ifx\pgfplots@plot@tbl@metaindex\pgfutil@empty - \else - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@metaindex}{\pgfplots@table@PTR@meta}% - \fi + \else + \let\pgfplots@dereferencepointer@and@ASSIGN@z=\relax + \fi + % + % + \def\pgfplots@dereferencepointer@and@ASSIGN@meta{% + \pgfplotstablereadevalptr\pgfplots@table@PTR@meta\pgfplots@current@point@meta + }% + \ifx\pgfplots@plot@tbl@meta\pgfutil@empty + \ifx\pgfplots@plot@tbl@metaindex\pgfutil@empty + \let\pgfplots@dereferencepointer@and@ASSIGN@meta=\relax \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@meta}{\pgfplots@table@PTR@meta}% + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@metaindex}{\pgfplots@table@PTR@meta}% \fi + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@meta}{\pgfplots@table@PTR@meta}% \fi - \pgfplotstablereadevalptr\pgfplots@table@PTR@x\pgfplots@current@point@x - \pgfplotstablereadevalptr\pgfplots@table@PTR@y\pgfplots@current@point@y - \ifpgfplots@curplot@threedim - \pgfplotstablereadevalptr\pgfplots@table@PTR@z\pgfplots@current@point@z - \fi - \ifx\pgfplots@table@PTR@meta\pgfutil@empty + \pgfkeysgetvalue{/pgfplots/table/meta expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty \else - \pgfplotstablereadevalptr\pgfplots@table@PTR@meta\pgfplots@current@point@meta + \def\pgfplots@dereferencepointer@and@ASSIGN@meta{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/meta expr}}% + \let\pgfplots@current@point@meta=\pgfmathresult + }% \fi + \let\pgfplots@addplotimpl@table@fromfile@listener@PREPARE=\relax }% -\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL{% - \pgfplots@addplotimpl@table@fromfile@listener@ +\def\pgfplots@addplotimpl@table@fromfile@listener@{% + \pgfplots@addplotimpl@table@fromfile@listener@PREPARE + \pgfplots@dereferencepointer@and@ASSIGN@x + \pgfplots@dereferencepointer@and@ASSIGN@y + \pgfplots@dereferencepointer@and@ASSIGN@z + \pgfplots@dereferencepointer@and@ASSIGN@meta +}% +\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare{% + % this here is only evaluated ONCE. + \pgfkeysgetvalue{/pgfplots/table/x error index}\pgfplots@plot@tbl@error@xindex + \pgfkeysgetvalue{/pgfplots/table/x error}\pgfplots@plot@tbl@error@x + \pgfkeysgetvalue{/pgfplots/table/y error index}\pgfplots@plot@tbl@error@yindex + \pgfkeysgetvalue{/pgfplots/table/y error}\pgfplots@plot@tbl@error@y + \pgfkeysgetvalue{/pgfplots/table/z error index}\pgfplots@plot@tbl@error@zindex + \pgfkeysgetvalue{/pgfplots/table/z error}\pgfplots@plot@tbl@error@z % - \ifx\pgfplots@table@ERRPTR@x\pgfutil@empty - % this here is only evaluated ONCE. - \ifx\pgfplots@plot@tbl@error@x\pgfutil@empty - \ifx\pgfplots@plot@tbl@error@xindex\pgfutil@empty - \let\pgfplots@table@ERRPTR@x=\relax% - \else - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@xindex}{\pgfplots@table@ERRPTR@x}% - \fi + \def\pgfplots@table@ERRPTR@x{x error}% + \def\pgfplots@table@ERRPTR@y{y error}% + \def\pgfplots@table@ERRPTR@z{z error}% + % + \def\pgfplots@dereferencepointer@and@ASSIGN@error@x{% + \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@x\pgfplots@current@point@x@error + }% + \def\pgfplots@dereferencepointer@and@ASSIGN@error@y{% + \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@y\pgfplots@current@point@y@error + }% + \def\pgfplots@dereferencepointer@and@ASSIGN@error@z{% + \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@z\pgfplots@current@point@z@error + }% + % + \ifx\pgfplots@plot@tbl@error@x\pgfutil@empty + \ifx\pgfplots@plot@tbl@error@xindex\pgfutil@empty + \let\pgfplots@table@ERRPTR@x=\relax% + \let\pgfplots@dereferencepointer@and@ASSIGN@error@x=\relax \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@x}{\pgfplots@table@ERRPTR@x}% + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@xindex}{\pgfplots@table@ERRPTR@x}% \fi - \ifx\pgfplots@plot@tbl@error@y\pgfutil@empty - \ifx\pgfplots@plot@tbl@error@yindex\pgfutil@empty - \let\pgfplots@table@ERRPTR@y=\relax% - \else - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@yindex}{\pgfplots@table@ERRPTR@y}% - \fi + \else + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@x}{\pgfplots@table@ERRPTR@x}% + \fi + % + \pgfkeysgetvalue{/pgfplots/table/x error expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@error@x{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/x error expr}}% + \let\pgfplots@current@point@x@error=\pgfmathresult + }% + \fi + % + % + \ifx\pgfplots@plot@tbl@error@y\pgfutil@empty + \ifx\pgfplots@plot@tbl@error@yindex\pgfutil@empty + \let\pgfplots@table@ERRPTR@y=\relax% + \let\pgfplots@dereferencepointer@and@ASSIGN@error@y=\relax \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@y}{\pgfplots@table@ERRPTR@y}% - \fi - \ifpgfplots@curplot@threedim - \ifx\pgfplots@plot@tbl@error@z\pgfutil@empty - \ifx\pgfplots@plot@tbl@error@zindex\pgfutil@empty - \let\pgfplots@table@ERRPTR@z=\relax% - \else - \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@zindex}{\pgfplots@table@ERRPTR@z}% - \fi - \else - \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@z}{\pgfplots@table@ERRPTR@z}% - \fi + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@yindex}{\pgfplots@table@ERRPTR@y}% \fi - \fi - \ifx\relax\pgfplots@table@ERRPTR@x - \let\pgfplots@current@point@x@error=\pgfutil@empty \else - \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@x\pgfplots@current@point@x@error + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@y}{\pgfplots@table@ERRPTR@y}% \fi - \ifx\relax\pgfplots@table@ERRPTR@y - \let\pgfplots@current@point@y@error=\pgfutil@empty + % + \pgfkeysgetvalue{/pgfplots/table/y error expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty \else - \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@y\pgfplots@current@point@y@error + \def\pgfplots@dereferencepointer@and@ASSIGN@error@y{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/y error expr}}% + \let\pgfplots@current@point@y@error=\pgfmathresult + }% \fi + % + % \ifpgfplots@curplot@threedim - \ifx\relax\pgfplots@table@ERRPTR@z - \let\pgfplots@current@point@z@error=\pgfutil@empty + \ifx\pgfplots@plot@tbl@error@z\pgfutil@empty + \ifx\pgfplots@plot@tbl@error@zindex\pgfutil@empty + \let\pgfplots@table@ERRPTR@z=\relax% + \let\pgfplots@dereferencepointer@and@ASSIGN@error@z=\relax + \else + \pgfplotstablereadgetptrtocolindex{\pgfplots@plot@tbl@error@zindex}{\pgfplots@table@ERRPTR@z}% + \fi \else - \pgfplotstablereadevalptr\pgfplots@table@ERRPTR@z\pgfplots@current@point@z@error + \pgfplotstablereadgetptrtocolname{\pgfplots@plot@tbl@error@z}{\pgfplots@table@ERRPTR@z}% \fi - \edef\pgfplots@current@point{(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)+-(\pgfplots@current@point@x@error,\pgfplots@current@point@y@error,\pgfplots@current@point@z@error) [\pgfplots@current@point@meta]}% + % + \pgfkeysgetvalue{/pgfplots/table/z error expr}{\pgfplots@loc@TMPa}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \def\pgfplots@dereferencepointer@and@ASSIGN@error@z{% + \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/z error expr}}% + \let\pgfplots@current@point@z@error=\pgfmathresult + }% + \fi + % + % \else - \edef\pgfplots@current@point{(\pgfplots@current@point@x,\pgfplots@current@point@y)+-(\pgfplots@current@point@x@error,\pgfplots@current@point@y@error) [\pgfplots@current@point@meta]}% + \let\pgfplots@dereferencepointer@and@ASSIGN@error@z=\relax + \fi + \let\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare=\relax +} +\def\pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL{% + \pgfplots@addplotimpl@table@fromfile@listener@ + \pgfplots@addplotimpl@table@fromfile@listener@witherrors@COLLECTHIGHLEVEL@prepare + % + \pgfplots@dereferencepointer@and@ASSIGN@error@x + \pgfplots@dereferencepointer@and@ASSIGN@error@y + \ifpgfplots@curplot@threedim + \pgfplots@dereferencepointer@and@ASSIGN@error@z + %\edef\pgfplots@current@point{(\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z)+-(\pgfplots@current@point@x@error,\pgfplots@current@point@y@error,\pgfplots@current@point@z@error) [\pgfplots@current@point@meta]}% + %\else + %\edef\pgfplots@current@point{(\pgfplots@current@point@x,\pgfplots@current@point@y)+-(\pgfplots@current@point@x@error,\pgfplots@current@point@y@error) [\pgfplots@current@point@meta]}% \fi - \expandafter\pgfplotsapplistXXglobalpushback\expandafter{\pgfplots@current@point}% + \pgfplots@coord@stream@coord + %\expandafter\pgfplotsapplistXXglobalpushback\expandafter{\pgfplots@current@point}% }% \def\pgfplots@addplotimpl@table@installkeypath{% \pgfkeysdef{/pgfplots/table/.unknown}{% @@ -2652,35 +5016,140 @@ }% }% +% \addplot[#1] table[#2] shell{#3} #4; +% +% #1: arguments to \addplot[...] +% #2: arguments to table[...] +% #3: the argument of plot table shell{...} +% #4: trailing path arguments after plot table shell{...}#4; +\long\def\pgfplots@addplotimpl@table@fromshell#1#2shell#3#4;{% + \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% + \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-shell}% + % + \def\pgfplots@plot@filename{\tikz@plot@prefix\tikz@plot@id}% + \pgfshell[\pgfplots@plot@filename]{#3}\pgfplots@addplotimpl@table@fromfile{#1}{#2}{\pgfplots@plot@filename.out}#4;% +}% + +% A common routine which resets internal data structures for the +% survey phase, i.e. it is the shared implementation for all \addplot +% variations. +% +% It takes all options which are provided to \addplot, sets them (at +% least partially) and remembers them for the command serialization. +% % #1: arguments to \addplot plot[#1] % -> these are called 'behavior' options in the manual; they are set % immediately. +% +% PRECONDITION: +% \pgfplots@addplotimpl@plot@withoptions has already been invoked +% +% POSTCONDITION: +% - internal datastructures are initialised (coordinate indexing, fpu) +% - all keys which are required for the current plot are determined +% (and set if necessary). +% They are stored into +% \pgfplots@addplot@survey@@optionlist. +% \def\pgfplots@start@plot@with@behavioroptions#1{% %\begingroup%<-- has been moved to \pgfplots@addplotimpl@plot@withoptions - \def\pgfplots@current@point@coordindex{0}% can be used inside of coordinate filters. + \c@pgfplots@coordindex=0 + \def\pgfplots@current@point@coordindex{\the\c@pgfplots@coordindex}% can be used inside of coordinate filters. \def\coordindex{\pgfplots@current@point@coordindex}% valid inside of \addplot - \ifx\pgfplots@execute@at@begin@plot\pgfutil@empty - \else - \pgfplots@execute@at@begin@plot + \ifpgfplots@usefpu + \pgfkeys{/pgf/fpu=true}% \fi - \let\pgfplots@addplot@nonlegend@options=\pgfutil@empty - \pgfplots@process@behavioroptions{#1}% + \def\pgfplots@addplot@running{1}% + % % these styles may contain behavior options (error bars, % samples,... ) activate them! + % + % As of february 20, 2009, #1 will contain BOTH, /pgfplots + % and /tikz options. The /tikz ones are primarily for drawing + % and are UNIMPORTANT at this stage of processing. + % In fact, transparency etc. will only confuse everything. + % + % So: ignore them and set only /pgfplots keys here: + % This may actually redefine styles, for example + % \addplot[every mark/.append style={}] will use + % /pgfplots/every mark/.append style. + % But that doesn't hurt here. + % + % there are some exceptions like /tikz/id etc. These + % exceptions need special styles in the /pgfplots root - or I + % need to change the .unknown handler. See the available + % compatibility styles! + % + \pgfkeysdef{/pgfplots/.unknown}{% +%\message{In \string\addplot[#1]: I am silently ignoring key `\pgfkeyscurrentkeyRAW' during the preparation phase.}% + }% + % + % it is possible that '#1' contains 'forget plot'. So, we need to + % set the options before checking + % \ifpgfplots@curplot@isirrelevant: + \pgfplotsset{/pgfplots/every axis plot,#1}% + % + % hooks: + \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% + \pgfkeysvalueof{/pgfplots/execute at begin plot}% + % \ifpgfplots@curplot@isirrelevant - \pgfplotsset{/pgfplots/every axis plot,/pgfplots/every forget plot/.try}% + \def\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every forget plot}% + \pgfplotsset{/pgfplots/every forget plot,/pgfplots/every axis plot post}% \else - \pgfplotsset{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% + \edef\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% + \pgfplotsset{/pgfplots/every axis plot no \the\pgfplots@numplots/.try,/pgfplots/every axis plot post}% \fi + \expandafter\def\expandafter\pgfplots@addplot@survey@@optionlist\expandafter{\pgfplots@addplot@survey@@optionlist,% + #1,/pgfplots/.cd,/pgfplots/every axis plot post}% + \pgfplots@validate@plot@domain@arguments } -\def\pgfplots@process@behavioroptions#1{% - \def\pgfplots@loc@TMPa{#1}% - \ifx\pgfplots@loc@TMPa\pgfutil@empty - \else - \expandafter\def\expandafter\pgfplots@addplot@nonlegend@options\expandafter{% - \pgfplots@addplot@nonlegend@options,#1}% - \pgfplotsset{#1}% - \fi + + +% This is a backwards-compatibility method to ensure that +% \axis[ybar] +% and +% \addplot[ybar] +% work as documented. +% +% The problem: earlier versions used /pgfplots/ybar for the global +% setting and /tikz/ybar for the local one. Now, both contexts yield +% /pgfplots/ybar in contradiction to the manual. +% +% So, this macro install special handlers to restore the old setting. +\def\pgfplots@install@local@bar@handlers{% + \pgfkeysgetvalue{/pgfplots/xbar/.@cmd}\pgfplotskeys@orig@xbar + \pgfkeysgetvalue{/pgfplots/ybar/.@cmd}\pgfplotskeys@orig@xbar + \pgfkeysgetvalue{/pgfplots/xbar interval/.@cmd}\pgfplotskeys@orig@xbari + \pgfkeysgetvalue{/pgfplots/ybar interval/.@cmd}\pgfplotskeys@orig@ybari + \pgfkeysdef{/pgfplots/xbar}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/xbar}% + \else + \pgfplotskeys@orig@xbar##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/ybar}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/ybar}% + \else + \pgfplotskeys@orig@ybar##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/xbar interval}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/xbar interval}% + \else + \pgfplotskeys@orig@xbari##1\pgfeov + \fi + }% + \pgfkeysdef{/pgfplots/ybar interval}{% + \ifpgfkeysaddeddefaultpath + \pgfkeysalso{/tikz/ybar interval}% + \else + \pgfplotskeys@orig@ybari##1\pgfeov + \fi + }% }% \def\pgfplots@end@plot{% @@ -2688,7 +5157,8 @@ \else \global\advance\pgfplots@numplots by1\relax% \fi - \pgfplots@execute@at@end@plot + \pgfkeysvalueof{/pgfplots/execute at end plot@@}% + \pgfkeysvalueof{/pgfplots/execute at end plot}% \endgroup%<-- close the \begingroup of \pgfplots@addplotimpl@plot@withoptions } @@ -2696,10 +5166,8 @@ \long\def\pgfplots@addplotimpl@coordinates#1#2plot coordinates#3#4;{\pgfplots@addplotimpl@coordinates@{#1}{#2}{#3}{#4}}% % \addplot[#1] [#2] coordinates {#3} #4; \long\def\pgfplots@addplotimpl@coordinates@#1#2#3#4{% -%\tracingmacros=2\tracingcommands=2 -%\pgfplots@message{processing plots coords with trailing path '#4'}% - \pgfplots@start@plot@with@behavioroptions{#2}% - \pgfplots@PREPARE@COORD@STREAM{#1}{#4}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% + \pgfplots@PREPARE@COORD@STREAM{#4}% \ifpgfplots@curplot@threedim \pgfplots@coord@stream@foreach@threedim{#3}% \else @@ -2785,11 +5253,26 @@ \def\pgfplots@invoke@filter#1#2{% \pgfkeysvalueof{/pgfplots/#2 filter/.@cmd}#1\pgfeov% }% +\def\pgfplots@invoke@filter@xyz{% + \pgfkeysgetvalue{/pgfplots/filter point/.@cmd}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key + \else + \pgfkeyslet{/data point/x}\pgfplots@current@point@x + \pgfkeyslet{/data point/y}\pgfplots@current@point@y + \pgfkeyslet{/data point/z}\pgfplots@current@point@z + \pgfplots@loc@TMPa\pgfeov% + \pgfkeysgetvalue{/data point/x}\pgfplots@current@point@x + \pgfkeysgetvalue{/data point/y}\pgfplots@current@point@y + \pgfkeysgetvalue{/data point/z}\pgfplots@current@point@z + \fi% +}% % this is a convenience macro to save storage in the long coordinate % lists. \def\pgfplots@stream#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} +\def\pgfplots@stream@#1#2#3{\def\pgfplots@current@point@coordindex{#1}\pgfplots@stream{#2}{#3}} \def\pgfplots@stream@withmeta#1#2#3{\def\pgfplots@current@point@meta{#3}\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} +\def\pgfplots@stream@withmeta@#1#2#3#4{\def\pgfplots@current@point@coordindex{#1}\pgfplots@stream@withmeta{#2}{#3}{#4}} \newif\ifpgfplots@record@marker@stream % Takes a sequence of PREPARED coordinates which are given in floating @@ -2808,17 +5291,21 @@ % Init the plot handlers: \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% + \def\pgfplots@loc@TMPa{0}% <-- if (collectmark positions) \ifpgfplots@scatterplotenabled - \ifx\tikz@plot@mark\pgfutil@empty - \pgfplots@warning{I am confused: A scatter plot with 'mark=none'? This may need attention...?}% - \fi + \def\pgfplots@loc@TMPa{1}% collect mark positions even if 'mark=none'! scatter might not even use markers. \fi - % \ifx\tikz@plot@mark\pgfutil@empty + \else + \def\pgfplots@loc@TMPa{1}% + \fi + % + \if\pgfplots@loc@TMPa0% % mark=none : no need to waste time collecting marker % positions. \pgfplots@record@marker@streamfalse \else + % we need markers. \ifx\pgfplots@basiclevel@plothandler\pgfplothandlerdiscard \ifpgfplots@clip@marker@paths % only marks: draw markers directly; no need for the @@ -2855,14 +5342,7 @@ \pgfplotsapplistXXpushback{\pgfplotstreamstart}% %\gdef#1{\pgfplotstreamstart}% \fi - % Define \pgfplots@process@perpointmeta properly: - \ifnum\pgfplots@perpointmeta@choice=0 - % disabled. - \def\pgfplots@process@perpointmeta{% - \let\pgfplots@current@point@meta=\pgfutil@empty - }% - \else - \fi + \c@pgfplots@coordindex=0 }% \def\pgfplots@coord@stream@end@{% \ifpgfplots@apply@datatrafo @@ -2886,16 +5366,17 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pgfplots@coord@stream@INIT@finalize@storedcoords@prepare@scaletrafomacro % - % Will be inserted in one of two possible places below: - \def\pgfplots@loc@TMPa{% - \ifnum\pgfplots@perpointmeta@choice=0 + % Will be inserted in one of two possible places below (to collect + % marker positions) + \def\pgfplots@visualize@performserizalization{% + \ifx\pgfplotspointmetainputhandler\pgfutil@empty % we don't have per-point meta data. Nothing special to % do: - \E\edef\E\pgfmathresult{\E\noexpand\E\pgfplots@stream{\E\the\E\pgf@x}{\E\the\E\pgf@y}}% + \E\edef\E\pgfmathresult{\E\noexpand\E\pgfplots@stream@{\E\the\E\c@pgfplots@coordindex}{\E\the\E\pgf@x}{\E\the\E\pgf@y}}% \E\expandafter\E\pgfplotsapplistXXpushback\E\expandafter{\E\pgfmathresult}% \else % Ok, then we need to process the meta data as well: - \E\edef\E\pgfmathresult{\E\noexpand\E\pgfplots@stream@withmeta{\E\the\E\pgf@x}{\E\the\E\pgf@y}{\E\pgfplots@current@point@meta}}% + \E\edef\E\pgfmathresult{\E\noexpand\E\pgfplots@stream@withmeta@{\E\the\E\c@pgfplots@coordindex}{\E\the\E\pgf@x}{\E\the\E\pgf@y}{\E\pgfplots@current@point@meta}}% \E\expandafter\E\pgfplotsapplistXXpushback\E\expandafter{\E\pgfmathresult}% \fi }% @@ -2934,11 +5415,11 @@ \E\else \E\ifdim\E\pgf@yb>\E\pgfplots@zmax@reg \E\else - \pgfplots@loc@TMPa + \pgfplots@visualize@performserizalization \E\fi \E\fi \else - \pgfplots@loc@TMPa + \pgfplots@visualize@performserizalization \fi \E\fi \E\fi @@ -2946,6 +5427,7 @@ \E\fi \fi \E\pgfplotstreampoint{}% it will simply take \pgf@x and \pgf@y! + \advance\c@pgfplots@coordindex by1 }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endgroup @@ -2962,9 +5444,24 @@ \pgfplots@coord@stream@finalize@currentpt }% \fi + \if\pgfplots@unbounded@handler j% unbounded coords=jump + \t@pgfplots@tokb=\expandafter{\pgfplots@coord@stream@coord@}% + \edef\pgfplots@coord@stream@coord@{% + \noexpand\ifx\noexpand\pgfplots@current@point@x\noexpand\pgfutil@empty + \noexpand\pgfplots@plothandler@unbounded@visualize@jump + \noexpand\else + \the\t@pgfplots@tokb + \noexpand\fi + }% + \fi % } +\def\pgfplots@plothandler@unbounded@visualize@jump{% + \pgfplotstreamend + \pgfplotstreamstart +}% + % Defines an optimized and matching \pgfplots@apply@data@scaletrafo@to@one@point % during the coordinate finalization step in \end{axis}. \def\pgfplots@coord@stream@INIT@finalize@storedcoords@prepare@scaletrafomacro{% @@ -2997,7 +5494,7 @@ % arithmetics are applied. \E\pgfplots@stacked@getnextzerolevelpoint \E\pgfplots@stacked@finishpoint% - \E\pgfplots@stacked@rememberzerolevelpoint@for@next@plot{(\E\pgfplots@current@point@x,\E\pgfplots@current@point@y)}% + \E\pgfplots@stacked@rememberzerolevelpoint@for@next@plot{(\E\pgfplots@current@point@x,\E\pgfplots@current@point@y\ifpgfplots@threedim,\E\pgfplots@current@point@z\fi)}% \fi % \t@pgfplots@tokc=\expandafter{\pgfplots@data@scaletrafo@result}% % \edef\pgfplots@data@scaletrafo@result{\the\t@pgfplots@tokc(\pgfplots@current@point@x,\pgfplots@current@point@y)}% @@ -3008,15 +5505,23 @@ \def\pgfplots@addplot@get@named@startendpoints@command#1{% \ifpgfplots@coord@stream@isfirst - \edef#1{% - \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfqpoint{\pgfplots@ZERO@x}{\pgfplots@ZERO@y}}% - \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfqpoint{\pgfplots@ZERO@x}{\pgfplots@ZERO@y}}% + % empty plot. + \def#1{% + \pgfcoordinate{current plot begin}{\pgfplotspointaxisorigin}% + \pgfcoordinate{current plot end}{\pgfplotspointaxisorigin}% }% \else - \edef#1{% - \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@firstcoord@x}{\pgfplots@currentplot@firstcoord@y}}% - \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@lastcoord@x}{\pgfplots@currentplot@lastcoord@y}}% - }% + \ifpgfplots@curplot@threedim + \edef#1{% + \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfplotsqpointxyz{\pgfplots@currentplot@firstcoord@x}{\pgfplots@currentplot@firstcoord@y}{\pgfplots@currentplot@firstcoord@z}}% + \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfplotsqpointxyz{\pgfplots@currentplot@lastcoord@x}{\pgfplots@currentplot@lastcoord@y}{\pgfplots@currentplot@lastcoord@z}}% + }% + \else + \edef#1{% + \noexpand\pgfcoordinate{current plot begin}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@firstcoord@x}{\pgfplots@currentplot@firstcoord@y}}% + \noexpand\pgfcoordinate{current plot end}{\noexpand\pgfplotsqpointxy{\pgfplots@currentplot@lastcoord@x}{\pgfplots@currentplot@lastcoord@y}}% + }% + \fi \fi }% @@ -3025,12 +5530,19 @@ % state of the \ifpgfplots@apply@datatrafo boolean) % \long\def\pgfplots@coord@stream@finalize@storedcoords@START normalized coordinates #1#2;\pgfplots@EOI{% + \ifpgfplots@threedim + \pgfplots@apply@zbuffer{#1}% + \let\pgfplots@coord@stream@finalize@storedcoords@START@coords=\pgfplotsglobalretval + \global\let\pgfplotsglobalretval=\relax + \else + \def\pgfplots@coord@stream@finalize@storedcoords@START@coords{#1}% + \fi \pgfplots@assert@tikzinternal@exists{tikz@make@last@position}% - \pgfplots@stored@current@cmd[current plot style] + \pgfplots@stored@current@cmd%[current plot style] <--- options are already set \pgfextra \tikzset{every plot/.try}% \pgfplots@coord@stream@INIT@finalize@storedcoords\pgfplots@recorded@marker@stream% - \pgfplots@coord@stream@foreach@NORMALIZED{#1}% + \expandafter\pgfplots@coord@stream@foreach@NORMALIZED\expandafter{\pgfplots@coord@stream@finalize@storedcoords@START@coords}% \pgfutil@ifundefined{pgfplotlastpoint}{}{% \tikz@make@last@position{\pgfplotlastpoint}% }% @@ -3041,8 +5553,7 @@ \ifpgfplots@clip@marker@paths % Draw markers on top of the plot lines: % - % FIXME: inefficient! Use \scope to set variables of 'current plot style' !? - \pgfplots@stored@current@cmd[current plot style] + \pgfplots@stored@current@cmd%[current plot style] <--- options are already set \pgfextra \pgfplots@install@plotmark@handler \pgfplots@recorded@marker@stream @@ -3077,12 +5588,7 @@ % \noexpand\xdef\noexpand\pgfplots@metamin{\pgfplots@metamin}% \noexpand\xdef\noexpand\pgfplots@metamax{\pgfplots@metamax}% - \ifpgfplots@perpointmeta@usesfloat - \noexpand\pgfplots@perpointmeta@usesfloattrue - \else - \noexpand\pgfplots@perpointmeta@usesfloatfalse - \fi - \noexpand\def\noexpand\pgfplots@perpointmeta@choice{\pgfplots@perpointmeta@choice}% + \noexpand\def\noexpand\pgfplotspointmetainputhandler{\pgfplotspointmetainputhandler}% % \the\t@pgfplots@tokb \noexpand\pgfextra @@ -3097,8 +5603,6 @@ }% \def\pgfplots@install@plotmark@handler{% - \pgfplots@assert@tikzinternal@exists{tikz@options}% - \pgfplots@assert@tikzinternal@exists{tikz@mode}% % note: I can't check on tikz@transform because it can be '\relax'. \pgfplots@gettikzinternal@keyval{mark indices}{tikz@mark@list}{}% \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% @@ -3148,20 +5652,9 @@ % the docs for details). % % Prepare arguments for '@pre/@post' macros: - \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% - \edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}% \t@pgfplots@toka={% \begingroup - \pgfutil@ifundefined{pgfplots@current@point@meta}{% - \pgfplots@error{'scatter' could not access its data source. Maybe you need to add '\string\addplot\space plot[scatter src=y]' or something like that?}% - \pgfmathfloatcreate{1}{1.0}{0}% - \def\pgfplotspointmetatransformed{1.0}% - }{% - % prepare arguments: - \let\pgfplotspointmeta=\pgfplots@current@point@meta - \pgfplots@perpointmeta@trafo{\pgfplotspointmeta}% - \let\pgfplotspointmetatransformed=\pgfmathresult - }% + \pgfplots@perpointmeta@trafo@APPLY \pgfkeysvalueof{/pgfplots/scatter/@pre marker code/.@cmd}\pgfeov }% \t@pgfplots@tokb=\expandafter{\pgfplots@loc@TMPa}% @@ -3217,186 +5710,53 @@ \def\pgfplots@loc@TMPb{\pgfkeysvalueof{/pgfplots/error bars/draw error bar/.@cmd}}% \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\pgfeov } +\def\pgfplots@errorbar@draw@float@threedim(#1,#2,#3)(#4,#5,#6){% + \ifpgfplots@apply@datatrafo@x + \pgfplots@datascaletrafo@x{#1}% + \let\pgfplots@xarg=\pgfmathresult% + \pgfplots@datascaletrafo@x{#4}% + \let\pgfplots@error@xarg=\pgfmathresult% + \else + \def\pgfplots@xarg{#1}% + \def\pgfplots@error@xarg{#4}% + \fi + \ifpgfplots@apply@datatrafo@y + \pgfplots@datascaletrafo@y{#2}% + \let\pgfplots@yarg=\pgfmathresult% + \pgfplots@datascaletrafo@y{#5}% + \let\pgfplots@error@yarg=\pgfmathresult% + \else + \def\pgfplots@yarg{#2}% + \def\pgfplots@error@yarg{#5}% + \fi + \ifpgfplots@apply@datatrafo@z + \pgfplots@datascaletrafo@z{#3}% + \let\pgfplots@zarg=\pgfmathresult% + \pgfplots@datascaletrafo@z{#6}% + \let\pgfplots@error@zarg=\pgfmathresult% + \else + \def\pgfplots@zarg{#3}% + \def\pgfplots@error@zarg{#6}% + \fi + \edef\pgfplots@loc@TMPa{{(\pgfplots@xarg,\pgfplots@yarg,\pgfplots@zarg)}{(\pgfplots@error@xarg,\pgfplots@error@yarg,\pgfplots@error@zarg)}}% + \def\pgfplots@loc@TMPb{\pgfkeysvalueof{/pgfplots/error bars/draw error bar/.@cmd}}% + \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\pgfeov +} \def\pgfplots@errorbar@draw#1#2{% \begingroup \ifpgfplots@apply@datatrafo - \pgfplots@errorbar@draw@float#1#2 + \ifpgfplots@curplot@threedim + \pgfplots@errorbar@draw@float@threedim#1#2% + \else + \pgfplots@errorbar@draw@float#1#2% + \fi \else \pgfkeysvalueof{/pgfplots/error bars/draw error bar/.@cmd}{#1}{#2}\pgfeov% \fi \endgroup }% -% Arguments: -% \pgfplots@current@point@[xyz] -% \pgfplots@current@point@[xyz]@unfiltered -% \pgfplots@current@point@[xyz]@error (if in argument list) -% Also provides UNFILTERED arguments x and y . These are use -% in case of logplots, because we may need to compute log( x + e_x ) -% or log( y + e_y ). -\def\pgfplots@process@errorbar@for{% -% \begingroup - \edef\pgfplots@xarg{\pgfplots@current@point@x}% - \edef\pgfplots@yarg{\pgfplots@current@point@y}% - \let\pgfplots@xarg@unfiltered\pgfplots@current@point@x@unfiltered% - \let\pgfplots@yarg@unfiltered\pgfplots@current@point@y@unfiltered% - \edef\pgfplots@error@xarg{\pgfplots@current@point@x@error}% - \edef\pgfplots@error@yarg{\pgfplots@current@point@y@error}% - \def\pgfplots@loc@TMPa{0}% - \ifx\pgfplots@loc@TMPa\pgfplots@error@xarg - \let\pgfplots@error@xarg=\pgfutil@empty - \fi - \ifx\pgfplots@loc@TMPa\pgfplots@error@yarg - \let\pgfplots@error@yarg=\pgfutil@empty - \fi - % FIXME : INEFFICIENT! This code here does every computation - % multiple times! - \ifcase\pgfplots@errorbars@xdirection - \or - \pgfplots@process@errorbar@@for{x}{+}1% - \or - \pgfplots@process@errorbar@@for{x}{-}2% - \or - \pgfplots@process@errorbar@@for{x}{+}1% - \pgfplots@process@errorbar@@for{x}{-}2% - \fi - \ifcase\pgfplots@errorbars@ydirection - \or - \pgfplots@process@errorbar@@for{y}{+}1% - \or - \pgfplots@process@errorbar@@for{y}{-}2% - \or - \pgfplots@process@errorbar@@for{y}{+}1% - \pgfplots@process@errorbar@@for{y}{-}2% - \fi - % Restore macros which may have been overwritten: - \let\pgfplots@current@point@x=\pgfplots@xarg - \let\pgfplots@current@point@y=\pgfplots@yarg -% \endgroup -} - -% #1: either 'x' or 'y' -% #2: either '+' or '-' -% #3: an integer representing the argument #2. It is '1' if #2='+' -% and '2' is #2 = '-'. -\def\pgfplots@process@errorbar@@for#1#2#3{% - \csname ifpgfplots@#1islinear\endcsname - \edef\pgfplots@error@src{\csname pgfplots@#1arg\endcsname}% - \ifcase\csname pgfplots@errorbars@#1mode\endcsname - % fixed absolute error. - \edef\pgfplots@error@coord{\csname pgfplots@errorbars@#1fixed\endcsname}% - \pgfmathfloatparsenumber{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \ifnum#3=1 - \pgfmathfloatadd@{\pgfplots@error@src}{\pgfplots@error@coord}% - \else - \pgfmathfloatsubtract@{\pgfplots@error@src}{\pgfplots@error@coord}% - \fi - \let\pgfplots@error@coord=\pgfmathresult - \or% fixed relative error: - \pgfmathparse{(1#2\csname pgfplots@errorbars@#1rel\endcsname)}% - \let\pgfplots@error@coord=\pgfmathresult - \pgfmathfloatmultiplyfixed@{\pgfplots@error@src}{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \or% explicit absolute: - \edef\pgfplots@error@coord{\csname pgfplots@error@#1arg\endcsname}% - \ifx\pgfplots@error@coord\pgfutil@empty - \else - \pgfmathfloatparsenumber{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \ifnum#3=1 - \pgfmathfloatadd@{\pgfplots@error@src}{\pgfplots@error@coord}% - \else - \pgfmathfloatsubtract@{\pgfplots@error@src}{\pgfplots@error@coord}% - \fi - \let\pgfplots@error@coord=\pgfmathresult - \fi - \or% explicit relative: - \edef\pgfplots@error@coord{\csname pgfplots@error@#1arg\endcsname}% - \ifx\pgfplots@error@coord\pgfutil@empty - \else - \pgfmathparse{(1#2\pgfplots@error@coord)}% - \let\pgfplots@error@coord=\pgfmathresult - \pgfmathfloatmultiplyfixed@{\pgfplots@error@src}{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \fi - \fi - \else - % LOGARITHMIC scaling. All errors are interpreted as - % log(x +- e_x) - % or - % log( x*(1+-e_x) ) - \ifcase\csname pgfplots@errorbars@#1mode\endcsname - % fixed absolute, log( x +- e_x ) - \edef\pgfplots@error@src{\csname pgfplots@#1arg@unfiltered\endcsname}% - \edef\pgfplots@error@coord{\csname pgfplots@errorbars@#1fixed\endcsname}% - \pgfmathfloatparsenumber{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \pgfmathfloatparsenumber{\pgfplots@error@src}% - \let\pgfplots@error@src=\pgfmathresult - \ifnum#3=1 - \pgfmathfloatadd@{\pgfplots@error@src}{\pgfplots@error@coord}% - \else - \pgfmathfloatsubtract@{\pgfplots@error@src}{\pgfplots@error@coord}% - \fi - \pgfmathlog@float{\pgfmathresult}% - \let\pgfplots@error@coord=\pgfmathresult - \or% fixed relative, log( x ( 1+-e_x ) ) = log(x) + log(1+-e_x) - \edef\pgfplots@error@src{\csname pgfplots@#1arg\endcsname}% - \pgfmathparse{\pgfplots@error@src + ln(1#2\csname pgfplots@errorbars@#1rel\endcsname)}% - \let\pgfplots@error@coord=\pgfmathresult% - \or% explicit absolute - \edef\pgfplots@error@src{\csname pgfplots@#1arg@unfiltered\endcsname}% - \edef\pgfplots@error@coord{\csname pgfplots@error@#1arg\endcsname}% - \ifx\pgfplots@error@coord\pgfutil@empty - \else - \pgfmathfloatparsenumber{\pgfplots@error@coord}% - \let\pgfplots@error@coord=\pgfmathresult - \pgfmathfloatparsenumber{\pgfplots@error@src}% - \let\pgfplots@error@src=\pgfmathresult - \ifnum#3=1 - \pgfmathfloatadd@{\pgfplots@error@src}{\pgfplots@error@coord}% - \else - \pgfmathfloatsubtract@{\pgfplots@error@src}{\pgfplots@error@coord}% - \fi - \pgfmathlog@float{\pgfmathresult}% - \let\pgfplots@error@coord=\pgfmathresult - \fi - \or% explicit relative: - \edef\pgfplots@error@src{\csname pgfplots@#1arg\endcsname}% - \edef\pgfplots@error@coord{\csname pgfplots@error@#1arg\endcsname}% - \ifx\pgfplots@error@coord\pgfutil@empty - \else - \pgfmathparse{\pgfplots@error@src + ln(1#2 \pgfplots@error@coord)}% - \let\pgfplots@error@coord=\pgfmathresult% - \fi - \fi - \fi - \ifx\pgfplots@error@coord\pgfutil@empty - \else - \def\pgfplots@loc@TMPa{#1}% - \def\pgfplots@loc@TMPb{x}% - \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb - \let\pgfplots@current@point@x=\pgfplots@error@coord - \let\pgfplots@current@point@y=\pgfplots@yarg - \pgfplots@update@limits@for@one@point - \edef\pgfplots@loc@TMPa{% - {(\pgfplots@xarg,\pgfplots@yarg)}% - {(\pgfplots@error@coord,\pgfplots@yarg)}% - }% - \else - \let\pgfplots@current@point@x=\pgfplots@xarg - \let\pgfplots@current@point@y=\pgfplots@error@coord - \pgfplots@update@limits@for@one@point - \edef\pgfplots@loc@TMPa{% - {(\pgfplots@xarg,\pgfplots@yarg)}% - {(\pgfplots@xarg,\pgfplots@error@coord)}% - }% - \fi - \expandafter\pgfplots@streamerrorbarcoords\pgfplots@loc@TMPa - \fi -} % This routine is called at the begin of every plot. % It initialises a zero level stream. % @@ -3416,8 +5776,9 @@ % coordinates. \pgfplots@stacked@initzerolevelhandler \else - \pgfplotxzerolevelstreamconstant{\pgfplots@ZERO@x}% - \pgfplotyzerolevelstreamconstant{\pgfplots@ZERO@y}% + \pgfplotspointaxisorigin + \expandafter\pgfplotxzerolevelstreamconstant\expandafter{\the\pgf@x}% + \expandafter\pgfplotyzerolevelstreamconstant\expandafter{\the\pgf@y}% \fi } @@ -3430,26 +5791,32 @@ \def\pgfplots@prepare@ZERO@coordinates{% \ifpgfplots@xislinear \ifpgfplots@apply@datatrafo@x - \pgfplots@datascaletrafo@fromfixed@x{0}% + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfplots@datascaletrafo@x{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@x{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@x}{\pgfplots@xmin}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@x}{\pgfplots@xmax}% + \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@x=\pgfplots@xmin% \fi % \ifpgfplots@yislinear \ifpgfplots@apply@datatrafo@y - \pgfplots@datascaletrafo@fromfixed@y{0}% + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfplots@datascaletrafo@y{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@y{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@y}{\pgfplots@ymin}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@y}{\pgfplots@ymax}% + \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@y=\pgfplots@ymin% \fi @@ -3457,20 +5824,22 @@ \ifpgfplots@threedim \ifpgfplots@zislinear \ifpgfplots@apply@datatrafo@z - \pgfplots@datascaletrafo@fromfixed@z{0}% + \pgfmathfloatcreate{0}{0.0}{0}% + \pgfplots@datascaletrafo@z{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@z{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@z}{\pgfplots@zmin}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult + \pgfplotsmathmin{\pgfplots@logical@ZERO@z}{\pgfplots@zmax}% + \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@z=\pgfplots@zmin% \fi \fi % % - \pgfinterruptboundingbox% \ifpgfplots@threedim \pgfplotsqpointxyz{\pgfplots@logical@ZERO@x}{\pgfplots@logical@ZERO@y}{\pgfplots@logical@ZERO@z}% \else @@ -3478,11 +5847,15 @@ \fi \xdef\pgfplots@ZERO@x{\the\pgf@x}% \xdef\pgfplots@ZERO@y{\the\pgf@y}% - \endpgfinterruptboundingbox% + \xdef\pgfplotspointaxisorigin{\noexpand\pgf@x=\pgfplots@ZERO@x\space\noexpand\pgf@y=\pgfplots@ZERO@y\space}% }% +% the low-level Tikz command which realizes 'plot graphics'. +% +% It's current state is described by some pgfkeys options and two +% coordinates. \def\pgfplotsplothandlergraphics{% \def\pgf@plotstreamstart{% \global\let\pgfplots@plot@handler@graphics@bb@first=\pgfutil@empty @@ -3490,6 +5863,9 @@ \global\let\pgf@plotstreampoint=\pgfplots@plot@handler@graphics@collectbb% \global\let\pgf@plotstreamspecial=\pgfutil@gobble% \global\let\pgf@plotstreamend=\pgfplots@plot@handler@graphics@finish% + \def\pgfplots@plothandler@unbounded@visualize@jump{% + \pgfplots@error{Sorry, plot graphics does not support 'unbounded coords=jump'.}% + }% }% }% \def\pgfplots@plot@handler@graphics@collectbb#1{% @@ -3516,20 +5892,1145 @@ \pgfplots@error{Error using 'plot graphics': I got too few coordinates! I expected the lower left and upper right corners!}% \xdef\pgfplots@plot@handler@graphics@bb@second{\noexpand\pgfqpoint{0pt}{0pt}}% \fi - \pgfpointdiff{\pgfplots@plot@handler@graphics@bb@first}{\pgfplots@plot@handler@graphics@bb@second}% - \edef\pgfplots@loc@TMPa{\the\pgf@x}% width - \edef\pgfplots@loc@TMPb{\the\pgf@y}% height + \begingroup + % determine the lower left / upper right corners. + \pgfplots@plot@handler@graphics@bb@first + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgfplots@plot@handler@graphics@bb@second + \pgf@xb=\pgf@x + \pgf@yb=\pgf@y + % + % xc,yc = lower left corner + % x,y = upper right + \ifdim\pgf@xa<\pgf@xb + \pgf@xc=\pgf@xa + \pgf@x=\pgf@xb + \else + \pgf@xc=\pgf@xb + \pgf@x=\pgf@xa + \fi + \ifdim\pgf@ya<\pgf@yb + \pgf@yc=\pgf@ya + \pgf@y=\pgf@yb + \else + \pgf@yc=\pgf@yb + \pgf@y=\pgf@ya + \fi + \advance\pgf@x by-\pgf@xc + \advance\pgf@y by-\pgf@yc + \edef\pgfplots@plot@handler@graphics@DRAW@{% + \noexpand\pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{% + {\the\pgf@x}% width + {\the\pgf@y}% height + }% + }% + \pgf@x=\pgf@xc + \pgf@y=\pgf@yc + \pgftransformshift{}% + \node[/pgfplots/plot graphics/node] {% + \pgfplots@plot@handler@graphics@DRAW@ + };% + \endgroup +}% +% initial value for /pgfplots/plots graphics/lowlevel draw: +\def\pgfplots@plot@handler@graphics@DRAW#1#2{% \pgfkeysgetvalue{/pgfplots/plot graphics/includegraphics}{\pgfplots@loc@TMPc}% \pgfkeysgetvalue{/pgfplots/plot graphics/src}{\pgfplots@loc@TMPd}% \ifx\pgfplots@loc@TMPd\pgfutil@empty \pgfplots@error{Error using 'plot graphics': I don't have a graphics file name! Please set the '/pgfplots/plot graphics/src' key to the image file name. Skipping this plot.}% \else + \expandafter\includegraphics\expandafter[\pgfplots@loc@TMPc,width=#1,height=#2]{\pgfplots@loc@TMPd}% + \fi +}% + + + +% The low-level tikz plot handler for 3D mesh and surface plots. +% +% It expects +% a) a coordinate stream which is a linearized matrix, iterated either +% rowwise or column wise, +% b) the current set of options in /pgfplots/mesh/. +% +% +% ATTENTION: +% this handler is NOT as general as the others. In particular, it +% can't be interrupted by TeX groups: every single statement, +% starting with streamstart and ending with stream end, must be in +% the same scope! +% +% As a consequence, you can't use this handler inside of (all) TikZ +% input streams. Try it out. It will work in pgfplots, however. +% +% Furthermore, it relies on a couple of pgfplots macros. This may +% change in future versions. +% It relies on: +% - \ifpgfplots@curplot@threedim +% - \pgfplots@current@point@meta +% -> it also invokes \pgfplots@perpointmeta@preparetrafo and its +% @APPLY counterpart which checks for +% - \pgfplots@metamax +% If you use it outside of pgfplots, use +% \global\let\pgfplots@metamax=\pgfutil@empty +% This is can be used without an initialised +% pgfplots axes - as long as \pgfplots@current@point@meta is in +% the range [0,1000]. +% - for the case 'shader=interp', a bounding box must be established +% before the plot is finished. This must be done using +% \def\pgfplotspointbbupperright{\pgfqpointxyz{2}{2}{0.9}} +% \def\pgfplotspointbblowerleft {\pgfqpointxyz{0}{0}{0.1}} +% or something like that. +% +% Besides these internals, it also relies on all public /pgfplots +% configuration keys related to mesh/surface plots. +% +% Please note that the 'z buffer' feature will not work without +% pgfplots (especially the z buffer=sort feature). +% +% Here is an example which compiles without a pgfplots axes: +% ---------------------------------------------------------- +% \begin{tikzpicture} +% \scope[ +% /pgfplots/.cd, +% surf, +% shader=faceted, +% mesh/rows=4, +% mesh/cols=4, +% mesh/num points=, +% /tikz/x={(0.44237cm,-0.07439cm)}, +% /tikz/y={(0.30942cm,0.23932cm)}, +% /tikz/z={(0.0cm,1.5cm)}, +% ] +% \makeatletter +% +% \global\let\pgfplots@metamax=\pgfutil@empty +% \pgfplots@curplot@threedimtrue +% +% \pgfplotsplothandlermesh +% \pgfplotstreamstart +% +% \def\rangea{0.21}% +% \def\rangeb{0.9}% +% +% \pgfmathparse{1000/(\rangeb-\rangea)} +% \let\factor=\pgfmathresult +% +% \def\simplecoordinate(#1,#2,#3){% +% \pgfmathparse{\factor*(#3 - \rangea)}% +% \let\pgfplots@current@point@meta=\pgfmathresult +% \pgfplotstreampoint{\pgfqpointxyz{#1}{#2}{#3}}% +% }% +% % for the case 'shaer=interp': +% \def\pgfplotspointbbupperright{\pgfqpointxyz{2}{2}{0.9}} +% \def\pgfplotspointbblowerleft {\pgfqpointxyz{0}{0}{0.1}} +% +% \simplecoordinate(0,3,0.7) +% \simplecoordinate(1,3,0.5) +% \simplecoordinate(2,3,0.58) +% \simplecoordinate(3,3,0.9) +% +% \simplecoordinate(0,2,0.68) +% \simplecoordinate(1,2,0.22) +% \simplecoordinate(2,2,0.25) +% \simplecoordinate(3,2,0.4) +% +% \simplecoordinate(0,1,0.6) +% \simplecoordinate(1,1,0.3) +% \simplecoordinate(2,1,0.21) +% \simplecoordinate(3,1,0.3) +% +% \simplecoordinate(0,0,0.8) +% \simplecoordinate(1,0,0.56) +% \simplecoordinate(2,0,0.5) +% \simplecoordinate(3,0,0.75) +% +% +% \pgfplotstreamend +% \pgfusepath{stroke} +% +% \endscope +% \end{tikzpicture} +% ---------------------------------------------------------- +% END OF EXAMPLE +% -> see also the legend image for mesh plots. +% +\def\pgfplotsplothandlermesh{% + \def\pgf@plotstreamstart{% +% \scope + \pgfplotsautocompletemeshkeys% + \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsplothandlermesh@rows + \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsplothandlermesh@cols + \pgfkeysgetvalue{/pgfplots/mesh/num points}\pgfplotsplothandlermesh@numpoints + % + \pgfutil@ifundefined{pgfplots@drawmodes}{% + \let\pgfplots@drawmodes=\tikz@mode + \let\pgfplots@drawoptions=\tikz@options + }{}% + % + \def\pgfplotsplothandlermesh@ONEDIMMODE{0}% + \ifnum\pgfplotsplothandlermesh@cols=1 + \def\pgfplotsplothandlermesh@ONEDIMMODE{1}% + \fi + \ifnum\pgfplotsplothandlermesh@rows=1 + \def\pgfplotsplothandlermesh@ONEDIMMODE{1}% + \fi + % + % + % Prepare color data source: + \ifx\pgfplotspointmetainputhandler\pgfutil@empty% + % oh. There is no color data!? Well... then use a constant + % color. + % + % This activates tikz colors: + %\tikz@options + \def\pgfplotsplothandlermesh@preparedrawforcurrent{% + \pgfplots@drawoptions + }% + \else + % Ok, we have color data. + % + % Prepare: + \pgfplots@perpointmeta@preparetrafo + \def\pgfplotsplothandlermesh@preparedrawforcurrent{% + \pgfplotscolormapdefinemappedcolor{\pgfplotsplothandlermesh@shader@cellcolor}% +% \pgfplotsplothandlermesh@setcolor{mapped color}% + % This activates tikz colors: +%\message{executing \meaning\pgfplots@drawoptions'}% + %\tikz@options + \pgfplots@drawoptions + }% + % + % Acquire the values for \tikz@mode@* [used for faceted] + \pgfplots@drawmodes + % + % Now, process the 'shader' key here: + \if\pgfplotsplothandlermesh@ONEDIMMODE1 + \def\pgfplots@meshmode{m}% 'mesh' + \fi + \if\pgfplots@meshmode m% mesh + % this is processed by the 'shader=flat' code below. + \def\pgfplotsplothandlermesh@shader{0}% 'flat' + \fi + \if\pgfplotsplothandlermesh@shader2% 'shader=interp' + \pgflibrarysurfshadingifactive + {}% + {% + \pgfutil@ifundefined{pgfplotsplothandlermesh@shader@warning}{% + \pgfplots@error{Sorry, surface shading (shader=interp) is NOT available for the selected driver `\pgfsysdriver'. I will use 'shader=flat' if you continue now}% + \gdef\pgfplotsplothandlermesh@shader@warning{x}% + }{}% + \def\pgfplotsplothandlermesh@shader{0}% + }% + \fi + \if\pgfplotsplothandlermesh@zbuffer@choice4% 'z buffer=sort': + \if\pgfplotsplothandlermesh@shader2% 'shader=interp' + \pgfplots@error{Sorry, 'shader=interp' does not support 'z buffer=sort'. If you continue now, 'shader=flat' will be used.}% + \def\pgfplotsplothandlermesh@shader{0}% 'flat' + \fi + \fi + \ifnum\pgfplotsplothandlermesh@shader<2 + % 0 == 'flat' + % 1 == 'faceted' + \if\pgfplotsplothandlermesh@flatmode c% 'flat corner': + % + % use colordata of ONE corner point. That's easy, not + % much to do. + \let\pgfplotsplothandlermesh@unpack=\pgfplotsplothandlermesh@unpack@corner + \t@pgfplots@toka=\expandafter{\pgfplotsplothandlermesh@preparedrawforcurrent}% + \t@pgfplots@tokb={% + \pgfplots@perpointmeta@trafo@APPLY + \let\pgfplotsplothandlermesh@shader@cellcolor=\pgfplotspointmetatransformed}% + \edef\pgfplotsplothandlermesh@preparedrawforcurrent{% + \the\t@pgfplots@tokb + \the\t@pgfplots@toka + }% + \else + % 'flat mean': + % + % use colordata as mean of all corners for shading. + \let\pgfplotsplothandlermesh@unpack=\pgfplotsplothandlermesh@unpack@mean@accum + \global\pgfplots@tmpa=0pt + \t@pgfplots@toka=\expandafter{\pgfplotsplothandlermesh@preparedrawforcurrent}% + \if\pgfplotsplothandlermesh@ONEDIMMODE0 + \t@pgfplots@tokb={\global\divide\pgfplots@tmpa by4 }% + \else + \t@pgfplots@tokb={\global\divide\pgfplots@tmpa by2 }% + \fi + \t@pgfplots@tokc={% + \edef\pgfplotsplothandlermesh@shader@cellcolor{\pgf@sys@tonumber\pgfplots@tmpa}% + \global\pgfplots@tmpa=0pt }% + \edef\pgfplotsplothandlermesh@preparedrawforcurrent{% + \the\t@pgfplots@tokb + \the\t@pgfplots@tokc + \the\t@pgfplots@toka + }% + \fi + \if\pgfplots@meshmode m% + % 'mesh' plot: stroke only and use the 'flat' code + % here just to define the color for each mesh + % segment. + \let\pgfplotsplothandlermesh@usepath=\pgfusepathqstroke + \else + % 'surf' plot: + \let\pgfplotsplothandlermesh@usepath=\pgfusepathqfillstroke + % the distinction between 'faceted' and 'flat' is + % technical: it is just the default draw color. + % + % 'flat,draw=black' is the same as 'faceted'. + \if\pgfplotsplothandlermesh@shader1% faceted + % make sure there is a the correct color. + \expandafter\def\expandafter\pgfplots@drawoptions\expandafter{% + \pgfplots@drawoptions + \pgfsetstrokecolor{\pgfkeysvalueof{/pgfplots/faceted color}}% + }% + \fi + \fi + \else + % 'shader=2': 'interp': + % very simple: defer work to surf library. Only + % provide the mapped colordata. + % + % This won't be used for mesh plots, neither in one + % nor in two dimensions. + \pgfkeyssetvalue{/pgfplots/surf shading/north east corner}{\pgfplotspointbbupperright}% + \pgfkeyssetvalue{/pgfplots/surf shading/south west corner}{\pgfplotspointbblowerleft}% + \pgfkeyssetvalue{/pgfplots/surf shading/anchor}{\pgfpointorigin}% + \pgfkeysgetvalue{/pgfplots/colormap name}\pgfplots@loc@TMPa + \expandafter\pgfplotscolormaptopdffunction\expandafter{\pgfplots@loc@TMPa}% + \pgfkeyslet{/pgfplots/surf shading/colormap}\pgfplotsretval + \let\pgfplotsplothandlermesh@unpack=\relax % unused. + \let\pgfplotsplothandlermesh@preparedrawforcurrent=\relax + \pgfkeyslet{/pgfplots/surf shading/cols}\pgfplotsplothandlermesh@cols + \if\pgfplots@plot@mesh@ordering0% + % ordering=x varies: + \global\let\pgf@plotstreampoint=\pgfplotsplothandlermesh@shader@interp% + \else + % colwise: + % + % The low level shader NEEDS rowwise ordering. So, we need to transpose the data matrix. + % As usual in TeX, we should save macros as much as possible. I guess we NEED at least one macro for each matrix row. + % Idea: + % while we iterate colwise through the input data, accumulate row vectors. + % Then, process the row vectors. + % Since vectors are expensive (in terms of number of macros), we use fast "append" lists instead of vectors. + \global\let\pgf@plotstreampoint=\pgfplotsplothandlermesh@shader@interp@incremental@transpose% + % + % init all required row vectors: + \c@pgfplots@scanlineindex=0 + \pgfutil@loop + \ifnum\c@pgfplots@scanlineindex<\pgfplotsplothandlermesh@rows\relax + \expandafter\pgfplotsapplistXnewempty\csname pgfp@transprow@\the\c@pgfplots@scanlineindex\endcsname% + \advance\c@pgfplots@scanlineindex by1 + \pgfutil@repeat + %\pgfkeyslet{/pgfplots/surf shading/cols}\pgfplotsplothandlermesh@rows + %\pgfplots@error{Sorry, the 'shader=interp' does not yet support 'mesh/ordering=colwise'... You can continue now, but the plot will be transposed.}% + \fi + \pgfplotslibrarysurfstreamstart + \let\pgfplotsplothandlermesh@usepath=\pgfusepathqfill + \fi + \fi + % PREPARE THE STREAM PROCESSING: + \def\pgfplots@plothandler@unbounded@visualize@jump{% + \pgfplotstreampoint{\pgf@x=-16000.0pt \pgf@y=-16000.0pt }% + }% + \def\pgfplotsplothandlermesh@check@unbounded####1####2\relax{% + \ifdim####1=-16000pt + \pgfplots@loc@tmpfalse + \fi + }% + \if\pgfplotsplothandlermesh@ONEDIMMODE1% + % Special case: 1D mesh processing + \global\let\pgf@plotstreampoint=\pgfplotsplothandlermesh@ONEDIM@draw% + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotsplothandlermesh@finish% + \let\pgfplotsplothandlermesh@draw@element=\pgfplotsplothandlermesh@draw@element@line + \def\pgfplotsplothandlermesh@process@element{% + \pgfplotsplothandlermesh@draw@element + \pgfplotsplothandlermesh@i + \pgfplotsplothandlermesh@im + }% + \if\pgfplots@unbounded@handler j% + % unbounded coords=jump: + % append checks for unbounded coords to + % \pgfplotsplothandlermesh@process@element + \t@pgfplots@tokb={% + \pgfplots@loc@tmptrue + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@i\relax + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@im\relax + }% + \t@pgfplots@toka=\expandafter{\pgfplotsplothandlermesh@process@element}% + \edef\pgfplotsplothandlermesh@process@element{% + \the\t@pgfplots@tokb + \noexpand\ifpgfplots@loc@tmp + \the\t@pgfplots@toka + \noexpand\fi + }% + \fi + \if\pgfplotsplothandlermesh@zbuffer@choice4% + % z buffer=sort: + % create a z buffer: + % the z buffer contains elements {<view depth>}{{<pt1>}{<pt2>}{<pt3>}{<pt4>}} + \pgfplotsarraynewempty\pgfplots@zbuffer@local + % + % and collect each point into the z buffer: + \def\pgfplotsplothandlermesh@process@element{% + \pgfplotsmathviewdepthxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@current@point@z}% FIXME relies on pgfplots macros + % assemble array element: + \edef\pgfplots@loc@TMPa{% + {\pgfmathresult}% + {% + {\pgfplotsplothandlermesh@i}% + {\pgfplotsplothandlermesh@im}% + }% + }% + \expandafter\pgfplotsarraypushback\pgfplots@loc@TMPa\to\pgfplots@zbuffer@local + }% + \fi + \else + % ok, normal 2D mesh processing: + % + % And now finally: initialise the conversion from + % LINEARIZED COORD STREAM -> DATA MATRIX: + \if\pgfplots@plot@mesh@ordering0% + % x varies (=rowwise): + \let\pgfplotsplothandlermesh@scanlinelength=\pgfplotsplothandlermesh@cols + \else + % y varies (=colwise): + \let\pgfplotsplothandlermesh@scanlinelength=\pgfplotsplothandlermesh@rows + \fi + \def\pgfplotsplothandlermesh@process@element{% + \pgfplotsplothandlermesh@draw@element + \pgfplotsplothandlermesh@im@jm + \pgfplotsplothandlermesh@im@j + \pgfplotsplothandlermesh@i@j + \pgfplotsplothandlermesh@i@jm + }% + % Init memory: + \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@scanlinelength\relax + \advance\c@pgfplots@scanlineindex by1 + \pgfplotsdequenewempty{lastscanline}\capacity{\the\c@pgfplots@scanlineindex}% + % + \if2\pgfplotsplothandlermesh@shader + % shader=interp does not support z buffer=sort. + % It also has its own \pgf@plotstreampoint method, see + % above. + \def\pgfplots@plothandler@unbounded@visualize@jump{% + \pgfplots@error{Sorry, shader=interp does not support 'unbounded coords=jump'. Please use 'shader=flat' for this case.}% + }% + \else + \global\let\pgf@plotstreampoint=\pgfplotsplothandlermesh@fillscanline% + \if\pgfplotsplothandlermesh@zbuffer@choice4% + % z buffer=sort: + % create a z buffer: + % the z buffer contains elements {<view depth>}{{<pt1>}{<pt2>}{<pt3>}{<pt4>}} + \pgfplotsarraynewempty\pgfplots@zbuffer@local + % + % and collect each point into the z buffer + % (instead of drawing it): + \def\pgfplotsplothandlermesh@process@element{% + \pgfplotsmathviewdepthxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@current@point@z}% FIXME relies on pgfplots macros + % assemble array element: + \edef\pgfplots@loc@TMPa{% + {\pgfmathresult}% + {% + {\pgfplotsplothandlermesh@im@jm}% + {\pgfplotsplothandlermesh@im@j}% + {\pgfplotsplothandlermesh@i@j}% + {\pgfplotsplothandlermesh@i@jm}% + }% + }% + \expandafter\pgfplotsarraypushback\pgfplots@loc@TMPa\to\pgfplots@zbuffer@local + }% + \fi + \if\pgfplots@unbounded@handler j% + % unbounded coords=jump: + % append checks for unbounded coords to + % \pgfplotsplothandlermesh@process@element + \t@pgfplots@tokb={% + \pgfplots@loc@tmptrue + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@i@j\relax + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@i@jm\relax + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@im@j\relax + \expandafter\pgfplotsplothandlermesh@check@unbounded\pgfplotsplothandlermesh@im@jm\relax + }% + \t@pgfplots@toka=\expandafter{\pgfplotsplothandlermesh@process@element}% + \edef\pgfplotsplothandlermesh@process@element{% + \the\t@pgfplots@tokb + \noexpand\ifpgfplots@loc@tmp + \the\t@pgfplots@toka + \noexpand\fi + }% + \fi + \fi + % + \global\let\pgf@plotstreamspecial=\pgfutil@gobble% + \global\let\pgf@plotstreamend=\pgfplotsplothandlermesh@finish% + \let\pgfplotsplothandlermesh@draw@element=\pgfplotsplothandlermesh@draw@element@rectangle + \fi + \c@pgfplots@scanlineindex=0 + }% +}% + +\long\def\pgfplotsplothandlermesh@defaultlegend@img#1{% + \scope[% + #1, + /pgfplots/mesh/rows=3, + /pgfplots/mesh/cols=3, + /pgfplots/mesh/num points=, + /tikz/x={(0.44237cm,-0.07439cm)}, + /tikz/y={(0.30942cm,0.23932cm)}, + /tikz/z={(0.0cm,1.5cm)}, + scale=0.4, + yshift=-0.7cm, + ] + \let\pgfplots@metamax=\pgfutil@empty + \pgfplots@curplot@threedimtrue + + \pgfplotsplothandlermesh + \pgfplotstreamstart + + \def\rangea{0.21}% + \def\rangeb{0.7}% + + \pgfmathparse{1000/(\rangeb-\rangea)} + \let\factor=\pgfmathresult + + \pgfutil@ifundefined{pgfqpointxyz@orig}{% + \let\pgfqpointxyz@orig=\pgfqpointxyz + }{}% + % + \def\simplecoordinate(##1,##2,##3){% + \pgfmathparse{\factor*(##3 - \rangea)}% + \pgfmathfloatparsenumber\pgfmathresult + \let\pgfplots@current@point@meta=\pgfmathresult + % pgfplots changes \pgfqpointxyz to + % \pgfplotspointdescriptionxy inside of legends, so use the + % '@orig' point command: + \pgfplotstreampoint{\pgfqpointxyz@orig{##1}{##2}{##3}}% + }% + % for the case 'shader=interp': + \def\pgfplotspointbbupperright{\pgfqpointxyz@orig{2}{2}{0.9}} + \def\pgfplotspointbblowerleft {\pgfqpointxyz@orig{0}{0}{0.1}} + + \simplecoordinate(0,2,0.7) + \simplecoordinate(1,2,0.5) + \simplecoordinate(2,2,0.43) + + \simplecoordinate(0,1,0.68) + \simplecoordinate(1,1,0.4) + \simplecoordinate(2,1,0.25) + + \simplecoordinate(0,0,0.6) + \simplecoordinate(1,0,0.35) + \simplecoordinate(2,0,0.21) + + \pgfplotstreamend + \pgfusepath{stroke} + \endscope +}% + +\def\pgfplotsplothandlermesh@finish{% + \ifnum\pgfplotsplothandlermesh@shader=2 + % shader=interp: + \ifx\pgf@plotstreampoint\pgfplotsplothandlermesh@shader@interp@incremental@transpose% + % This is the case for 'mesh/ordering=colwise'. We need to finish the transpose procedure: + \pgfplotsplothandlermesh@shader@interp@transpose@finish + \fi + \pgfplotslibrarysurfstreamend + \pgfplotslibrarysurfdrawinpicture + \else + \if\pgfplotsplothandlermesh@zbuffer@choice4% + % z buffer=sort: + % process the z buffer: + \pgfkeyslet{/pgfplots/array/iflessthan/.@cmd}\pgfplotsplothandlermesh@zbuffer@sort@iflessthen + \pgfkeysdef{/pgfplots/array/unscope pre}{% + \pgfplotsarrayforeachungrouped\pgfplots@zbuffer@local\as\curelem{% + \expandafter\pgfplotsplothandlermesh@draw@zbufferelement\curelem% + }% + }% + \pgfkeysdef{/pgfplots/array/unscope post}{}% + \pgfplotsarraysort\pgfplots@zbuffer@local + \fi + \fi +% \endscope +}% + +% the pgf@plotstreampoint routine for the first scan line: +\def\pgfplotsplothandlermesh@fillscanline#1{% + \pgf@process{#1}% + \edef\pgfplotsplothandlermesh@i@j{{\the\pgf@x}{\the\pgf@y}{\pgfplots@current@point@meta}}% + \expandafter\pgfplotsdequepushback\pgfplotsplothandlermesh@i@j\to{lastscanline}% + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@scanlinelength\relax + % second line! + \global\let\pgf@plotstreampoint=\pgfplotsplothandlermesh@draw%% + \c@pgfplots@scanlineindex=0 + \fi +}% + +% This is the pgf@plotstreampoint for all scan lines starting with the +% second. +% +% We perform +% for i = 1 to rows (note the 1! 0 would be the first row) +% for j = 0 to cols +% get (i-1, j) from front of deque // remember: i: rows, j : cols. We iterate rowwise. +% push (i,j) to back of deque +% if j > 0 +% draw +% (i-1,j-1) [from last iteration] -- (i-1,j) [from deque] +% -- ( i,j-1) [from last iteration] -- ( i,j) [from #1] +% endif +% let (i-1,j-1) := (i-1,j) // for next iteration +% let ( i,j-1) := ( i,j) // for next iteration +% end +% end +% +% This is a SWEEP through the data matrix. +\def\pgfplotsplothandlermesh@draw#1{% + % NOTATION: + % 'im == (i-1)' + % 'jm == (j-1)' + \pgf@process{#1}% + \edef\pgfplotsplothandlermesh@i@j{{\the\pgf@x}{\the\pgf@y}{\pgfplots@current@point@meta}}% FIXME relies on pgfplots macros +%\message{##\the\c@pgfplots@scanlineindex: prepare rectangle with corner \meaning\pgfplotsplothandlermesh@i@j.}% + \pgfplotsdequepopfront{lastscanline}\to\pgfplotsplothandlermesh@im@j + \expandafter\pgfplotsdequepushback\pgfplotsplothandlermesh@i@j\to{lastscanline}% + \ifnum\c@pgfplots@scanlineindex>0 + \pgfplotsplothandlermesh@process@element + \fi + \let\pgfplotsplothandlermesh@im@jm=\pgfplotsplothandlermesh@im@j + \let\pgfplotsplothandlermesh@i@jm=\pgfplotsplothandlermesh@i@j + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@scanlinelength\relax + \c@pgfplots@scanlineindex=0 + \fi +}% +\def\pgfplotsplothandlermesh@shader@interp#1{% + \pgfplots@perpointmeta@trafo@APPLY + \pgfplotslibrarysurfstreamcoord{#1}{\pgfplotspointmetatransformed}% +}% +\def\pgfplotsplothandlermesh@shader@interp@incremental@transpose#1{% + \pgfplots@perpointmeta@trafo@APPLY + \pgf@process{#1}% + \edef\pgfplotsplothandlermesh@i{\noexpand\pgfplotsplothandlermesh@shader@interp@next{\the\pgf@x}{\the\pgf@y}{\pgfplotspointmetatransformed}}% + % + % Store the postprocessed point into the appropriate row vector: + \def\pgfplots@loc@TMPa{\expandafter\pgfplotsapplistXpushback\expandafter{\pgfplotsplothandlermesh@i}\to} + \expandafter\pgfplots@loc@TMPa\csname pgfp@transprow@\the\c@pgfplots@scanlineindex\endcsname% + % + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@scanlinelength\relax + \c@pgfplots@scanlineindex=0 + \fi +}% +\def\pgfplotsplothandlermesh@shader@interp@transpose@finish{% + % Now, "execute" each row vector: + \def\pgfplotsplothandlermesh@shader@interp@next##1##2##3{% + \pgfplotslibrarysurfstreamcoord{\pgf@x=##1 \pgf@y=##2 }{##3}% + }% + \c@pgfplots@scanlineindex=0 + \pgfutil@loop + \ifnum\c@pgfplots@scanlineindex<\pgfplotsplothandlermesh@rows\relax + \expandafter\pgfplotsapplistXlet\expandafter\pgfplots@loc@TMPa\expandafter=\csname pgfp@transprow@\the\c@pgfplots@scanlineindex\endcsname% + \expandafter\pgfplotsapplistXnewempty\csname pgfp@transprow@\the\c@pgfplots@scanlineindex\endcsname% clear + % execute the row: + \pgfplots@loc@TMPa + \advance\c@pgfplots@scanlineindex by1 + \pgfutil@repeat +}% + +\def\pgfplotsplothandlermesh@draw@zbufferelement#1#2{% + \pgfplotsplothandlermesh@draw@element#2\relax +}% +% a possible value for \pgfplotsplothandlermesh@draw@element +\def\pgfplotsplothandlermesh@draw@element@line#1#2{% + \pgfpathmoveto{\expandafter\pgfplotsplothandlermesh@unpack#1}% + \pgfpathlineto{\expandafter\pgfplotsplothandlermesh@unpack#2}% + \pgfplotsplothandlermesh@preparedrawforcurrent + \pgfplotsplothandlermesh@usepath +}% +% a possible value for \pgfplotsplothandlermesh@draw@element +\def\pgfplotsplothandlermesh@draw@element@rectangle#1#2#3#4{% + \pgfpathmoveto{\expandafter\pgfplotsplothandlermesh@unpack#1}% + \pgfpathlineto{\expandafter\pgfplotsplothandlermesh@unpack#2}% + \pgfpathlineto{\expandafter\pgfplotsplothandlermesh@unpack#3}% + \pgfpathlineto{\expandafter\pgfplotsplothandlermesh@unpack#4}% + \pgfplotsplothandlermesh@preparedrawforcurrent + \pgfpathclose + \pgfplotsplothandlermesh@usepath +}% + +\def\pgfplotsplothandlermesh@zbuffer@sort@iflessthen#1#2#3#4\pgfeov{% + \edef\pgfplots@loc@TMPa{#1}% + \expandafter\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@\pgfplots@loc@TMPa\relax + \let\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@a=\pgfmathresult + \edef\pgfplots@loc@TMPb{#2}% + \expandafter\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@\pgfplots@loc@TMPb\relax + \let\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@b=\pgfmathresult + \ifdim\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@b pt<\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@a pt% + #3\relax + \else + #4\relax + \fi +}% +\def\pgfplotsplothandlermesh@zbuffer@sort@iflessthen@#1#2{% + \def\pgfmathresult{#1}% +}% + +% #1: projected x coord +% #2: projected y coord +% #3: per point meta (if any) +\def\pgfplotsplothandlermesh@unpack@corner#1#2#3{% + \pgf@x=#1\relax + \pgf@y=#2\relax +}% +\def\pgfplotsplothandlermesh@unpack@mean@accum#1#2#3{% + \pgf@x=#1\relax + \pgf@y=#2\relax + \def\pgfplots@current@point@meta{#3}% + \pgfplots@perpointmeta@trafo@APPLY + \global\advance\pgfplots@tmpa by\pgfplotspointmetatransformed pt +}% +% same as above, just for one dim plots (rows == 1 || cols==1) +\def\pgfplotsplothandlermesh@ONEDIM@draw#1{% + \pgf@process{#1}% + \edef\pgfplotsplothandlermesh@i{{\the\pgf@x}{\the\pgf@y}{\pgfplots@current@point@meta}}% + \ifnum\c@pgfplots@scanlineindex>0 + \pgfplotsplothandlermesh@process@element + \fi + \let\pgfplotsplothandlermesh@im=\pgfplotsplothandlermesh@i + \advance\c@pgfplots@scanlineindex by1 +}% + +% #1: a normalized coordinate stream. +% +% Output: a normalized coordinate stream in \pgfplotsglobalretval. +\def\pgfplots@apply@zbuffer#1{% + \ifcase\pgfplotsplothandlermesh@zbuffer@choice\relax + % none. + \gdef\pgfplotsglobalretval{#1}% + \or + % reverse x seq: only for 'mesh' + \if\pgfplots@meshmode n% + \pgfplots@error{Sorry, `/pgfplots/z buffer=reverse x seq' can only be used for mesh/surf plots.}% + \gdef\pgfplotsglobalretval{#1}% + \else + \pgfplotsautocompletemeshkeys + \if\pgfplots@plot@mesh@ordering0% + % ordering = rowwise -> scanline is cols! + \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversescanline{#1}% + \else + % ordering = colwise: scanline is rows! + \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversetransposed{#1}% + \fi + \fi + \or + % reverse y seq: only for 'mesh' + \if\pgfplots@meshmode n% + \pgfplots@error{Sorry, `/pgfplots/z buffer=reverse y seq' can only be used for mesh/surf plots.}% + \gdef\pgfplotsglobalretval{#1}% + \else + \pgfplotsautocompletemeshkeys + \if\pgfplots@plot@mesh@ordering0% + % ordering = rowwise -> scanline is cols! + \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversetransposed{#1}% + \else + % ordering = colwise: scanline is rows! + \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsscanlinelength + \pgfplots@apply@zbuffer@reversescanline{#1}% + \fi + \fi + \or + % reverse xy seq: + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsprependlistXnewempty{reversed}% + }% + \def\pgfplots@coord@stream@coord{% + \edef\pgfplots@loc@TMPa{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z,\pgfplots@current@point@meta;}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@loc@TMPa}\to{reversed}% + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversed}% + \pgfplotsprependlistXnewempty{reversed}% clear it + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \pgfplots@coord@stream@foreach@NORMALIZED{#1}% + \endgroup + \or + % sort. + \if\pgfplots@meshmode n% + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsarraynewempty\pgfplots@zbuffer@local + \pgfplotsarrayresize\pgfplots@zbuffer@local{\numcoords}% + \c@pgfplots@scanlineindex=0 + \def\pgfplots@zbuffer@local@SETCUR####1{% + \expandafter\pgfplotsarrayset\c@pgfplots@scanlineindex\of\pgfplots@zbuffer@local\to{####1}% + }% + }% + \def\pgfplots@coord@stream@coord{% + \edef\pgfplots@loc@TMPa{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z,\pgfplots@current@point@meta;}% + \expandafter\pgfplots@zbuffer@local@SETCUR\expandafter{\pgfplots@loc@TMPa}% + \advance\c@pgfplots@scanlineindex by1 + }% + \def\pgfplots@coord@stream@end{% + \ifnum\c@pgfplots@scanlineindex=\numcoords + \else + \pgfplotsarrayresize\pgfplots@zbuffer@local{\c@pgfplots@scanlineindex}% + \fi + \pgfkeyslet{/pgfplots/array/iflessthan/.@cmd}\pgfplots@apply@zbuffer@SORT@iflessthan + \pgfkeysdef{/pgfplots/array/unscope pre}{% + \pgfplotsapplistXnewempty{\pgfp@sortedlist}% + \pgfplotsarrayforeachungrouped\pgfplots@zbuffer@local\as\curelem{% + \expandafter\pgfplotsapplistXpushback\curelem\to{\pgfp@sortedlist}% + }% + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\pgfp@sortedlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \pgfkeysdef{/pgfplots/array/unscope post}{}% + \pgfplotsarraysort\pgfplots@zbuffer@local + }% + \pgfplots@coord@stream@foreach@NORMALIZED{#1}% + \endgroup + \else + % meshmode handles sort separately! + \gdef\pgfplotsglobalretval{#1}% + \fi + \or + % z buffer=auto + % + % I can decide for each axis if coordinate reversal is + % necessary. + % Idea: check if axis side planes are on foreground or not (a + % very simple task)! I + % only need to know whether [xy] coordinates are sorted + % ascending or descending. This information is already ready. + % \begingroup - \pgftransformshift{\pgfplots@plot@handler@graphics@bb@first}% - \node[/pgfplots/plot graphics/node,rectangle] {% - \expandafter\includegraphics\expandafter[\pgfplots@loc@TMPc,width=\pgfplots@loc@TMPa,height=\pgfplots@loc@TMPb]{\pgfplots@loc@TMPd}% - };% + \if+\pgfkeysvalueof{/pgfplots/x coord sorting}% + \def\pgfplots@minmaxvalue@x{0}% + \else + \def\pgfplots@minmaxvalue@x{0}% + \fi + \if+\pgfkeysvalueof{/pgfplots/y coord sorting}% + \def\pgfplots@minmaxvalue@y{0}% + \else + \def\pgfplots@minmaxvalue@y{1}% + \fi + \pgfplotsifaxissurfaceisforeground{\pgfplots@minmaxvalue@x vv}{% + \def\pgfplots@reverse@x{1}% + }{% + \def\pgfplots@reverse@x{0}% + }% + \pgfplotsifaxissurfaceisforeground{v\pgfplots@minmaxvalue@y v}{% + \def\pgfplots@reverse@y{1}% + }{% + \def\pgfplots@reverse@y{0}% + }% + \if1\pgfplots@reverse@x + \if1\pgfplots@reverse@y + \pgfkeys{/pgfplots/z buffer=reverse xy seq}% + \else + \pgfkeys{/pgfplots/z buffer=reverse x seq}% + \fi + \else + \if1\pgfplots@reverse@y + \pgfkeys{/pgfplots/z buffer=reverse y seq}% + \else + \pgfkeys{/pgfplots/z buffer=none}% + \fi + \fi +%\message{z buffer=auto mode chose z buffer= \ifcase\pgfplotsplothandlermesh@zbuffer@choice NONE \or reverse x seq \or reverse y seq \or reverse xy seq \or sort\or default \fi. mesh ordering = \ifcase\pgfplots@plot@mesh@ordering x varies/rowwise\or y varies/colwise\fi}% + % 'z buffer' is no longer 'auto' now: + \pgfplots@apply@zbuffer{#1}% \endgroup + \or + % z buffer=default. + \if\pgfplots@meshmode n% + % mesh mode deactivated! + \gdef\pgfplotsglobalretval{#1}% + \else + % mesh=true + \begingroup + \pgfkeysalso{/pgfplots/z buffer=auto}% + \pgfplots@apply@zbuffer{#1}% + \endgroup + \fi \fi }% +% Defines \pgfplotsglobalretval (globally) to be a partial reversion of the +% (normalized) 2d coordinate sequence '#1'. +% +% In other words, the normalized coordinate sequence '#1' is visited +% linearly and while we go, each scanline is reversed. The result is +% collected into \pgfplotsglobalretval. +% +% This implements the 'z buffer=reverse x seq' feature for +% ordering=y varies. +% +% PRECONDITION: +% \pgfplotsscanlinelength contains the scanline length +% POSTCONDITION: +% \pgfplotsglobalretval contains the partial reversion. +\def\pgfplots@apply@zbuffer@reversescanline#1{% + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsprependlistXnewempty{reversedscanline}% + \c@pgfplots@scanlineindex=0 + \pgfplotsapplistXnewempty{\resultlist}% + }% + \def\pgfplots@coord@stream@coord{% + \edef\pgfplots@loc@TMPa{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z,\pgfplots@current@point@meta;}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@loc@TMPa}\to{reversedscanline}% + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversedscanline}% + \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@loc@TMPa}\to\resultlist + \pgfplotsprependlistXnewempty{reversedscanline}% + \c@pgfplots@scanlineindex=0 + \fi + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversedscanline}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfplots@zbuffer@error + \fi + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\resultlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \pgfplots@coord@stream@foreach@NORMALIZED{#1}% +%\message{I have performed partial reversion of '#1' and got '\pgfplotsglobalretval'!}% + \endgroup +}% + +% A very similar method of \pgfplots@apply@zbuffer@reversescanline, +% but this one keeps everything inside of each scanline in the +% original ordering, and reverses the ordering in which whole +% scanlines occur. +\def\pgfplots@apply@zbuffer@reversetransposed#1{% + \begingroup + \def\pgfplots@coord@stream@start{% + \pgfplotsapplistXnewempty{\scanline}% + \c@pgfplots@scanlineindex=0 + \pgfplotsprependlistXnewempty{resultlist}% + }% + \def\pgfplots@coord@stream@coord{% + \edef\pgfplots@loc@TMPa{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z,\pgfplots@current@point@meta;}% + \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@loc@TMPa}\to{\scanline}% + \advance\c@pgfplots@scanlineindex by1 + \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\scanline}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@loc@TMPa}\to{resultlist} + \pgfplotsapplistXnewempty{\scanline}% + \c@pgfplots@scanlineindex=0 + \fi + }% + \def\pgfplots@coord@stream@end{% + \pgfplotsapplistXlet\pgfplots@loc@TMPa={\scanline}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfplots@zbuffer@error + \fi + \pgfplotsprependlistXlet\pgfplots@loc@TMPa={resultlist}% + \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa + }% + \pgfplots@coord@stream@foreach@NORMALIZED{#1}% +%\message{I have performed partial reversion of '#1' and got '\pgfplotsglobalretval'!}% + \endgroup +}% +\def\pgfplots@zbuffer@error{% + \pgfplots@error{An internal error occured during z buffer reorderings: the rows/cols where not balanced! I have rows= \pgfkeysvalueof{/pgfplots/mesh/rows}, cols=\pgfkeysvalueof{/pgfplots/mesh/cols}. If this happens to be wrong, you might want to provide rows and cols manually.}% +} + +% A special '<' operation which returns true if the point coordinate +% '#1' is BEHIND #2 with respect to the current 3D view. +\def\pgfplots@apply@zbuffer@SORT@iflessthan#1#2#3#4\pgfeov{% + \edef\pgfplots@loc@TMPa{#1}% + \expandafter\pgfplots@apply@zbuffer@SORT@iflessthan@\pgfplots@loc@TMPa\relax + \let\pgfplots@apply@zbuffer@SORT@iflessthan@a=\pgfmathresult + \edef\pgfplots@loc@TMPb{#2}% + \expandafter\pgfplots@apply@zbuffer@SORT@iflessthan@\pgfplots@loc@TMPb\relax + \let\pgfplots@apply@zbuffer@SORT@iflessthan@b=\pgfmathresult + \pgfmathfloatlessthan@{\pgfplots@apply@zbuffer@SORT@iflessthan@b}{\pgfplots@apply@zbuffer@SORT@iflessthan@a}% + \ifpgfmathfloatcomparison + #3\relax + \else + #4\relax + \fi +}% + +% returns the view depth of the provided serialized coordinate into +% \pgfmathresult +% +% FIXME : relies on the internal repr in +% \pgfplots@coord@stream@foreach@NORMALIZED : +\def\pgfplots@apply@zbuffer@SORT@iflessthan@#1,#2,#3,#4;{% + \pgfplotsmathfloatviewdepthxyz{#1}{#2}{#3}% +}% + +% Defines \pgfmathresult to be the view depth of a three component +% vector. The third component will be used if and only if the boolean +% \ifpgfplots@curplot@threedim is true. +% The return value will be assigned in floating point. +% +% The arguments need to be numbers (will be parsed with +% \pgfmathfloatparsenumber). +% @see \pgfplotsmathviewdepthxyz +\def\pgfplotsmathfloatviewdepthxyz#1#2#3{% + \pgfmathfloatparsenumber{#1}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfmathfloatparsenumber{#2}\let\pgfplots@loc@TMPb=\pgfmathresult + \pgfmathfloatparsenumber{#3}\let\pgfplots@loc@TMPc=\pgfmathresult + \edef\pgfplots@loc@TMPa{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}}% + \expandafter\pgfplotsmathfloatviewdepthxyz@\pgfplots@loc@TMPa +}% + +\def\pgfplotsmathfloatviewdepthxyz@#1#2#3{% + \pgfplots@error{Sorry, you can't use \string\pgfplotsmathfloatviewdepthxyz\space in this context.}% +}% +\def\pgfplotsmathfloatviewdepthxyz@infigure#1#2#3{% + \pgfmathfloatmultiplyfixed@{#1}{\pgfplots@view@dir@threedim@x}% + \let\pgfplots@loc@TMPa=\pgfmathresult + \pgfmathfloatmultiplyfixed@{#2}{\pgfplots@view@dir@threedim@y}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \pgfmathfloatadd@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \ifpgfplots@curplot@threedim + \pgfmathfloatmultiplyfixed@{#3}{\pgfplots@view@dir@threedim@z}% + \let\pgfplots@loc@TMPc=\pgfmathresult + \pgfmathfloatadd@{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \fi + \let\pgfmathresult=\pgfplots@loc@TMPb +}% + +% Similar to \pgfplotsmathfloatviewdepthxyz, but this always relies on +% fixed point arithmetics. +\def\pgfplotsmathviewdepthxyz#1#2#3{\pgfplotsmathviewdepthxyz@{#1}{#2}{#3}} +\def\pgfplotsmathviewdepthxyz@#1#2#3{% + \pgfplots@error{Sorry, you can't use \string\pgfplotsmathviewdepthxyz\space in this context.}% +} +\def\pgfplotsmathviewdepthxyz@infigure#1#2#3{% + \pgfmath@basic@multiply@{#1}{\pgfplots@view@dir@threedim@x}% + \let\pgfplots@loc@TMPa=\pgfmathresult + \pgfmath@basic@multiply@{#2}{\pgfplots@view@dir@threedim@y}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \pgfmath@basic@add@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \ifpgfplots@curplot@threedim + \pgfmath@basic@multiply@{#3}{\pgfplots@view@dir@threedim@z}% + \let\pgfplots@loc@TMPc=\pgfmathresult + \pgfmath@basic@add@{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}% + \let\pgfplots@loc@TMPb=\pgfmathresult + \fi + \let\pgfmathresult=\pgfplots@loc@TMPb +}% + + +% Evaluate shell commands. +% +% #1 = filename prefix for .sh and .out files (optional, +% default is \jobname) +% #2 = shell command text +% +% Description: +% +% This command will write the command text to a file called +% #1.sh. Then it calls sh (using the \write18 mechanism) to +% execute the file and redirect the output to a file called +% #1.out. +% In contrast to pgfplotgnuplot the result has to be read +% from #1.out later using \pgfplotxyfile. (This allows +% using the function from within the plot table functions +% as well.) +% +% Example: +% +% \pgfplothandlerlineto +% \pgfshell[\jobname]{cat table.dat} +% \pgfplotxyfile{\jobname.out} + +\pgfutil@ifundefined{w@pgf@writea}{% + \csname newwrite\endcsname\pgf@shellwrite +}{% + \let\pgf@shellwrite=\w@pgf@writea +} +\newif\ifpgf@resample@shell + +\def\pgfshell{\pgfutil@ifnextchar[{\pgf@shell}{\pgf@shell[\jobname]}}%} +\def\pgf@shell[#1]#2{% + \pgf@resample@shelltrue% + % Check, whether it is up-to-date + \openin\pgfutil@inputcheck=#1.sh + \ifeof\pgfutil@inputcheck% + \else% + \read\pgfutil@inputcheck to\pgf@shell@line% + \edef\pgf@plot@code{#2\space}% + \ifx\pgf@plot@code\pgf@shell@line% + \openin\pgfutil@inputcheck=#1.out + \ifeof\pgfutil@inputcheck% + \else% + \pgf@resample@shellfalse + \fi% + \fi% + \fi + \ifpgf@resample@shell% + \immediate\openout\pgf@shellwrite=#1.sh + \immediate\write\pgf@shellwrite{#2}% + \immediate\closeout\pgf@shellwrite% + \immediate\write18{sh #1.sh > #1.out} + \fi% +} +% Used inside of /pgfplots/scatter/classes : +\def\pgfplots@scatter@classes@pre@marker@code{% + \pgfutil@ifundefined{pgfp@scatter@class@\pgfplotspointmeta}{% + \let\pgfplots@loc@TMPa=\pgfplotspointmeta + % + % ups - no styles available? Maybe something went + % wrong with the 'scatter src' key. Check whether it + % was accidentally a numerical style: + \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname + \else + % ok, be fault tolerant and round to an integer: + \pgfmathfloattofixed{\pgfplotspointmeta}% + \begingroup + \pgfkeys{/pgf/number format/precision=0}% + \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% + \pgfmath@smuggleone\pgfmathresult + \endgroup + \let\pgfplotspointmeta=\pgfmathresult + \fi + % now, check again: + \pgfutil@ifundefined{pgfp@scatter@class@\pgfplotspointmeta}{% + % still not possible? Then, try truncating the + % number to an integer. + \expandafter\pgfutil@in@\expandafter.\expandafter{\pgfplotspointmeta}% + \ifpgfutil@in@ + \def\pgfplots@loc@TMPb##1.##2\relax{\def\pgfplotspointmeta{##1}}% + \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\relax + \fi + % now, check again: + \pgfutil@ifundefined{pgfp@scatter@class@\pgfplotspointmeta}{% + \pgfutil@ifundefined{pgfp@scatter@WARNING@\pgfplotspointmeta}{% + \pgfplots@warning{scatter/classes: can't find class for '\pgfplotspointmeta'!? Please make sure you have specified 'scatter src=explicit symbolic'. Ignoring class '\pgfplotspointmeta' (this message will not come again).}% + \expandafter\gdef\csname pgfp@scatter@WARNING@\pgfplotspointmeta\endcsname{ALREADY CHECKED}% + }{}% + \def\pgfplots@loc@TMPa{}% + }{% + \expandafter\let\expandafter\pgfplots@loc@TMPa\csname pgfp@scatter@class@\pgfplotspointmeta\endcsname + }% + }{% + \expandafter\let\expandafter\pgfplots@loc@TMPa\csname pgfp@scatter@class@\pgfplotspointmeta\endcsname + }% + }{% + \expandafter\let\expandafter\pgfplots@loc@TMPa\csname pgfp@scatter@class@\pgfplotspointmeta\endcsname + }% + \expandafter\scope\expandafter[\pgfplots@loc@TMPa]% +}% |