diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex | 5654 |
1 files changed, 3586 insertions, 2068 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex index 1331a3f284b..996dce22550 100644 --- a/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex +++ b/Master/texmf-dist/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex @@ -7,7 +7,7 @@ % % It is based on Till Tantau's PGF package. % -% Copyright 2007/2008 by Christian Feuersänger. +% Copyright 2007-2010 by Christian Feuersänger. % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by @@ -63,10 +63,15 @@ \pgf@zx=0pt \pgf@zy=0pt }% - \let\pgfpointxy@orig=\pgfpointxy - \let\pgfqpointxy@orig=\pgfqpointxy - \let\pgfpointxyz@orig=\pgfpointxyz - \let\pgfqpointxyz@orig=\pgfqpointxyz + % + % + \edef\pgfplotsplothandlerpointxyz##1##2##3{% + \ifpgfplots@curplot@threedim + \noexpand\pgfplotsqpointxyz{##1}{##2}{##3}% + \else + \noexpand\pgfplotsqpointxy{##1}{##2}% + \fi + }% % % A point command such that (0,0) is the 'south west' and (1,1) % the 'north east' point of an axis. @@ -97,17 +102,9 @@ {\pgfqpointxy@orig{##1}{##2}}% }% }% - \edef\pgfplotspointunitx{\global\pgf@x=\the\pgf@xx\space\global\pgf@y=\the\pgf@xy\space}% - \edef\pgfplotspointunity{\global\pgf@x=\the\pgf@yx\space\global\pgf@y=\the\pgf@yy\space}% - \let\pgfplotsunitxlength=\pgfplots@x@veclength - \let\pgfplotsunitylength=\pgfplots@y@veclength - \let\pgfplotsunitxinvlength=\pgfplots@x@inverseveclength - \let\pgfplotsunityinvlength=\pgfplots@y@inverseveclength - \ifpgfplots@threedim - \edef\pgfplotspointunitz{\global\pgf@x=\the\pgf@zx\space\global\pgf@y=\the\pgf@zy\space}% - \let\pgfplotsunitzlength=\pgfplots@z@veclength - \let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength - \fi + \pgfplotspoint@initialisation@axes + \pgfplotspoint@initialisation@units + \pgfplotspoint@initialisation@center % % declare the '[xyz]ticklabel cs' \tikzdeclarecoordinatesystem{xticklabel}{\pgfplotspointticklabelcs{x}{##1}}% @@ -119,12 +116,167 @@ \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}}}% + \pgfkeysdef{/tikz/sloped like x axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{x}}}% + \pgfkeysdef{/tikz/sloped like y axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{y}}}% + \pgfkeysdef{/tikz/sloped like z axis}{\tikz@addtransform{\pgfplotstransformtoaxisdirection[##1]{z}}}% % }% +% Determine final axes this does also fix the axis' dimension. +% There are the following cases: +% 1. the user really wants a fixed dimension, +% i.e. he used 'scale only axis'. +% Then, we have to work to get the correct dimension! +% +% Up to now, the scaling mechanism looses to many significant +% digits such that the final width/height differs by 1-2 pt. +% +% If I am not mistaken, this does ONLY affect the final size, +% not the relative plot precision. +% +% FIXME : really compute the plot precision! +% +% 2. The use specified width and/or height, but not 'scale only +% axis'. Accept inaccurate final widths/heights (see above). +% +% 3. The user supplied 'x' and or 'y'. Simply use them, its +% accurate. +% POSTCONDITION: the macros +% \pgfplotspointminminmin +% \pgfplotspoint[xyz]axis +% \pgfplotspoint[xyz]axislength +% are defined (globally). +% +\def\pgfplotspoint@initialisation@axes{% + \begingroup + \ifpgfplots@threedim + \def\pgfplotspointmaxminmin{\pgfplotsqpointxyz{\pgfplots@xmax}{\pgfplots@ymin}{\pgfplots@zmin}}% + \def\pgfplotspointminmaxmin{\pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymax}{\pgfplots@zmin}}% + \pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymin}{\pgfplots@zmin}% + \else + \def\pgfplotspointmaxminmin{\pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymin}}% + \def\pgfplotspointminmaxmin{\pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymax}}% + \pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymin}% + \fi + \xdef\pgfplotspointminminmin{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + % ATTENTION: I re-use registers here! Make sure they won't be + % overwritten! \pgfpointdiff and \pgfplotsqpointxy are ok in this respect. + \let\pgfplots@xcoordminTEX=\pgf@xb + \let\pgfplots@ycoordminTEX=\pgf@yb + \pgfplots@xcoordminTEX=\pgf@x + \pgfplots@ycoordminTEX=\pgf@y + % + %-------------------------------------------------- + % FIXME : WHAT IS THIS HERE FOR? + % \pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymax}% + % \ifx\pgfplots@rectangle@width\pgfutil@empty + % \def\pgfplots@tmp@xmax@ymin{\pgfplotsqpointxy{\pgfplots@xmax}{\pgfplots@ymin}}% + % \else + % % this 'if' here should only make a difference of about + % % 1-2pt, not more. + % % + % % and I am quite sure that this inaccuracy (and this + % % work-around) only affects the + % % final size, not the relative plot accuracy. + % \pgf@x=\pgfplots@xcoordminTEX + % \advance\pgf@x by\pgfplots@width + % \edef\pgfplots@tmp@xmax@ymin{\noexpand\pgfqpoint{\the\pgf@x}{\noexpand\pgfplots@ycoordminTEX}}% + % \fi + % \ifx\pgfplots@rectangle@height\pgfutil@empty + % \def\pgfplots@tmp@xmin@ymax{\pgfplotsqpointxy{\pgfplots@xmin}{\pgfplots@ymax}}% + % \else + % \pgf@x=\pgfplots@ycoordminTEX + % \advance\pgf@x\pgfplots@height + % \edef\pgfplots@tmp@xmin@ymax{\noexpand\pgfqpoint{\noexpand\pgfplots@xcoordminTEX}{\the\pgf@x}}% + % \fi + %-------------------------------------------------- + \pgfpointdiff + {\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}} + {\pgfplotspointmaxminmin}% + \xdef\pgfplotspointxaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + \pgfmathveclen{\pgf@x}{\pgf@y}% + \xdef\pgfplotspointxaxislength{\pgfmathresult pt}% + % + \pgfpointdiff + {\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}} + {\pgfplotspointminmaxmin}% + \xdef\pgfplotspointyaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + \pgfmathveclen{\pgf@x}{\pgf@y}% + \xdef\pgfplotspointyaxislength{\pgfmathresult pt}% + % + \ifpgfplots@threedim + \pgfpointdiff + {\pgfqpoint{\pgfplots@xcoordminTEX}{\pgfplots@ycoordminTEX}} + {\pgfplotsqpointxyz{\pgfplots@xmin}{\pgfplots@ymin}{\pgfplots@zmax}}% + \xdef\pgfplotspointzaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + \pgfmathveclen{\pgf@x}{\pgf@y}% + \xdef\pgfplotspointzaxislength{\pgfmathresult pt}% + \else + \global\let\pgfplotspointzaxis=\pgfpointorigin + \gdef\pgfplotspointzaxislength{0pt}% + \fi + \endgroup + % +} + +% PRECONDITION: called after \pgfplotspoint@initialisation@axes +% POSTCONDITION: +% \pgfplotspointcenter is defined. +\def\pgfplotspoint@initialisation@center{% + \begingroup + % + % + \ifpgfplots@threedim + % + \pgfpointscale + {0.5}% + {\pgfplotspointxaxis + \pgf@xa=\pgf@x + \pgf@xb=\pgf@y + \pgfplotspointyaxis% + \advance\pgf@xa by\pgf@x + \advance\pgf@xb by\pgf@y + \pgfplotspointzaxis% + \advance\pgf@xa by\pgf@x + \advance\pgf@xb by\pgf@y + \pgf@x=\pgf@xa + \pgf@y=\pgf@xb + }% + \xdef\pgfplotspointcenter{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + \else + \pgfpointscale + {0.5}% + {\pgfpointadd + \pgfplotspointxaxis% + \pgfplotspointyaxis% + }% + \xdef\pgfplotspointcenter{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% + \fi + \endgroup +} + +% PRECONDITION: +% the unit vectors are set up +% +% POSTCONDITION: +% \pgfplotspointunit[xyz] +% \pgfplotspointunit[xyz]length +% \pgfplotspointunit[xyz]invlength +% are all set up. +\def\pgfplotspoint@initialisation@units{% + \edef\pgfplotspointunitx{\pgf@x=\the\pgf@xx\space\pgf@y=\the\pgf@xy\space}% + \edef\pgfplotspointunity{\pgf@x=\the\pgf@yx\space\pgf@y=\the\pgf@yy\space}% + \let\pgfplotsunitxlength=\pgfplots@x@veclength + \let\pgfplotsunitylength=\pgfplots@y@veclength + \let\pgfplotsunitxinvlength=\pgfplots@x@inverseveclength + \let\pgfplotsunityinvlength=\pgfplots@y@inverseveclength + \ifpgfplots@threedim + \edef\pgfplotspointunitz{\pgf@x=\the\pgf@zx\space\pgf@y=\the\pgf@zy\space}% + \let\pgfplotsunitzlength=\pgfplots@z@veclength + \let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength + \fi +}% + % The idea here is the following: % % 1. A point coordinate (<x>,<y>) without units should use @@ -253,7 +405,7 @@ % \pgfplotspointonorientedsurfaceN. % % Example: -% \pgfplotspointonorientedsurfaceabsetupforxyz +% \pgfplotspointonorientedsurfaceabsetupfor xyz % \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} % % -> @@ -264,7 +416,7 @@ % \pgfplotspointonorientedsurfacespecunordered = {vv0} % \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{3}{4}{<lower z limit>} % -% \pgfplotspointonorientedsurfaceabsetupforyxz +% \pgfplotspointonorientedsurfaceabsetupfor yxz % \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} % -> % \pgfplotspointonorientedsurfaceA = y @@ -274,11 +426,32 @@ % \pgfplotspointonorientedsurfacespecunordered = {vv0} % \pgfplotspointonorientedsurfaceab{3}{4} =\pgfqpointxyz{4}{3}{<lower z limit>} % -% @see \pgfplotspointonorientedsurfaceabsetupforxyz +% @see \pgfplotspointonorientedsurfaceabsetupfor xyz \def\pgfplotspointonorientedsurfaceab#1#2{% - \pgfplots@error{Internal logic error: \string\pgfplotspointonorientedsurfaceab\ used although surface has not been declared! You need to call \string\pgfplotspointonorientedsurfaceabsetupforxyz\ or its friends to do so.}% + \pgfplots@error{Internal logic error: \string\pgfplotspointonorientedsurfaceab\ used although surface has not been declared! You need to call \string\pgfplotspointonorientedsurfaceabsetupfor xyz\ or its friends to do so.}% }% +% This is a shortcut for +% \pgfpointadd +% {\pgfplotspointonorientedsurfaceab{#1}{#2}} +% {<shift in B direction of #3>} +% +% where #3 is a dimension (a number with unit). +\def\pgfplotspointonorientedsurfaceabwithbshift#1#2#3{% + \begingroup + \pgf@xa=#3\relax + \ifdim\pgf@xa=0pt + \else + \pgf@xa=\csname pgfplots@\pgfplotspointonorientedsurfaceB @inverseveclength\endcsname\pgf@xa + \fi + \advance\pgf@xa by#2pt + \edef\pgfplots@loc@b{\pgf@sys@tonumber\pgf@xa}% + \pgf@process{\pgfplotspointonorientedsurfaceab{#1}{\pgfplots@loc@b}}% + \endgroup +} + +\pgfkeyssetvalue{/pgfplots/oriented surf installed}{} + % This macro will be defined after % \pgfplotspointonorientedsurfaceabsetupfor... % routines. It expands to a three-character string @@ -308,65 +481,78 @@ % fixed. \def\pgfplotspointonorientedsurfacespecsymbol{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol} +\def\pgfplotspointonorientedsurfaceabsetupfor#1#2#3{% + \pgfutil@ifundefined{pgfplotspointonorientedsurfaceabsetupfor@@#1#2#3}{% + \pgfplots@error{Sorry, \string\pgfplotspointonorientedsurfaceabsetupfor\space#1#2#3 is not yet implemented.}% + }{ + \csname pgfplotspointonorientedsurfaceabsetupfor@@#1#2#3\endcsname + }% +}% +% % Initialises \pgfplotspointonorientedsurfaceab such that 'a' is the x % axis and 'b' is the y axis and the z coordinate has been fixed with % \pgfplotspointonorientedsurfaceabsetupforsetz{}. % % The Z value needs to be fixed with % \pgfplotspointonorientedsurfaceabsetupforsetz . -% -\def\pgfplotspointonorientedsurfaceabsetupforxyz{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedZ}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@xyz{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedz}}% \def\pgfplotspointonorientedsurfaceA{x}% \def\pgfplotspointonorientedsurfaceB{y}% \def\pgfplotspointonorientedsurfaceN{z}% \edef\pgfplotspointonorientedsurfacespec{ab\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% \edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforyxz{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedZ}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@yxz{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedz}}% \def\pgfplotspointonorientedsurfaceA{y}% \def\pgfplotspointonorientedsurfaceB{x}% \def\pgfplotspointonorientedsurfaceN{z}% \edef\pgfplotspointonorientedsurfacespec{ba\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% \edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforxzy{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedY}{##2}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@xzy{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##1}{\pgfplotspointonorientedsurfaceabsetupfor@fixedy}{##2}}% \def\pgfplotspointonorientedsurfaceA{x}% \def\pgfplotspointonorientedsurfaceB{z}% \def\pgfplotspointonorientedsurfaceN{y}% \edef\pgfplotspointonorientedsurfacespec{a\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol b}% \edef\pgfplotspointonorientedsurfacespecunordered{v\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol v}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforzxy{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedY}{##1}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@zxy{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{##2}{\pgfplotspointonorientedsurfaceabsetupfor@fixedy}{##1}}% \def\pgfplotspointonorientedsurfaceA{z}% \def\pgfplotspointonorientedsurfaceB{x}% \def\pgfplotspointonorientedsurfaceN{y}% \edef\pgfplotspointonorientedsurfacespec{b\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol a}% \edef\pgfplotspointonorientedsurfacespecunordered{v\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol v}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforyzx{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedX}{##1}{##2}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@yzx{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedx}{##1}{##2}}% \def\pgfplotspointonorientedsurfaceA{y}% \def\pgfplotspointonorientedsurfaceB{z}% \def\pgfplotspointonorientedsurfaceN{x}% \edef\pgfplotspointonorientedsurfacespec{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol ab}% \edef\pgfplotspointonorientedsurfacespecunordered{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol vv}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforzyx{% - \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedX}{##2}{##1}}% +\def\pgfplotspointonorientedsurfaceabsetupfor@@zyx{% + \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxyz{\pgfplotspointonorientedsurfaceabsetupfor@fixedx}{##2}{##1}}% \def\pgfplotspointonorientedsurfaceA{z}% \def\pgfplotspointonorientedsurfaceB{y}% \def\pgfplotspointonorientedsurfaceN{x}% \edef\pgfplotspointonorientedsurfacespec{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol ba}% \edef\pgfplotspointonorientedsurfacespecunordered{\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol vv}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% % Fixes 'x' to #1 for use in -% \pgfplotspointonorientedsurfaceabsetupforzyx and -% \pgfplotspointonorientedsurfaceabsetupforyzx. +% \pgfplotspointonorientedsurfaceabsetupfor zyx and +% \pgfplotspointonorientedsurfaceabsetupfor yzx. % % #1: The fixed value for 'x' (a coordinate in transformed range). % #2: a one-character symbol describing 'x'. @@ -375,21 +561,21 @@ % 1 : x is the upper x-axis range. % 2 : other. \def\pgfplotspointonorientedsurfaceabsetupforsetx#1#2{% - \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedX{#1}% + \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedx{#1}% \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}% }% \def\pgfplotspointonorientedsurfaceabsetupforsety#1#2{% - \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedY{#1}% + \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedy{#1}% \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}% }% \def\pgfplotspointonorientedsurfaceabsetupforsetz#1#2{% - \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedZ{#1}% + \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedz{#1}% \edef\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{#2}% }% % Helper methods which should be used if no Z component exists (pure % 2d plots). -\def\pgfplotspointonorientedsurfaceabsetupforxy{% +\def\pgfplotspointonorientedsurfaceabsetupfor@@xy{% \def\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{0}% \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxy{##1}{##2}}% \def\pgfplotspointonorientedsurfaceA{x}% @@ -397,8 +583,9 @@ \def\pgfplotspointonorientedsurfaceN{z}% \edef\pgfplotspointonorientedsurfacespec{ab\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% \edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% -\def\pgfplotspointonorientedsurfaceabsetupforyx{% +\def\pgfplotspointonorientedsurfaceabsetupfor@@yx{% \def\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol{0}% \def\pgfplotspointonorientedsurfaceab##1##2{\pgfplotsqpointxy{##2}{##1}}% \def\pgfplotspointonorientedsurfaceA{y}% @@ -406,6 +593,7 @@ \def\pgfplotspointonorientedsurfaceN{z}% \edef\pgfplotspointonorientedsurfacespec{ba\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% \edef\pgfplotspointonorientedsurfacespecunordered{vv\pgfplotspointonorientedsurfaceabsetupfor@fixedsymbol}% + \pgfkeysvalueof{/pgfplots/oriented surf installed}% }% @@ -439,7 +627,7 @@ % (three-char-string). % % Example: -% \pgfplotspointonorientedsurfaceabsetupforxyz +% \pgfplotspointonorientedsurfaceabsetupfor xyz % \pgfplotspointonorientedsurfaceabsetupforsetz{<lower z limit>}{0} % -> the oriented surface is 'ab0' % ... @@ -734,22 +922,22 @@ % % Example: % \pgfplotspointonorientedsurfaceabsetupforsetz{\zmax}{1} -% \pgfplotspointonorientedsurfaceabsetupforyxz +% \pgfplotspointonorientedsurfaceabsetupfor yxz % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be 'v' because 'x=v' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsety{\ymin}{0} -% \pgfplotspointonorientedsurfaceabsetupforxzy +% \pgfplotspointonorientedsurfaceabsetupfor xzy % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be '1' because 'z=1' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsety{\ymax}{1} -% \pgfplotspointonorientedsurfaceabsetupforxzy +% \pgfplotspointonorientedsurfaceabsetupfor xzy % \pgfplotspointonorientedsurfaceabmatchaxisline{v01}{\result} % -> \result will be empty because 'y=0' in '{v01} % % \pgfplotspointonorientedsurfaceabsetupforsetx{\xmax}{1} -% \pgfplotspointonorientedsurfaceabsetupforyzx +% \pgfplotspointonorientedsurfaceabsetupfor yzx % \pgfplotspointonorientedsurfaceabmatchaxisline{10v}{\result} % -> \result will be 'v' because 'z=v' in '{10v} \def\pgfplotspointonorientedsurfaceabmatchaxisline#1#2{% @@ -835,11 +1023,17 @@ \let\pgfplots@loc@TMPa=\pgfutil@empty \fi \else - \pgfplots@error{The character '#1' is no valid element for a three-character axis line or surface description!}% + % return TRUE. + % I admit I am not sure at all if this works in all + % cases + \pgfplotspointonorientedsurfaceabmatchaxisline@warn{#1}% \fi \fi \fi }% +\def\pgfplotspointonorientedsurfaceabmatchaxisline@warn#1{% + \pgfplots@warning{The internal implementation is suspicious that something is wrong: \string\pgfplotspointonorientedsurfaceabmatchaxisline@warn: the character '#1' in a three-character axis line or surface description might not be fully supported...}% +}% % Provides a point on an arbitrary axis (identified by a % three-character-string) which can take any value on that axis and @@ -931,7 +1125,17 @@ % % The returned normal vector has length 1 (computed with % \pgfpointnormalised). +% +% NOTE: some specialized axis types support non-linear axes (for +% example, polar axes). In that case, the outer normal vector *varies* +% along the `v' direction (of the three-character-string `#1'). +% The value of `v' can be set using +% \pgfplotspointouternormalvectorofaxissetv{<axis three char string>}{<transformed coordinate>} \def\pgfplotspointouternormalvectorofaxis#1{% + \pgfplotspointouternormalvectorofaxis@ifdependson@v{#1}{% + \expandafter\global\expandafter\let\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname\relax + }{% + }% \expandafter\ifx\csname pgfplotspointouternormalvectorofaxis@cache@#1\endcsname\relax \begingroup \edef\pgfplots@loc@TMPa{#1}% @@ -943,6 +1147,60 @@ \fi }% +% Fixes the "v" value for successive calls to +% \pgfplotspointouternormalvectorofaxis{#1}. +% +% #1 the three-character-string of an axis or the empty string. +% If #1 is empty, the actual configuration of oriented surfaces may be +% used to check which normal vector is intented. +% +% #2 the "v" value to store. It should be a transformed coordinate. +\def\pgfplotspointouternormalvectorofaxissetv#1#2{% + \edef\pgfplots@loc@TMPa{#1}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \expandafter\edef\csname pgfplotspointouternormalvectorofaxis@v@\pgfplotspointonorientedsurfaceA\endcsname{#2}% + \else + \expandafter\edef\csname pgfplotspointouternormalvectorofaxis@v@#1\endcsname{#2}% + \fi +}% + +% Defines \pgfplotsretval to contain the 'v' value for an outer normal +% vector (if there is one known). If there is no such value, +% \pgfplotsretval will be empty. +% #1 a three-character-string +\def\pgfplotspointouternormalvectorofaxisgetv#1{% + \edef\pgfplots@loc@TMPa{#1}% + \expandafter\pgfplotspointouternormalvectorofaxisgetv@\pgfplots@loc@TMPa\relax\relax\relax\relax +} +\def\pgfplotspointouternormalvectorofaxisgetv@#1#2#3\relax{% + \pgfutil@ifundefined{pgfplotspointouternormalvectorofaxis@v@#1#2#3}{% + % no value found so far. + \if#1v% + \def\pgfplotsretval{x}% + \else + \if#2v% + \def\pgfplotsretval{y}% + \else + \def\pgfplotsretval{z}% + \fi + \fi + \pgfutil@ifundefined{pgfplotspointouternormalvectorofaxis@v@\pgfplotsretval}{% + \let\pgfplotsretval\pgfutil@empty + }{% + \edef\pgfplotsretval{\csname pgfplotspointouternormalvectorofaxis@v@\pgfplotsretval\endcsname}% + }% + }{% + \edef\pgfplotsretval{\csname pgfplotspointouternormalvectorofaxis@v@#1#2#3\endcsname}% + }% +}% + +% invokes #2 if the outer normal for the axis #1 (identified by a +% three-character-string) depends on a coordinate on that axis and #3 +% otherwise. +% +% Overwrite in subclasses if necessary. +\def\pgfplotspointouternormalvectorofaxis@ifdependson@v#1#2#3{#3} + % FIXME : this doesn't work if one of the three characters is '2' (for % center) \def\pgfplotspointouternormalvectorofaxis@#1#2#3\relax{% @@ -1032,39 +1290,39 @@ % #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 + \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotspointonorientedsurfaceabsetupforsety{\pgfplots@loc@TMPa}{#2}% + % + \pgfplotspointonorientedsurfaceabsetupfor xzy% + \pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@A=\pgfmathresult + \ifpgfplots@threedim + \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@B=\pgfmathresult + \else + \def\pgfplots@loc@B{0}% + \fi + \else + \if v#2% \ifpgfplots@threedim - \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult + \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPa=\pgfmathresult \else - \def\pgfplots@loc@TMPc{0}% + \def\pgfplots@loc@TMPa{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}% - }% + \pgfplotspointonorientedsurfaceabsetupforsetz{\pgfplots@loc@TMPa}{#3}% + % + \pgfplotspointonorientedsurfaceabsetupfor yxz% + \pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@A=\pgfmathresult + \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@B=\pgfmathresult \else - \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}% - }% + \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotspointonorientedsurfaceabsetupforsetx{\pgfplots@loc@TMPa}{#1}% + % + \pgfplotspointonorientedsurfaceabsetupfor zyx% + \ifpgfplots@threedim + \pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@A=\pgfmathresult + \else + \def\pgfplots@loc@A{0}% + \fi + \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@B=\pgfmathresult \fi \fi % @@ -1076,8 +1334,9 @@ % \pgf@process{% \pgfpointadd - {\pgfplots@loc@point@orthogonal@to@v} + {\pgfplotspointonorientedsurfaceab{\pgfplots@loc@A}{\pgfplots@loc@B}} {% + \pgfplotspointouternormalvectorofaxissetv{#1#2#3}{\pgfplots@loc@A}% \pgfqpointscale {\pgfplots@loc@distalong@normal}% {\pgfplotspointouternormalvectorofaxis{#1#2#3}}% @@ -1085,10 +1344,67 @@ }% \endgroup }% +%-------------------------------------------------- +% \def\pgfplotspointoutsideofaxis@#1#2#3\relax#4#5{% +% \if v#1% +% \def\pgfplots@loc@point@orthogonal@to@v{% +% \pgfplotspointoutsideofaxis@plug@trafo{x}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult +% \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPb=\pgfmathresult +% \ifpgfplots@threedim +% \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult +% \else +% \def\pgfplots@loc@TMPc{0}% +% \fi +% \pgfplotsqpointxyz{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}% +% }% +% \else +% \if v#2% +% \def\pgfplots@loc@point@orthogonal@to@v{% +% \pgfplotspointoutsideofaxis@plug@trafo{y}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult +% \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult +% \ifpgfplots@threedim +% \pgfplotspointoutsideofaxis@plug@getlimit{z}{#3}\let\pgfplots@loc@TMPc=\pgfmathresult +% \else +% \def\pgfplots@loc@TMPc{0}% +% \fi +% \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPc}% +% }% +% \else +% \def\pgfplots@loc@point@orthogonal@to@v{% +% \ifpgfplots@threedim +% \pgfplotspointoutsideofaxis@plug@trafo{z}{#4}\let\pgfplots@loc@TMPa=\pgfmathresult +% \else +% \def\pgfplots@loc@TMPa{0}% +% \fi +% \pgfplotspointoutsideofaxis@plug@getlimit{x}{#1}\let\pgfplots@loc@TMPb=\pgfmathresult +% \pgfplotspointoutsideofaxis@plug@getlimit{y}{#2}\let\pgfplots@loc@TMPc=\pgfmathresult +% \pgfplotsqpointxyz{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}{\pgfplots@loc@TMPa}% +% }% +% \fi +% \fi +% % +% % read dimen argument #5: +% \afterassignment\pgfplots@gobble@until@relax +% \pgf@xa=#5pt\relax +% \edef\pgfplots@loc@distalong@normal{\pgf@sys@tonumber\pgf@xa}% +% % +% % +% \pgf@process{% +% \pgfpointadd +% {\pgfplots@loc@point@orthogonal@to@v} +% {% +% \pgfqpointscale +% {\pgfplots@loc@distalong@normal}% +% {\pgfplotspointouternormalvectorofaxis{#1#2#3}}% +% }% +% }% +% \endgroup +% }% +%-------------------------------------------------- % Helper method for \pgfplotsqpointoutsideofaxis and its variants. % #1: an axis (x,y or z) -% #2: one of '0', '1' or '2' where +% #2: o(\pgfplots@loc@TMPa - \pgfplots@loc@TMPb) ne of '0', '1' or '2' where % 0 == add lower #1 axis limit, % 1 == add upper #1 axis limit, % 2 == add nothing. @@ -1103,29 +1419,65 @@ \fi }% +\newif\ifpgfplots@sloped +\pgfplots@slopedtrue % its only purpose is to *DEACTIVATE* the sloped transformation after it has been activated. +\newif\ifpgfplots@sloped@resets@nontranslations +\newif\ifpgfplots@sloped@allowupsidedown +\pgfkeys{ + /pgfplots/sloped/true/.code={\pgfplots@slopedtrue}, + /pgfplots/sloped/false/.code={\pgfplots@slopedfalse}, + /pgfplots/sloped/allow upside down/.is if=pgfplots@sloped@allowupsidedown, + /pgfplots/sloped/allow upside down/.default=true, + /pgfplots/sloped/execute for upside down/.initial=, + /pgfplots/sloped/reset nontranslations/.is if=pgfplots@sloped@resets@nontranslations, + /pgfplots/sloped/reset nontranslations/.default=true, +} % Installs a rotation transformation matrix such that labels or % whatever are aligned precisely in direction of one of the two/three % coordinate directions. % -% #1: the coordinate direction (one of x,y or z) +% \pgfplotstransformtoaxisdirection[<options>]{<axis char>} +% +% <axis char>: the coordinate direction (one of x,y or z) % % The code is pretty much the same as \pgftransformlineattime, except % that the computation is considerably simpler as axis directions are % a well known quantity. % -% This command assumes \ifpgfallowupsidedownattime = false and -% \ifpgfresetnontranslationattime = true -\def\pgfplotstransformtoaxisdirection#1{% - \pgftransformresetnontranslations +% This command uses \ifpgfplots@sloped@allowupsidedown (=false) and +% \ifpgfplots@sloped@resets@nontranslations (= true). The default +% setting is reinitialised before options are processed +\def\pgfplotstransformtoaxisdirection{% + \pgfutil@ifnextchar[{\pgfplotstransformtoaxisdirection@}{\pgfplotstransformtoaxisdirection@[]}% +}% +\def\pgfplotstransformtoaxisdirection@[#1]#2{% + \pgfplots@sloped@allowupsidedownfalse + \pgfplots@sloped@resets@nontranslationstrue + % + \def\pgfplots@loc@TMPa{#1}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \pgfqkeys{/pgfplots/sloped}{#1}% + \fi + \ifpgfplots@sloped + % + \ifpgfplots@sloped@resets@nontranslations + \pgftransformresetnontranslations + \fi % % compute unit length vector pointing into the direction of % '#1#2#3': - \pgfqpointscale{\csname pgfplotsunit#1invlength\endcsname}{\csname pgfplotspointunit#1\endcsname}% + \pgfqpointscale{\csname pgfplotsunit#2invlength\endcsname}{\csname pgfplotspointunit#2\endcsname}% % - % do not allow upside down labels: \ifdim\pgf@x<0pt% - \global\pgf@x=-\pgf@x% - \global\pgf@y=-\pgf@y% + % oh. upside down. + \pgfkeysvalueof{/pgfplots/sloped/execute for upside down}% + \ifpgfplots@sloped@allowupsidedown + \else + % do not allow upside down labels: + \global\pgf@x=-\pgf@x% + \global\pgf@y=-\pgf@y% + \fi \fi% % \pgf@ya=-\pgf@y% @@ -1136,6 +1488,7 @@ \pgftransformcm% {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}% {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}% + \fi } @@ -1194,6 +1547,10 @@ }% % this does the work for \pgfplotsdeclareborderanchorforaxis. +% +% It depends on \pgfplotspointunit[xyz] and +% \pgfplotspointouternormalvectorofaxis +% % #1: either x,y or z the direction which varies % #2: a three-char-string uniquely identifying the axis line. % The parameter '#1' is redundand: it is the same as the 'v' @@ -1310,31 +1667,48 @@ \pgf@ya=\pgf@y \pgf@pos@transform\pgf@xa\pgf@ya % - \edef\pgfplots@LEQ{% - % solve linear system - {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xa}% - {\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@ya}% - }% - % - % apply inverse matrix to right-hand-side (and compute RHS): - \pgf@sh@reanchor{#3}{center}% - \edef\pgfplots@loc@center{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% - \pgfpointdiff% {<start>}{<end>} -> computes <end> - <start> - {\pgfplots@loc@center}% - {\pgf@sh@reanchor{#3}{\pgfplots@anchor}}% - \edef\pgfplots@RHS{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}% - % - \pgfutilsolvetwotwoleq{\pgfplots@LEQ}{\pgfplots@RHS}% - \def\pgfplots@extract##1##2{% - \def\pgfplots@r{##1}% - }% - \expandafter\pgfplots@extract\pgfmathresult - % GOT IT! - % - % compute x_c + r*n: - \pgfpointadd - {\pgfplots@loc@center}% - {\pgfqpointscale{\pgfplots@r}{\pgfplots@tmp@normaldir}}% + % verify that |n^T d | + \pgf@xc=\pgf@sys@tonumber\pgf@xa\pgf@xb + \advance\pgf@xc by\pgf@sys@tonumber\pgf@ya\pgf@yb + \ifdim\pgf@xc<0pt \pgf@xc=-\pgf@xc \fi + \ifdim\pgf@xc<0.8pt + % ok. 'n' and 'd' are not parallel. + % + \edef\pgfplots@LEQ{% + % solve linear system + % a11 a12 + % a21 a22 + {\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@xa}% + {\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@ya}% + }% + % + \pgf@sh@reanchor{#3}{center}% + \edef\pgfplots@loc@center{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% + % + % apply inverse matrix to right-hand-side (and compute RHS): + \pgfpointdiff% {<start>}{<end>} -> computes <end> - <start> + {\pgfplots@loc@center}% + {\pgf@sh@reanchor{#3}{\pgfplots@anchor}}% + \edef\pgfplots@RHS{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}% + % + \pgfutilsolvetwotwoleq{\pgfplots@LEQ}{\pgfplots@RHS}% + \def\pgfplots@extract##1##2{% + \def\pgfplots@r{##1}% + }% + \expandafter\pgfplots@extract\pgfmathresult + % GOT IT! + % + % compute x_c + r*n: + \pgfpointadd + {\pgfplots@loc@center}% + {\pgfqpointscale{\pgfplots@r}{\pgfplots@tmp@normaldir}}% + \else + \message{^^JPGFPlots warning: The ticklabel anchor cannot be determined, the normal vector -(\the\pgf@xb,\the\pgf@yb) and the unit #1 vector (\the\pgf@xa,\the\pgf@ya) are almost parallel (abs(cos(angle)) = \the\pgf@xc)!^^J}% + % Something went awry: normal and unit#1 are almost parallel!? + % just use the determined anchor. + \def\pgfplots@r{0}% + \pgf@sh@reanchor{#3}{\pgfplots@anchor}% + \fi %\message{==========>>>>>>>>>> I got finally (\the\pgf@x,\the\pgf@y). <<<<<<<<<===================}% \pgf@process{}% <- transport outside of group \endgroup @@ -1439,13 +1813,38 @@ \xdef\pgfplots@glob@TMPc{\noexpand\pgfqpointscale{-1}{\the\t@pgfplots@toka}}% \fi % + % Process 'plot box ratio': \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 }% + \def\pgfplots@extract@plot@box@ratio@spaces##1 ##2 ##3 ##4\pgfplots@EOI{% + \pgfplots@extract@plot@box@ratio{##1}{##2}{##3}{##4}\pgfplots@EOI + }% \pgfkeysgetvalue{/pgfplots/plot box ratio}\pgfplots@loc@TMPa - \expandafter\pgfplots@extract@plot@box@ratio\pgfplots@loc@TMPa{1}{1}{1}\pgfplots@EOI + % Auto-determine input format which is either '{x}{y}{z}' or 'x y z' + \def\pgfplots@loc@TMPb{% + \pgfutil@ifnextchar\bgroup{% + \pgfplots@loc@tmptrue + \pgfplots@gobble@until@EOI + }{% + \pgfplots@loc@tmpfalse + \pgfplots@gobble@until@EOI + }% + }% + \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPa\pgfplots@EOI + \ifpgfplots@loc@tmp + % Ah- braces format. + \edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa{1}{1}{1}}% + \expandafter\pgfplots@extract@plot@box@ratio\pgfplots@loc@TMPa\pgfplots@EOI + \else + % Ah- space-separated + \edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa\space 1 1 1}% + \expandafter\pgfplots@extract@plot@box@ratio@spaces\pgfplots@loc@TMPa\pgfplots@EOI + \fi + % + % process it: \ifdim\pgfplots@plotboxratio@x pt=1pt \else \t@pgfplots@toka=\expandafter{\pgfplots@glob@TMPa}% @@ -1468,7 +1867,7 @@ \pgfmathmultiply@{\cosaz}{\cosel}% \xdef\pgfplots@glob@TMPd{{\pgfmathresultNx}{\pgfmathresult}{\sinel}}% \endgroup -%\message{Setting x,y and z from {#1}{#2} to x = \meaning\pgfplots@glob@TMPa, y = \meaning\pgfplots@glob@TMPb, z = \meaning\pgfplots@glob@TMPc...n = \pgfplots@glob@TMPd.}% +%\message{Setting x,y and z from {#1}{#2} to^^J x = \meaning\pgfplots@glob@TMPa,^^J y = \meaning\pgfplots@glob@TMPb,^^J z = \meaning\pgfplots@glob@TMPc,^^J n = \pgfplots@glob@TMPd.^^J}% \pgfsetxvec{\pgfplots@glob@TMPa}% \pgfsetyvec{\pgfplots@glob@TMPb}% \pgfsetzvec{\pgfplots@glob@TMPc}% @@ -1479,16 +1878,60 @@ }% \expandafter\pgfplots@loc@TMPa\pgfplots@glob@TMPd\relax \def#3{0}% + \pgfplots@scale@plotbox@to@widthheight +}% + +\def\message@pgfplots@units{% + \begingroup + \pgfmathparse{veclen(\pgf@zx,\pgf@zy)}\let\Z=\pgfmathresult + \ifdim\Z pt=0pt + \def\Z{1}% + \fi + \pgfmathparse{veclen(\pgf@xx,\pgf@xy)/\Z}\let\X=\pgfmathresult + \pgfmathparse{veclen(\pgf@yx,\pgf@yy)/\Z}\let\Y=\pgfmathresult + \message{^^J + x = (\the\pgf@xx,\the\pgf@xy),^^J + y =(\the\pgf@yx,\the\pgf@yy),^^J + z = (\the\pgf@zx,\the\pgf@zy),^^J + \expandafter\ifx\csname pgfplots@view@dir@threedim@x\endcsname\relax + \else + n = (\pgfplots@view@dir@threedim@x,\pgfplots@view@dir@threedim@y,\pgfplots@view@dir@threedim@z),^^J + \fi + unit vector ratio=[\X\space\Y\space 1],^^J}% + \endgroup +}% + +% Takes the current plot box, defined by the actual PGF x,y and z unit +% vectors, and re-scales it such that it fits into the +% width and height of the axis (as they have been provided by the +% user). +% +% @see \pgfplots@scale@axisbox@to@widthheight +% @see\pgfplots@scaleaxes@to@BB +\def\pgfplots@scale@plotbox@to@widthheight{% \pgfplots@initsizes@get@width@withoutlabels \let\pgfplots@loc@TMPa=\pgfmathresult \pgfplots@initsizes@get@height@withoutlabels \edef\pgfplots@loc@TMPa{{\pgfplots@loc@TMPa}{\pgfmathresult}}% + \let\pgfplots@BB@for@plotbox=\pgfplots@BB@for@plotbox@relative + \let\pgfplots@BB@for@plotbox@compute@post@scales=\pgfplots@BB@for@plotbox@compute@post@scales@relative \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).}% -}% +} + + +% A variant of \pgfplots@scale@plotbox@to@widthheight which does not +% use the given x,y,z vectors to define the plot box. Instead, it uses +% the lower and upper axis limits. +\def\pgfplots@scale@axisbox@to@widthheight{% + \pgfplots@initsizes@get@width@withoutlabels + \let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplots@initsizes@get@height@withoutlabels + \edef\pgfplots@loc@TMPa{{\pgfplots@loc@TMPa}{\pgfmathresult}}% + \let\pgfplots@BB@for@plotbox=\pgfplots@BB@for@plotbox@computelimits + \let\pgfplots@BB@for@plotbox@compute@post@scales=\pgfplots@BB@for@plotbox@compute@post@scales@NOP + \expandafter\pgfplots@scaleaxes@to@BB\pgfplots@loc@TMPa +} + % 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. @@ -1513,10 +1956,27 @@ % - the @veclength and @inverseveclength have been re-scaled as % well. \def\pgfplots@scaleaxes@to@BB#1#2{% - \begingroup - \pgfinterruptboundingbox - % STEP 1: compute the bounding box for UNITS. We just need the - % relative sizes: +%\message{before scaling:}\message@pgfplots@units + \if0\pgfplots@scale@mode@choice + % scale mode=auto + \def\pgfplots@scale@mode@choice{2}% stretch to fill + \fi + \if1\pgfplots@scale@mode@choice + % scale mode=none + \else + \pgfplots@scaleaxes@to@BB@{#1}{#2}% + \fi + % FIXME + % I suppose I should call \pgfplotsgetnormalforcurrentview now? + \pgfplots@computeunitvectorlengths +%\message{after scaling:}\message@pgfplots@units +}% +\def\pgfplots@BB@for@plotbox@relative{% + % We just need the + % relative sizes, i.e. + % "0" == lower axis limit + % "1" == upper axis limit + % \ifpgfplots@threedim \pgfpathmoveto{\pgfqpointxyz000}% \pgfpathmoveto{\pgfqpointxyz001}% @@ -1532,6 +1992,63 @@ \pgfpathmoveto{\pgfqpointxy10}% \pgfpathmoveto{\pgfqpointxy11}% \fi +}% +\let\pgfplots@BB@for@plotbox=\pgfplots@BB@for@plotbox@relative +\def\pgfplots@BB@for@plotbox@compute@post@scales@relative#1#2#3{% + % Consequently, we have to multiply with 1/(max-min): + \pgfmathsubtract@{\pgfplots@xmax}{\pgfplots@xmin}% + % compute 1/(xmax - xmin) in float for more recent versions (see /pgfplots/compat/scaling). + % I observed that it is much more accurate + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{parsenumber}{\pgfmathresult}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{op}{reciprocal}{{\pgfmathresult}}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{tofixed}{\pgfmathresult}% + \let#1=\pgfmathresult + % + \pgfmathsubtract@{\pgfplots@ymax}{\pgfplots@ymin}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{parsenumber}{\pgfmathresult}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{op}{reciprocal}{{\pgfmathresult}}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{tofixed}{\pgfmathresult}% + \let#2=\pgfmathresult + % + \ifpgfplots@threedim + \pgfmathsubtract@{\pgfplots@zmax}{\pgfplots@zmin}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{parsenumber}{\pgfmathresult}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{op}{reciprocal}{{\pgfmathresult}}% + \pgfplotscoordmath{\pgfplots@compat@scaling@coordmath}{tofixed}{\pgfmathresult}% + \else + \def\pgfmathresult{1}% + \fi + \let#3=\pgfmathresult +}% +\let\pgfplots@BB@for@plotbox@compute@post@scales=\pgfplots@BB@for@plotbox@compute@post@scales@relative +\def\pgfplots@BB@for@plotbox@computelimits{% + \ifpgfplots@threedim + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmin\pgfplots@ymin\pgfplots@zmin}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmin\pgfplots@ymin\pgfplots@zmax}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmin\pgfplots@ymax\pgfplots@zmin}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmin\pgfplots@ymax\pgfplots@zmax}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmax\pgfplots@ymin\pgfplots@zmin}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmax\pgfplots@ymin\pgfplots@zmax}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmax\pgfplots@ymax\pgfplots@zmin}% + \pgfpathmoveto{\pgfqpointxyz\pgfplots@xmax\pgfplots@ymax\pgfplots@zmax}% + \else + \pgfpathmoveto{\pgfqpointxy\pgfplots@xmin\pgfplots@ymin}% + \pgfpathmoveto{\pgfqpointxy\pgfplots@xmin\pgfplots@ymax}% + \pgfpathmoveto{\pgfqpointxy\pgfplots@xmax\pgfplots@ymin}% + \pgfpathmoveto{\pgfqpointxy\pgfplots@xmax\pgfplots@ymax}% + \fi +}% +\def\pgfplots@BB@for@plotbox@compute@post@scales@NOP#1#2#3{% + \let#1=\pgfutil@empty + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty +}% +\def\pgfplots@scaleaxes@to@BB@#1#2{% + \begingroup + \pgfinterruptboundingbox + % STEP 1: compute the bounding box for the plot box. + \pgfplots@BB@for@plotbox + % % TMPa = width \pgf@xa=\pgf@pathmaxx \advance\pgf@xa by-\pgf@pathminx @@ -1541,62 +2058,156 @@ \pgf@ya=#1\relax \pgf@yb=#2\relax %\message{PGFPLOTS: the current unit vectors result in a UNIT BB of (\the\pgf@xa,\the\pgf@xb). Scaling it to (\the\pgf@ya,\the\pgf@yb)...}% - % STEP 2: compute the scales for x and y such - % that the UNIT-BB will have size #1,#2: - \pgfplotsutil@edef@invoke\pgfmathdivide@{% - {\pgf@sys@tonumber\pgf@ya}% - {\pgf@sys@tonumber\pgf@xa}% - }% - % TMPa = scalex - \global\let\pgfplots@glob@TMPa=\pgfmathresult - \pgfplotsutil@edef@invoke\pgfmathdivide@{% - {\pgf@sys@tonumber\pgf@yb}% - {\pgf@sys@tonumber\pgf@xb}% - }% - % TMPb = scaley - \global\let\pgfplots@glob@TMPb=\pgfmathresult + \ifcase\pgfplots@scale@mode@choice + % scale mode=auto does not happen here + \or + % scale mode=none does not happen here + \or + % scale mode=stretch to fill + % Compute individual scaling factors for X and Y + % such that the UNIT-BB will have size #1,#2: + \pgfplotsutil@edef@invoke\pgfmathdivide@{% + {\pgf@sys@tonumber\pgf@ya}% + {\pgf@sys@tonumber\pgf@xa}% + }% + % TMPa = scalex + \global\let\pgfplots@glob@TMPa=\pgfmathresult + \pgfplotsutil@edef@invoke\pgfmathdivide@{% + {\pgf@sys@tonumber\pgf@yb}% + {\pgf@sys@tonumber\pgf@xb}% + }% + % TMPb = scaley + \global\let\pgfplots@glob@TMPb=\pgfmathresult + \global\let\pgfplots@glob@TMPc=\relax + \or + % scale mode=scale uniformly + % compute ONE common scale for both, X and Y. + % + \pgfplotsutil@edef@invoke\pgfmathdivide@{% + {\pgf@sys@tonumber\pgf@ya}% + {\pgf@sys@tonumber\pgf@xa}% + }% + \global\let\pgfplots@glob@TMPa=\pgfmathresult + \global\let\pgfplots@glob@TMPb=\pgfplots@glob@TMPa + \global\let\pgfplots@glob@TMPc=\relax + \ifdim\pgf@zy=0pt + \ifdim\pgf@yx=0pt + \pgfplots@prepare@vertical@rescaling@for@scale@uniformly@in@dir{y}\returninto\pgfplots@glob@TMPc + \else + \pgfplots@error@scale@uniformly@failed + \fi + \else + \ifdim\pgf@zx=0pt + \pgfplots@prepare@vertical@rescaling@for@scale@uniformly@in@dir{z}\returninto\pgfplots@glob@TMPc + \else + \pgfplots@error@scale@uniformly@failed + \fi + \fi + \fi \pgfusepath{discard}% \endpgfinterruptboundingbox \endgroup -%\message{got scalex = \pgfplots@glob@TMPa\space and scaley = \pgfplots@glob@TMPb.}% - \pgfmathsubtract@{\pgfplots@xmax}{\pgfplots@xmin}% - % compute 1/(xmax - xmin) in float. - % I observed that it is much more accurate (lead to scaling differences of up to 10pt!) - \pgfmathfloatparsenumber\pgfmathresult - \pgfmathfloatreciprocal@\pgfmathresult - \pgfmathfloattofixed\pgfmathresult - %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% -%\message{and 1/(xmax-xmin) = 1/(\pgfplots@xmax-\pgfplots@xmin) = \pgfmathresult.}% + % Ok, we know the W,H scalings now. + % + % But remember that we have worked with RELATIVE scales up to now. + % We have to convert them now, by interpreting "1 == upper limit" + % and "0 == lower limit" for every direction. + % + \pgfplots@BB@for@plotbox@compute@post@scales{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}{\pgfplots@loc@TMPc}% + % + % ok. Now apply all scalings. + % Let's hope all these temporary macros are still valid! +%\message{got scaleW = \pgfplots@glob@TMPa\space and scaleH = \pgfplots@glob@TMPb; scalex=\pgfplots@loc@TMPa, scaley=\pgfplots@loc@TMPb, scalez=\pgfplots@loc@TMPc.}% \pgf@xx=\pgfplots@glob@TMPa\pgf@xx \pgf@xy=\pgfplots@glob@TMPb\pgf@xy - \pgf@xx=\pgfmathresult\pgf@xx - \pgf@xy=\pgfmathresult\pgf@xy + \pgf@xx=\pgfplots@loc@TMPa\pgf@xx + \pgf@xy=\pgfplots@loc@TMPa\pgf@xy % - \pgfmathsubtract@{\pgfplots@ymax}{\pgfplots@ymin}% - \pgfmathfloatparsenumber\pgfmathresult - \pgfmathfloatreciprocal@\pgfmathresult - \pgfmathfloattofixed\pgfmathresult - %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% -%\message{and 1/(ymay-ymin) = 1/(\pgfplots@ymax-\pgfplots@ymin) = \pgfmathresult.}% \pgf@yx=\pgfplots@glob@TMPa\pgf@yx \pgf@yy=\pgfplots@glob@TMPb\pgf@yy - \pgf@yx=\pgfmathresult\pgf@yx - \pgf@yy=\pgfmathresult\pgf@yy + \pgf@yx=\pgfplots@loc@TMPb\pgf@yx + \pgf@yy=\pgfplots@loc@TMPb\pgf@yy % \ifpgfplots@threedim - \pgfmathsubtract@{\pgfplots@zmax}{\pgfplots@zmin}% - \pgfmathfloatparsenumber\pgfmathresult - \pgfmathfloatreciprocal@\pgfmathresult - \pgfmathfloattofixed\pgfmathresult - %\expandafter\pgfmath@basic@reciprocal@\expandafter{\pgfmathresult}% -%\message{and 1/(zmaz-zmin) = 1/(\pgfplots@zmax-\pgfplots@zmin) = \pgfmathresult.}% \pgf@zx=\pgfplots@glob@TMPa\pgf@zx \pgf@zy=\pgfplots@glob@TMPb\pgf@zy - \pgf@zx=\pgfmathresult\pgf@zx - \pgf@zy=\pgfmathresult\pgf@zy - \fi - \pgfplots@computeunitvectorlengths -}% + \pgf@zx=\pgfplots@loc@TMPc\pgf@zx + \pgf@zy=\pgfplots@loc@TMPc\pgf@zy + \fi + \pgfplots@glob@TMPc +}% + +\def\pgfplots@error@scale@uniformly@failed{% + \pgfplots@error{Sorry, 'scale uniformly' failed because its actual implementation works only if y_x = 0 (for 2d axes) or if z_x = 0 (for 3d axes). The result will not fill the prescribed dimensions. For 2d axes, you may also want to consider the 'unit vector ratio' key}% +}% +\def\pgfplots@prepare@vertical@rescaling@for@scale@uniformly@in@dir#1\returninto#2{% + % The strategy is as follows: + % 1. I want to fit the axis into width #1 (\pgf@ya) and + % height #1 (\pgf@yb). + % 2. I want to MAINTAIN the unit vector ratio. + % 3. I want to MAINTAIN the unit vector directions. + % + % I already know the scaling factor to fit the width (it + % is stored in \pgfplots@glob@TMPa = \pgfplots@glob@TMPb). + % Let's call it "s". + % + % Consequently, a uniform scaling by "s" leads the image + % height + % h = s* (r_x * e_xy + r_y * e_yy + r_z * e_zy) + % where r_i = (imax - imin). This here is essentially the + % same as the bounding box computation above (at least for + % standart orthographic 3D axes). + % + % What I want now is to enlarge the limits such that I + % have BOTH, width #1 AND height #2, without obscuring the + % unit vector ratio. Recall that width #1 is already + % given. + % + % In my opinion the ONLY way to achieve this goal is to + % modify axis limits for an axis whose unit vector is + % parallel to the canvas y axis, i.e. e_i = (0,*). To see + % this, remember that a rescaling of the other limits will + % also modify the width. + % + % That means I have to introduce a SECOND scale s_z which + % applies only to the Z unit vector (since e_z = (0,*) ). + % If H = #2 is the desired height, I find the target + % equation for s_z, + % + % H = s* r_x e_xy + s * r_y e_yy + s_z * s * r_z * e_zy + % => + % s_z = ( H- s*r_x e_xy - s*r_y e_yy) / ( s * r_z * e_zy). + % + % Remember that + % s = \pgfplots@glob@TMPa + % and + % \pgfplots@glob@TMPa * \pgf@xb = s*h + % + \pgf@xc=\csname pgfplots@#1max\endcsname\csname pgf@#1y\endcsname% FIXME : what if we are working with relative coords? + \advance\pgf@xc by -\csname pgfplots@#1min\endcsname\csname pgf@#1y\endcsname + % + \advance\pgf@xb by-\pgf@xc + \pgf@xb=\pgfplots@glob@TMPa\pgf@xb + \advance\pgf@yb by-\pgf@xb + \pgf@xb=\pgfplots@glob@TMPa\pgf@xc + \pgfplotsutil@edef@invoke\pgfmathdivide@{% + {\pgf@sys@tonumber\pgf@yb}% + {\pgf@sys@tonumber\pgf@xb}% + }% + % Now, s_z = \pgfmathresult . + % + % Now, adjust the z limits. + % Note that \pgfplots@apply@unit@vector@rescale@keep@size + % has a slightly different context; it assumes that the + % unit vector has been rescaled, not the axis limits. + % Consequently, the inverse of the scaling factor enters. + % Since \pgfplots@apply@unit@vector@rescale@keep@size + % expects the inverse of the scale, we can provide + % \pgfmathresult: + \xdef#2{% + \noexpand\pgfplots@apply@unit@vector@rescale@keep@size{#1}{\pgfmathresult}% + }% +} \def\pgfplots@computeunitvectorlengths{% \pgfplotsutil@edef@invoke\pgfmathveclen@{% @@ -1641,6 +2252,746 @@ \fi }% +% Defines \pgfplots@view@dir@threedim@[xyz] according to the actual +% configuration of x,y,z (2d) unit vectors, assuming the associated +% unit vectors form a right-handed-system. +% +% The algorithm works for standard three dimensional axes. It works as +% follows: +% +% First, observe that we have a normal direction N if all its +% multiples are on the mapped onto the same point in 2D canvas +% coordinates. In other words: all 3D coordinates which are mapped +% onto an arbitrary point in 2D canvas coordinates (take, for example, +% the origin (0,0) ) are on a line in direction of N. +% +% We use this observation to compute the normal axis, i.e. we search +% for all points which are mapped onto the 2D canvas coordinate (0,0): +% N_x e_xx + N_y e_yx + N_z e_zx = 0 +% N_x e_xy + N_y e_yy + N_z e_zy = 0. +% All solutions make up a linear space of dimension 1 (up to special +% cases). In the general case, we can chose an arbitrary N_z != 0 +% and reduce the linear system to +% N_x e_xx + N_y e_yx = - N_z e_zx +% N_x e_xy + N_y e_yy = - N_z e_zy. +% Choosing *any* N_z != 0, say, N_z=-1 (which corresponds to view +% from above) will lead to a vector parallel to the normal direction. +% But it might have the wrong sign. +% +% To find the correct sign for N, I have made several case +% distinctions to identify the cases when we have to multiply with -1. +% The key idea is to assume a right-handed-system of unit vectors; +% this is the condition which allows to determine the sign. +% +% Furthermore, I assume that e_z points to the top, i.e. that e_zy >0. +% Then, there are (mainly) four conditions on the signs of e_x and e_y +% which indicate that we are viewing from below and should switch the +% sign of N (keep in mind that our initial choice was N_z =-1, see above). +% +% The conditions can be identified by drawing a 3D box and +% identifying the corner which represents the lower left 3D limits. +% +% You can visualize these cases using +%-------------------------------------------------- +% \pgfplotsset{ +% separate axis lines, +% every outer x axis line/.append style= {-stealth}, +% every outer y axis line/.append style= {-stealth}, +% every outer z axis line/.append style= {-stealth}, +% samples=2,shader=interp,title={view=\h,\v}, +% domain=0:1, +% enlargelimits=false, +% view=\h\v,xlabel=x,ylabel=y, +% extra description/.code={% +% \node[draw,fill=white] at (axis cs:0,0,0) {}; +% }, +% } +% +% \def\v{30} +% \foreach \h in {30,120,210,300} { +% \message{VIEW={\h}{\v}^^J} +% \begin{tikzpicture} +% \begin{axis} +% \addplot3[surf] {x}; +% \end{axis} +% \end{tikzpicture} +% +% } +% +% \def\v{-30} +% \foreach \h in {30,120,210,300} { +% \message{VIEW={\h}{\v}^^J} +% \begin{tikzpicture} +% \begin{axis} +% \addplot3[surf] {x}; +% \end{axis} +% \end{tikzpicture} +% +% } +%-------------------------------------------------- +% The precise formulas can be found below in the source code. +% +% You can override this function by the /pgfplots/view dir key. +\def\pgfplotsgetnormalforcurrentview{% + \pgfkeysgetvalue{/pgfplots/view dir}\pgfplots@loc@TMPc + \ifx\pgfplots@loc@TMPc\pgfutil@empty + \begingroup + \xdef\pgfplots@view@dir@threedim@z{-1}% hold it at some arbitrary value + \pgf@xa=-\pgfplots@view@dir@threedim@z\pgf@zx + \pgf@ya=-\pgfplots@view@dir@threedim@z\pgf@zy + \edef\pgfplots@loc@TMPa{% + {% + {\pgf@sys@tonumber\pgf@xx}{\pgf@sys@tonumber\pgf@yx}% + {\pgf@sys@tonumber\pgf@xy}{\pgf@sys@tonumber\pgf@yy}% + }% + {% + {\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}% + }% + }% + \expandafter\pgfutilsolvetwotwoleq\pgfplots@loc@TMPa + \def\pgfplots@loc@TMPb##1##2{% + \xdef\pgfplots@view@dir@threedim@x{##1}% + \xdef\pgfplots@view@dir@threedim@y{##2}% + }% + \expandafter\pgfplots@loc@TMPb\pgfmathresult + % + % Identify if we need to switch the sign. + % To verify that these cases are useful, I suggest visualizing + % that stuff using the TeX code from above... + % + % I guess it is correct up to collapsing views (as you see, I + % did not properly identify the cases with "=0" ) + \def\pgfplots@scale{1}% + \ifdim\pgf@xx>0pt + \ifdim\pgf@yx>0pt + % + \ifdim\pgf@xy>0pt + \ifdim\pgf@yy<0pt + \def\pgfplots@scale{-1}% + \fi + \fi + % + \fi + \else + \ifdim\pgf@xx<0pt + \ifdim\pgf@yx<0pt + % + \ifdim\pgf@xy<0pt + \ifdim\pgf@yy>0pt + \def\pgfplots@scale{-1}% + \fi + \fi + % + \fi + \fi + \fi + \ifdim\pgf@xy>0pt + \ifdim\pgf@yy>0pt + % + \ifdim\pgf@xx<0pt + \ifdim\pgf@yx>0pt + \def\pgfplots@scale{-1}% + \fi + \fi + % + \fi + \else + \ifdim\pgf@xy<0pt + \ifdim\pgf@yy<0pt + % + \ifdim\pgf@xx>0pt + \ifdim\pgf@yx<0pt + \def\pgfplots@scale{-1}% + \fi + \fi + % + \fi + \fi + \fi + \pgfmathmultiply@{\pgfplots@scale}{\pgfplots@view@dir@threedim@x}% + \global\let\pgfplots@view@dir@threedim@x\pgfmathresult + \pgfmathmultiply@{\pgfplots@scale}{\pgfplots@view@dir@threedim@y}% + \global\let\pgfplots@view@dir@threedim@y\pgfmathresult + \pgfmathmultiply@{\pgfplots@scale}{\pgfplots@view@dir@threedim@z}% + \global\let\pgfplots@view@dir@threedim@z\pgfmathresult + \endgroup + \else + \def\pgfplots@loc@TMPb##1##2##3{% + \xdef\pgfplots@view@dir@threedim@x{##1}% + \xdef\pgfplots@view@dir@threedim@y{##2}% + \xdef\pgfplots@view@dir@threedim@z{##3}% + }% + \expandafter\pgfplots@loc@TMPb\pgfplots@loc@TMPc + \fi +%\message{\string\pgfplotsgetnormalforcurrentview: got (\pgfplots@view@dir@threedim@x,\pgfplots@view@dir@threedim@y,\pgfplots@view@dir@threedim@z)^^J}% +}% + +% ================================================================================== +% +% COORDINATE MATH. +% +% ================================================================================== + +% Declares a new "subclass" to perform coordinate math. +% +% Coordinate math usually needs a more powerful number format than the pgf +% basic layer, or at least a powerful mapping into the pgf basic +% layer. Both cases are realized by the coordinate math class. +% +% Different coordinates can use different instances, and it is also +% possible to use yet a further instance for point meta (or whatever). +% +% Coordinate math is used to compute axis limits and to map the range +% into the pgf number format. +% +% It is *not* necessarily used for \pgfmathparse, since switching +% the number format of \pgfmathparse is quite involved (at the time of +% this writing). Instead, it is used for *single* operations (like +% max, min, multiply, add). +% +% #1: the name of the coord math class +% #2: methods to override the default. +% +% The available methods are documented and shown below in the +% \pgfqkeys listing. +% +% @see the predefined examples, also shown below. +\def\pgfplotsdeclarecoordmath#1#2{% + \edef\pgfplotsdeclarecoordmath@{@#1@}% + \pgfqkeys{/pgfplots/@declare coord math}{% + initialise=, + parse=\pgfmathparse{##1}, + parsenumber=\pgfmathfloatparsenumber{##1}\pgfmathfloattofixed{##1},% + zero= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{0}, + one= \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{1}, + log e= \pgfmathlog@{##1},% + log to display log=\pgfmath@basic@multiply@{##1}{2.3025851},% * log(10) + log from display log=\pgfmath@basic@multiply@{##1}{0.434294},% / log(10) + log unsigned int={% + \edef\pgfmathresult{% + \ifcase##1 + \or0 + \or0.693147 + \or1.098612 + \or1.386294 + \or1.60943791 + \or1.7917594 + \or1.94591014 + \or2.07944154 + \or2.197224 + \fi + }% + }, + set log basis=\edef\pgfmathresult{{#1}{##1}}\expandafter\pgfplotscoordmath@log@set@basis\pgfmathresult, + exp e={% + % make sure the exponential can be represented, i.e. use + % 'float' in the default repr: + \pgfmathfloatparsenumber{##1}% + \pgfmathfloatexp@\pgfmathresult% + \pgfplotscoordmath{\pgfplotscoordmathid}{parsenumber}{\pgfmathresult}% + }, + tofixed= \edef\pgfmathresult{##1},% + tostring= \edef\pgfmathresult{##1},% + max= \pgfplotsmathmax{##1}{##2},% + min= \pgfplotsmathmin{##1}{##2},% + min limit= \def\pgfmathresult{-16300},% + max limit= \def\pgfmathresult{16300},% + if less than= {\pgfplotsmathlessthan{##1}{##2}\ifpgfmathfloatcomparison ##3\else ##4\fi}, + if is= {% + \if##20 + \ifdim##1pt=0pt ##2\else ##3\fi + \else + \if##2+\ifdim##1pt>0pt ##2\else ##3\fi + \else + \if##2-\ifdim##1pt<0pt ##2\else ##3\fi + \else + \def\pgfplots@loc@TMPd{##1}\ifx\pgfplots@loc@TMPd\pgfutil@empty ##2\else ##3\fi + \fi + \fi + \fi + },% + if is bounded=\edef\pgfplotsretval{##1}\ifx\pgfplotsretval\pgfutil@empty ##3\else ##2\fi, + suffix= #1,% + datascaletrafo set params=, + datascaletrafo get params= \def\pgfmathresult{{}{}}, + datascaletrafo= \edef\pgfmathresult{##1}, + datascaletrafo inverse= \edef\pgfmathresult{##1}, + datascaletrafo noshift inverse= \edef\pgfmathresult{##1}, + datascaletrafo inverse to fixed= \edef\pgfmathresult{##1}, + datascaletrafo noshift inverse to fixed= \edef\pgfmathresult{##1}, + datascaletrafo noshift= \edef\pgfmathresult{##1}, + datascaletrafo noshift= \edef\pgfmathresult{##1}, + datascaletrafo undo shift= \edef\pgfmathresult{##1}, + datascaletrafo redo shift= \edef\pgfmathresult{##1}, + #2% + }% + \expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ op\endcsname##1##2{% + \noexpand\edef\noexpand\pgfplotscoordmath@{##2}% + \noexpand\expandafter\noexpand\expandafter\noexpand\csname pgfmath\csname pgfpmth@#1@suffix\endcsname ##1@\noexpand\endcsname\noexpand\pgfplotscoordmath@ + }% + % + % + % these log function depend on the first argument of + % \pgfplotscoordmath{}, which is available as + % \pgfplotscoordmathid. + \pgfplotsutilforeachcommasep{% + exp,% + log,% + log to display log,% + log from display log,% + log to log 10,% + log unsigned int}\as\pgfplots@loc@TMPa + {% + \expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@\pgfplots@loc@TMPa\endcsname{% + % invoke \pgfpmth@#1@@<name>@<function> + % for example + % \pgfpmth@pgfbasic@@y@log + \noexpand\csname pgfpmth\pgfplotsdeclarecoordmath@ @\noexpand\pgfplotscoordmathid @\pgfplots@loc@TMPa\noexpand\endcsname + }% + }% + % + \pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log}{% + \pgfutil@namelet + {pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log} + {pgfpmth\pgfplotsdeclarecoordmath@ log e}% + }{}% + \pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp}{% + \pgfutil@namelet + {pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp} + {pgfpmth\pgfplotsdeclarecoordmath@ exp e}% + }{}% + \pgfplotscoordmath@def@log@to@log@ten{#1}{}{tmpl}% empty arg + % +}% +\pgfqkeys{/pgfplots/@declare coord math}{% + initialise/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ initialise\endcsname{#1% + \pgfplotscoordmath@initialise@logs + }},% + % takes a number literal as input and defines \pgfmathresult to be + % the parsed result. + parsenumber/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parsenumber\endcsname##1{#1}},% + % + zero/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ zero\endcsname{#1}},% + one/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ one\endcsname{#1}},% + % + % Calls pgfmathparse. Note that this might need to switch to the + % required math library (which is not necessarily cheap) + parse/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ parse\endcsname##1{#1}},% + % + % takes a parsed number and returns a fixed point number: + tofixed/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tofixed\endcsname##1{#1}},% + % + % chooses a human readable string (which can be processed by parsenumber): + tostring/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tostring\endcsname##1{#1}},% + % + % defines a max routine which returns the max of *exactly* two numbers: + max/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max\endcsname##1##2{#1}},% + % + % counterpart for max: + min/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min\endcsname##1##2{#1}},% + % + % defines \pgfmathresult to be the largest supported number. + max limit/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ max limit\endcsname{#1}},% + % + % defines \pgfmathresult to be the smallest supported number. + min limit/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ min limit\endcsname{#1}},% + % + % computes ##1 < ##2 and invokes ##3 in the true case and ##4 in + % the false case. + if less than/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if less than\endcsname##1##2##3##4{#1}},% + % checks if ##1 is 0, positive, negative or unbounded + % ##1: the number to check + % ##2: either 0 or + or - or u (u = unbounded) + % ##3: true code + % ##4: false code + if is/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is\endcsname##1##2##3##4{#1}},% + % + % Checks if the argument ##1 is bounded and invokes ##2 in that + % case. IF the argument is unbounded, it invokes #3. + if is bounded/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ if is bounded\endcsname##1##2##3{#1}},% + % + % applies the natural logarithm. If the log is not defined, the + % argument is "unbounded", see 'if is bounded' + % + % 'log' is special in that it accepts a number literal which may + % be OUTSIDE of the accepted number format. The result, however, is + % then in the accepted number format. + log e/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ log e\endcsname##1{#1}},% + % + % Similar, but the log basis can be set with 'set log basis'. + % This allows \pgfplotscoordmath{x}{log}{} to use a different log + % basis thatn \pgfplotscoordmath{y}{log}{} (with special handling) + log/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log\endcsname##1{#1}},% + % applies a *scale* from the actual log basis to the actual + % *display* log basis. The display log basis is usually 10, unless + % the log basis has been changed. + log to display log/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to display log\endcsname##1{#1}},% + % applies a *scale* from the displau log basis to the actual + % log basis (the inverse of `log to display log'). + log from display log/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log from display log\endcsname##1{#1}},% + log to log 10/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to log 10\endcsname##1{#1}},% + % returns log(i) where i \in {1,2,3,...,basis-1} + % currently, it is only invoked for log basis 10 + log unsigned int/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log unsigned int\endcsname##1{#1}},% + % sets (changes) the actual log basis. + set log basis/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ set log basis\endcsname##1{#1}},% + % + % The inverse to 'log e '. + exp e/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ exp e\endcsname##1{#1}},% + % + % The inverse to 'log'. It also uses the correct log basis. + exp/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@exp\endcsname##1{#1}},% + % + % A macro taking two parameters: + % #1: the EXPONENT (as integer) + % #2: the SHIFT (as fixed point number) + % + % After any change, \pgfplotscoordmathnotifydatascalesetfor{<id>} will be + % invoked where <id> is the argument to + % \pgfplotscoordmath{<id>}... + datascaletrafo set params/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo set params\endcsname##1##2{% + #1\relax\pgfplotscoordmathnotifydatascalesetfor{\pgfplotscoordmathid}% + }},% + datascaletrafo set shift/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo set shift\endcsname##1{% + #1\relax\pgfplotscoordmathnotifydatascalesetfor{\pgfplotscoordmathid}% + }},% + % + % Defines \pgfmathresult to contain the two parameters required + % for 'datascaletrafo set params'. + datascaletrafo get params/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo get params\endcsname{#1}},% + datascaletrafo/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo\endcsname##1{#1}},% + datascaletrafo inverse/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo inverse\endcsname##1{#1}},% + datascaletrafo noshift inverse/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift inverse\endcsname##1{#1}},% + datascaletrafo inverse to fixed/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo inverse to fixed\endcsname##1{#1}},% + datascaletrafo noshift inverse to fixed/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift inverse to fixed\endcsname##1{#1}},% + datascaletrafo noshift/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift\endcsname##1{#1}},% + datascaletrafo noshift/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo noshift\endcsname##1{#1}},% + datascaletrafo undo shift/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo undo shift\endcsname##1{#1}},% + datascaletrafo redo shift/.code= + {\expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ datascaletrafo redo shift\endcsname##1{#1}},% + % + % defines a suffix such that + % \csname pgfmath<suffix><op>@\endcsname + % exists. Example: <suffix>=float --> \pgfmathfloatmultiply@ for <op>=multiply + suffix/.code= + {\expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ suffix\endcsname{#1}},% +}% + +\def\pgfplotscoordmath@initialise@logs{% + \edef\pgfplotsdeclarecoordmath@{@\pgfplotscoordmathclassfor{\pgfplotscoordmathid}@}% + \pgfutil@ifundefined{pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log}{% + \pgfplotsutilforeachcommasep{% + exp,% + log,% + log to display log,% + log from display log,% + log to log 10,% + log unsigned int}\as\pgfplots@loc@TMPa + {% + \pgfutil@namelet + {pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @\pgfplots@loc@TMPa} + {pgfpmth\pgfplotsdeclarecoordmath@ tmpl@\pgfplots@loc@TMPa}% + }% + }{}% +}% + +% shared implementation for 'set log basis' It works for every +% subclass. +\def\pgfplotscoordmath@log@set@basis#1#2{% + \edef\pgfplotsdeclarecoordmath@{@#1@}% + % + \pgfplotscoordmath{\pgfplotscoordmathid}{log e}{#2}% + \let\pgfplots@loc@TMPa=\pgfmathresult% TMPa = log_e(#2) + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{reciprocal}{{\pgfmathresult}}% + \let\pgfplots@loc@TMPb=\pgfmathresult% TMPb = 1/log_e(#2) + % + \expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log\endcsname##1{% + \noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{log e}{##1}% + \noexpand\ifx\noexpand\pgfmathresult\noexpand\pgfutil@empty + \noexpand\else + \noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{% + {\noexpand\pgfmathresult}% + {\pgfplots@loc@TMPb}% + }% + \noexpand\fi + }% + \expandafter\edef\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @exp\endcsname##1{% + \noexpand\edef\noexpand\pgfmathresult{##1}% + \noexpand\ifx\noexpand\pgfmathresult\noexpand\pgfutil@empty + \noexpand\else + \noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{% + {\noexpand\pgfmathresult}% + {\pgfplots@loc@TMPa}% + }% + \noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{exp e}{\noexpand\pgfmathresult}% + \noexpand\fi + }% + \expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log to display log\endcsname##1{\edef\pgfmathresult{##1}}% + \expandafter\def\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log from display log\endcsname##1{\edef\pgfmathresult{##1}}% + % + % compute 'log unsigned int' for the new basis. + % + % Idea: re-scale the old implementation (of basis e for i = 1,...,9) + % and re-compute i>=10 : + \begingroup + \expandafter\let\expandafter\logi\csname pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log unsigned int\endcsname + \let\logscale=\pgfplots@loc@TMPb + % + \logi{1}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@1\endcsname=\pgfmathresult + % + \logi{2}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@2\endcsname=\pgfmathresult + % + \logi{3}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@3\endcsname=\pgfmathresult + % + \logi{4}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@4\endcsname=\pgfmathresult + % + \logi{5}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@5\endcsname=\pgfmathresult + % + \logi{6}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@6\endcsname=\pgfmathresult + % + \logi{7}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@7\endcsname=\pgfmathresult + % + \logi{8}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@8\endcsname=\pgfmathresult + % + \logi{9}% + \pgfplotscoordmath{\pgfplotscoordmathid}{op}{multiply}{{\pgfmathresult}{\logscale}}% + \expandafter\let\csname logi@@9\endcsname=\pgfmathresult + % + \xdef\pgfplots@glob@TMPa##1{% + \noexpand\ifcase##1 + \noexpand\def\noexpand\pgfmathresult{}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@1\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@2\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@3\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@4\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@5\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@6\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@7\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@8\endcsname}% + \noexpand\or\noexpand\def\noexpand\pgfmathresult{\csname logi@@9\endcsname}% + \noexpand\else + \noexpand\pgfplotscoordmath{\pgfplotscoordmathid}{log}{##1}% + \noexpand\fi + }% + \endgroup + \expandafter\let\csname pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log unsigned int\endcsname=\pgfplots@glob@TMPa + \pgfplotscoordmath@def@log@to@log@ten{#1}\pgfplots@loc@TMPa{\pgfplotscoordmathid}% + % + \pgfutil@namelet + {pgfpmth\pgfplotsdeclarecoordmath@ @\pgfplotscoordmathid @log to log 10} + {pgfpmth\pgfplotsdeclarecoordmath@ tmpl@log to log 10}% +}% +% #1: the coord math class +% #2: either empty (basis e) or 1/ln(basis) +% #3: either 'tmpl' or '\pgfplotscoordmathid. It defines the target +% macro name (see the source code) +\def\pgfplotscoordmath@def@log@to@log@ten#1#2#3{% + \csname pgfpmth@#1@parsenumber\endcsname{0.434294}% + \edef\pgfplots@loc@TMPa{#2}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + % log basis e ---> log basis 10 + % log_10 x = log x / log(10) + \else + % log basis a ---> log basis 10 + % + % log_a x = log x / log a + % log_10 x = log_a x * log a / log(10) = log x / log(10) [OK] + \csname pgfpmth@#1@op\endcsname{multiply}{{#2}{\pgfmathresult}}% + \fi + \expandafter\edef\csname pgfpmth@#1@#3@log to log 10\endcsname##1{% + \noexpand\pgfplotscoordmath{\noexpand\pgfplotscoordmathid}{op}{multiply}{{##1}{\pgfmathresult}}% + }% +}% + +\pgfplotsdeclarecoordmath{pgfbasic}{% + parsenumber=\pgfmathfloatparsenumber{#1}\pgfmathfloattofixed\pgfmathresult, + suffix=@basic@, + zero=\def\pgfmathresult{0}, + one=\def\pgfmathresult{1}, +} +\pgfplotsdeclarecoordmath{float}{% + initialise= + \pgfutil@ifundefined{pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid}{% + \expandafter\edef\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname{0}% + \expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{0}% + }{}, + parsenumber=\pgfmathfloatparsenumber{#1}, + parse=\begingroup \pgfkeys{/pgf/fpu}\pgfmathparse{#1}\pgfmath@smuggleone\pgfmathresult\endgroup, + zero=\pgfmathfloatcreate{0}{0.0}{0},% + one=\pgfmathfloatcreate{1}{1.0}{0},% + tofixed=\pgfmathfloattofixed{#1}, + tostring=\pgfmathfloattosci{#1}, + max=\pgfplotsmathfloatmax{#1}{#2},% + min=\pgfplotsmathfloatmin{#1}{#2},% + max limit=\pgfmathfloatcreate{1}{1.0}{2147483645},% + min limit=\pgfmathfloatcreate{2}{1.0}{2147483645},% + log e=\pgfmathfloatparsenumber{#1}\pgfmathfloatln@{\pgfmathresult},% + if less than=\pgfmathfloatlessthan@{#1}{#2}\ifpgfmathfloatcomparison #3\else #4\fi, + if is bounded=% + \expandafter\pgfmathfloatgetflagstomacro\expandafter{#1}\pgfplotsretval + \ifnum\pgfplotsretval>2 #3\else #2\fi, + if is=% + \pgfmathfloatifflags{#1}{#2}{#3}{#4}, + log=\pgfmathlog@float{#1},% + datascaletrafo set params={% + \expandafter\edef\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname{#1}% + \expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{#2}% + },% + datascaletrafo set shift={% + \expandafter\edef\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname{#1}% + },% + datascaletrafo get params={% + \edef\pgfmathresult{% + {\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + {\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}% + }% + },% + datascaletrafo={% + \edef\pgfmathresult{#1}% + \pgfmathfloatshift@\pgfmathresult{\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + \pgfmathfloattofixed\pgfmathresult + \expandafter\pgfmath@basic@subtract@\expandafter{\pgfmathresult}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}% + },% + datascaletrafo noshift={% + \edef\pgfmathresult{#1}% + \pgfmathfloatshift@\pgfmathresult{\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + \pgfmathfloattofixed{\pgfmathresult}% + },% + datascaletrafo undo shift= + \pgfmath@basic@subtract@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname},% + datascaletrafo redo shift=\pgfmath@basic@add@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname},% + datascaletrafo inverse={% + \pgfplotscoordmath@float@datascaletrafo@inverse{#1}% + },% + datascaletrafo inverse to fixed={% + \pgfplotscoordmath@float@datascaletrafo@inverse{#1}% + \pgfmathfloattofixed\pgfmathresult + },% + datascaletrafo noshift inverse={% + \pgfmathfloatparsenumber{#1}% + \pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + },% + datascaletrafo noshift inverse to fixed={% + \pgfmathfloatparsenumber{#1}% + \pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + \pgfmathfloattofixed\pgfmathresult + },% +} + +\def\pgfplotscoordmath@float@datascaletrafo@inverse#1{% + \pgfmath@basic@add@{#1}{\csname pgfplots@data@scale@trafo@SHIFT@\pgfplotscoordmathid\endcsname}% + \let\pgfplots@inverse@datascaletrafo@@shifted=\pgfmathresult + \pgfmathapproxequalto@{\pgfplots@inverse@datascaletrafo@@shifted}{0.0}% + \ifpgfmathcomparison + \pgfmathfloatcreate{0}{0.0}{0}% + \else + \pgfmathfloatparsenumber{\pgfplots@inverse@datascaletrafo@@shifted}% + \pgfmathfloatshift@{\pgfmathresult}{-\csname pgfplots@data@scale@trafo@EXPONENT@\pgfplotscoordmathid\endcsname}% + \fi +}% + +% Invokes a coordinate math routine. +% +% #1: the axis (x,y or z) +% #2: a method name declared by \pgfplotsdeclarecoordmath (one of +% 'op', 'parsenumber', 'tofixed' etc) +% #3-#9: any further arguments required to perform the call to '#2'. +% +% \pgfplotscoordmath {x}{op}{multiply}{{<a>}{<b>}} +% \pgfplotscoordmath {x}{parsenumber}{<a>} +\def\pgfplotscoordmath#1#2{% + \edef\pgfplotscoordmathid{#1}% + \csname pgfpmth@\csname pgfcrdmth@#1\endcsname @#2\endcsname}% + +\def\pgfplotscoordmathclassfor#1{\csname pgfcrdmth@#1\endcsname}% + +\def\pgfplotscoordmathnotifydatascalesetfor#1{}% + +% Enables a particular coordinate math class for the label `#1'. +% +% #1 a label (usually x,y or z) +% #2 the coordinate math class (one prepare by +% \pgfplotsdeclarecoordmath) +% +% From this point on, any call to \pgfplotscoordmath{#1}{...} +% will use the selected math class. +\def\pgfplotssetcoordmathfor#1#2{% + \pgfutil@ifundefined{pgfpmth@#2@initialise}{% + \pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, \string\pgfplotssetcoordmathfor{#1}{#2} failed since `#2' is unknown. Maybe you misspelled it?}\pgfeov% + }{% + \expandafter\edef\csname pgfcrdmth@#1\endcsname{#2}% + \pgfplotscoordmath{#1}{initialise}% + }% +}% + +% Defines \pgfplotsretval to be the coordmath id for #1 +\def\pgfplotsgetcoordmathfor#1{% + \pgfutil@ifundefined{pgfcrdmth@#1}{% + \pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, \string\pgfplotsgetcoordmathfor{#1} failed since `#1' is unknown. Maybe you misspelled it?}\pgfeov% + }{% + \pgfutil@namelet{pgfplotsretval}{pgfcrdmth@#1}% + }% +}% +\pgfplotssetcoordmathfor{pgfbasic}{pgfbasic}% +\pgfplotssetcoordmathfor{float}{float}% +\pgfplotssetcoordmathfor{meta}{float}% +\pgfplotssetcoordmathfor{default}{float}% + + + +% ================================================================================== + + % #1 the name of an input method for point meta. It must have been % declared by \pgfplotsdeclarepointmetasource first. @@ -1654,59 +3005,55 @@ % Expands to the current value of 'point meta'. \def\pgfplotspointmetainputhandler{} +\def\pgfplotsaxisifhaspointmeta#1#2{% + \ifx\pgfplotspointmetainputhandler\pgfutil@empty #2\else #1\fi +}% + +% Invokes '#1' if the axis contains the coordinate designated by +% \pgfplots@current@point@[xyz] and '#2' if not. +\def\pgfplotsaxisifcontainspoint#1#2{% + \pgf@xa=\pgfplots@current@point@x pt % FIXME : SCOPE REGISTERS!? + \pgf@ya=\pgfplots@current@point@y pt % + \ifpgfplots@curplot@threedim + \pgf@yb=\pgfplots@current@point@z pt % + \fi + \def\pgfplots@loc@TMPa{#2}% + % + % I assume that \pgfplots@[xyz]min@reg and min@reg are registers + % containing the limits. + \ifdim\pgf@xa<\pgfplots@xmin@reg + \else + \ifdim\pgf@xa>\pgfplots@xmax@reg + \else + \ifdim\pgf@ya<\pgfplots@ymin@reg + \else + \ifdim\pgf@ya>\pgfplots@ymax@reg + \else + \ifpgfplots@curplot@threedim + \ifdim\pgf@yb<\pgfplots@zmin@reg + \else + \ifdim\pgf@yb>\pgfplots@zmax@reg + \else + \def\pgfplots@loc@TMPa{#1}% + \fi + \fi + \else + \def\pgfplots@loc@TMPa{#1}% + \fi + \fi + \fi + \fi + \fi + \pgfplots@loc@TMPa% +} + % Declares a routine which can be used to get point meta input. % % Such a routine is invoked in a context where point coordinates are % processed, i.e. during 'plot coordinates', 'plot table' or the like. % -% The routine is called `#1'. It consists of several methods: -% - \csname pgfpmeta@#1@assign\endcsname{} -% During the survey phase, this macro is expected to assign -% \pgfplots@current@point@meta -% if it is a numeric input method, it should return a -% floating point number. -% It is allowed to return an empty string to say "there is no point -% meta". -% PRECONDITION for '@assign': -% - the coordinate input method has already assigned its -% '\pgfplots@current@point@meta' (probably as raw input string). -% - the other input coordinates are already read. -% POSTCONDITION for '@assign': -% - \pgfplots@current@point@meta is ready for use: -% - EITHER a parsed floating point number -% - OR an empty string, -% - OR a symbolic string (if the issymbolic boolean is true) -% The default implementation is -% \let\pgfplots@current@point@meta=\pgfutil@empty -% -% - \csname pgfpmeta@#1@issymbolic\endcsname -> expands to either '1' or '0' -% A numeric source will be processed numerically in float -% arithmetics. Thus, the output of the @assign routine should be -% a macro \pgfplots@current@point@meta in float format. -% -% The output of a numeric point meta source will result in meta -% limit updates and the final map to [0,1000] will be -% initialised automatically. -% -% A symbolic input routine won't be processed. -% Default is '0' -% -% - \csname pgfpmeta@#1@explicitinput\endcsname -> expands to either -% '1' or '0'. In case '1', it expects explicit input from the -% coordinate input routines. For example, 'plot file' will look for -% further input after the x,y,z coordinates. -% Default is '0' -% -% - \csname pgfpmeta@#1@initfor\endcsname##1{....} -% a macro used to initialise the point meta source when it is -% selected. -% This macro body is invoked by pgfplots when someone types -% 'point meta=x' -> will invoke 'pgfpmeta@x@initfor{}'. -% The first argument to initfor can be supplied by the user. -% PRECONDITION for 'initfor': -% - it will be invoked just before -% '\pgfplotspointmetainputhandler' will be changed. -% Default is to do nothing. +% The routine is called `#1'. It consists of several methods, which +% are described below, in the key definitions. % % #1: the name of the input routine. % #2: a sequence of key-value pairs which can be used to overwrite @@ -1722,16 +3069,66 @@ \pgfqkeys{/pgfplots/@declare point meta src}{#2}% }% \pgfqkeys{/pgfplots/@declare point meta src}{% - assign/.code= - {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @assign\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. initfor/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @initfor\endcsname##1{#1}},% + % % Called during the survey phase before the first 'assign' call. % It is usually empty. activate/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @activate\endcsname{#1}},% + % + % During the survey phase, this macro is expected to assign + % \pgfplots@current@point@meta + % if it is a numeric input method, it should return a + % floating point number. + % It is allowed to return an empty string to say "there is no point + % meta". + % PRECONDITION for '@assign': + % - the coordinate input method has already assigned its + % '\pgfplots@current@point@meta' (probably as raw input string). + % - the other input coordinates are already read. + % POSTCONDITION for '@assign': + % - \pgfplots@current@point@meta is ready for use: + % - EITHER a parsed floating point number + % - OR an empty string, + % - OR a symbolic string (if the issymbolic boolean is true) + % The default implementation is + % \let\pgfplots@current@point@meta=\pgfutil@empty + % + assign/.code= + {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @assign\endcsname{#1}},% + % + % expands to either '1' or '0' + % A numeric source will be processed numerically in float + % arithmetics. Thus, the output of the @assign routine should be + % a macro \pgfplots@current@point@meta in float format. + % + % The output of a numeric point meta source will result in meta + % limit updates and the final map to [0,1000] will be + % initialised automatically. + % + % A symbolic input routine won't be processed. + % Default is '0' + % issymbolic/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @issymbolic\endcsname{#1}},% + % + % expands to either + % '1' or '0'. In case '1', it expects explicit input from the + % coordinate input routines. For example, 'plot file' will look for + % further input after the x,y,z coordinates. + % Default is '0' + % explicitinput/.code= {\expandafter\def\csname pgfpmeta@\pgfplotsdeclarepointmetasource@ @explicitinput\endcsname{#1}},% }% @@ -1741,31 +3138,25 @@ \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}} + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}% + \let\pgfplots@current@point@meta=\pgfmathresult + }} \pgfplotsdeclarepointmetasource{y}{assign={% \let\pgfplots@current@point@meta=\pgfplots@current@point@y - \ifpgfplots@yislinear - \else - \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% - \let\pgfplots@current@point@meta=\pgfmathresult - \fi}} + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}% + \let\pgfplots@current@point@meta=\pgfmathresult + }} \pgfplotsdeclarepointmetasource{z}{assign={% \let\pgfplots@current@point@meta=\pgfplots@current@point@z - \ifpgfplots@zislinear - \else - \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% - \let\pgfplots@current@point@meta=\pgfmathresult - \fi}} + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}% + \let\pgfplots@current@point@meta=\pgfmathresult + }} \pgfplotsdeclarepointmetasource{explicit}{% assign={% \ifx\pgfplots@current@point@meta\pgfutil@empty \else - \pgfmathfloatparsenumber{\pgfplots@current@point@meta}% + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@current@point@meta}% \let\pgfplots@current@point@meta=\pgfmathresult \fi }, @@ -1785,6 +3176,7 @@ \ifx\pgfplots@loc@TMPa\pgfutil@empty \else \pgfmathparse{\pgfplots@loc@TMPa}% + \pgfplotscoordmath{meta}{parsenumber}{\pgfmathresult}% \let\pgfplots@current@point@meta=\pgfmathresult \fi },% @@ -1813,13 +3205,12 @@ }, }% - \pgfplotsdeclarepointmetasource{TeX code}{% assign={% \begingroup \let\pgfplotspointmeta=\pgfutil@empty \pgfplots@invoke@pgfkeyscode{/pgfplots/point meta/code/.@cmd}{}% - \pgfmathfloatparsenumber{\pgfplotspointmeta}% + \pgfplotscoordmath{meta}{parsenumber}{\pgfplotspointmeta}% \let\pgfplots@current@point@meta=\pgfmathresult \pgfmath@smuggleone\pgfplots@current@point@meta \endgroup @@ -1859,15 +3250,7 @@ % copy operations. That experiment was not successfull (it was not % faster :-( ). However, the streaming methods still assign their % things globally... -\newif\ifpgfplots@coord@stream@isfirst \def\pgfplots@coord@stream@start{% - \global\pgfplots@coord@stream@isfirsttrue - \global\let\pgfplots@currentplot@firstcoord@x=\pgfutil@empty - \global\let\pgfplots@currentplot@firstcoord@y=\pgfutil@empty - \global\let\pgfplots@currentplot@firstcoord@z=\pgfutil@empty - \global\let\pgfplots@currentplot@lastcoord@x=\pgfutil@empty - \global\let\pgfplots@currentplot@lastcoord@y=\pgfutil@empty - \global\let\pgfplots@currentplot@lastcoord@z=\pgfutil@empty \let\pgfplots@current@point@x=\pgfutil@empty \let\pgfplots@current@point@y=\pgfutil@empty \let\pgfplots@current@point@z=\pgfutil@empty @@ -1888,15 +3271,24 @@ % \pgfplots@current@point@meta \def\pgfplots@coord@stream@coord{% \pgfplots@coord@stream@coord@% +}% +\def\pgfplotscoordstream@firstlast@init{% + \global\let\pgfplots@currentplot@firstcoord@x=\pgfutil@empty + \global\let\pgfplots@currentplot@firstcoord@y=\pgfutil@empty + \global\let\pgfplots@currentplot@firstcoord@z=\pgfutil@empty + \global\let\pgfplots@currentplot@lastcoord@x=\pgfutil@empty + \global\let\pgfplots@currentplot@lastcoord@y=\pgfutil@empty + \global\let\pgfplots@currentplot@lastcoord@z=\pgfutil@empty +}% +\def\pgfplotscoordstream@firstlast@update{% \ifx\pgfplots@current@point@x\pgfutil@empty % only one \if is enough as ONE empty coordinate results all % others to be reset as well. \else - \ifpgfplots@coord@stream@isfirst + \ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty \global\let\pgfplots@currentplot@firstcoord@x=\pgfplots@current@point@x \global\let\pgfplots@currentplot@firstcoord@y=\pgfplots@current@point@y \global\let\pgfplots@currentplot@firstcoord@z=\pgfplots@current@point@z - \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 @@ -1906,34 +3298,54 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% Scanline management. The idea is to allow a simple syntax -% to provide matrix input - by means of scanlines. +% Scanline management. The idea is to handle complete sequences of +% input coordinates, which are usually separated by a blank line. +% +% This allows a simple syntax to provide matrix input - by means of scanlines. +% Furthermore, 2d plots can use it to interrupt the display. % % An empty line in 'addplot coordinates {}' indicates the end of a % scan line. Similarly, an empty line in 'addplot file' or 'table' % also indicates the end of a scan line. % -% The following methods allow to update the scanline computation. +% The steps taken whenever a scan line is complete depend on the +% configuration of the /pgfplots/empty line choice key (queried in +% \pgfplotsscanlinelengthinitzero). +% +% +% The following methods constitute the scanline interface. % % Usage: % % \pgfplotsscanlinelengthinitzero % % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinecomplete % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinecomplete % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinelengthincrease +% <process point> % \pgfplotsscanlinecomplete % % \pgfplotsscanlinelengthcleanup % +% In other words, the \pgfplotsscanlinelengthincrease routine is +% invoked *before* the point is processed. That's important. +% % Now, \pgfplotsscanlinelength expands to either % a) a negative number in which case there is no % unique scanline length. @@ -1942,13 +3354,72 @@ % had different lengths. % b) the scanline length. \def\pgfplotsscanlinelengthinitzero{% + \def\pgfplotsscanlinelength{-1}% + \pgfkeysgetvalue{/pgfplots/empty line}\pgfplots@loc@TMPa% + \edef\pgfplots@loc@TMPa{\pgfplots@loc@TMPa}% + \def\pgfplots@loc@TMPb{auto}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \pgfplotsdetermineemptylinehandler + \pgfkeysgetvalue{/pgfplots/empty line}\pgfplots@loc@TMPa% + \fi + \def\pgfplots@loc@TMPb{jump}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \def\pgfplots@loc@TMPa{nan}% alias for jump + \fi + \def\pgfplots@loc@TMPb{no op}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \def\pgfplots@loc@TMPa{none}% alias for no op + \fi + \pgfutil@ifundefined{pgfplotsscanlinelength@\pgfplots@loc@TMPa @initzero}{% + \pgfplots@error{Sorry, the choice `empty line=\pgfkeysvalueof{/pgfplots/empty line}' is unknown. Maybe you misspelled it}% + }{}% + \expandafter\let\expandafter\pgfplotsscanlinelength@initzero \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @initzero\endcsname + \expandafter\let\expandafter\pgfplotsscanlinelengthincrease \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @increase\endcsname + \edef\pgfplotsscanlinecomplete{% + \expandafter\noexpand\csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @complete\endcsname + \noexpand\pgfplotsplothandlernotifyscanlinecomplete + }% + \expandafter\let\expandafter\pgfplotsscanlinelengthcleanup \csname pgfplotsscanlinelength@\pgfplots@loc@TMPa @cleanup\endcsname + \pgfplotsscanlinelength@initzero +}% + +\newif\ifpgfplots@emptyline@compat + +% Invoked for 'empty line=auto'. +% +% @POSTCONDITION: '/pgfplots/empty line' is set to something useful +% (not auto) +\def\pgfplotsdetermineemptylinehandler{% + \if n\pgfplots@meshmode + % no mesh/surf plot: + \pgfkeyssetvalue{/pgfplots/empty line}{jump}% + \ifpgfplots@emptyline@compat + \pgfkeyssetvalue{/pgfplots/empty line}{none}% do nothing for backwards compatibility with 2D processing. + \fi + \else + % it is a mesh or surf plot; use scanline: + \pgfkeyssetvalue{/pgfplots/empty line}{scanline}% + \fi +}% +\def\pgfplotsscanlinedisablechanges{% + \let\pgfplotsscanlinecomplete=\relax + \let\pgfplotsscanlinelengthincrease=\relax + \let\pgfplotsscanlinelengthcleanup=\relax + \let\pgfplotsscanlinelengthinitzero=\relax + \let\pgfplotsscanlineendofinput=\relax +}% + +% ------------------------------------------------------------------------------- +% empty line=scanline +% class: +\def\pgfplotsscanlinelength@scanline@initzero{% \c@pgfplots@scanlineindex=0 \def\pgfplots@scanlinelength{-1}% } -\def\pgfplotsscanlinelengthincrease{% +\def\pgfplotsscanlinelength@scanline@increase{% \advance\c@pgfplots@scanlineindex by1 } -\def\pgfplotsscanlinecomplete{% +\def\pgfplotsscanlinelength@scanline@complete{% \ifnum\pgfplots@scanlinelength>0 \ifnum\c@pgfplots@scanlineindex=0 % @@ -1973,7 +3444,7 @@ \fi \c@pgfplots@scanlineindex=0 } -\def\pgfplotsscanlinelengthcleanup{% +\def\pgfplotsscanlinelength@scanline@cleanup{% \ifnum\c@pgfplots@scanlineindex=0 % I assume the last scan line is already complete. \else @@ -1981,12 +3452,58 @@ \fi \let\pgfplotsscanlinelength=\pgfplots@scanlinelength } -\def\pgfplotsscanlinedisablechanges{% - \let\pgfplotsscanlinecomplete=\relax - \let\pgfplotsscanlinelengthincreas=\relax - \let\pgfplotsscanlinelengthcleanup=\relax - \let\pgfplotsscanlinelengthinitzero=\relax +% ------------------------------------------------------------------------------- +% +% empty line=none class: +% +\let\pgfplotsscanlinelength@none@initzero=\pgfutil@empty +\let\pgfplotsscanlinelength@none@increase=\relax +\let\pgfplotsscanlinelength@none@complete=\relax +\let\pgfplotsscanlinelength@none@cleanup=\relax +% ------------------------------------------------------------------------------- +% +% empty line=nan class: +\def\pgfplotsscanlinelength@nan@initzero{% + \def\pgfplotsscanlinelength@nan@isfirst{1}% + \let\pgfplotsscanlinelength@nan@pendingwork=\relax + \pgfplotsifinaxis{}{\let\pgfplotsaxisserializedatapoint=\relax}% +}% +\def\pgfplotsscanlinelength@nan@increase{% + \def\pgfplotsscanlinelength@nan@isfirst{0}% + \pgfplotsscanlinelength@nan@pendingwork +}% +\def\pgfplotsscanlinelength@nan@complete{% + \if1\pgfplotsscanlinelength@nan@isfirst + \else + \def\pgfplotsscanlinelength@nan@pendingwork{% + % this will be executed when the next point has been + % found. + \def\pgfplots@current@point@x{}% + \def\pgfplots@current@point@y{}% + \def\pgfplots@current@point@z{}% + % simply serialize an empty point. That works -- the + % visualization phase checks if the coordinates are empty and + % visualizes them as "jump" + % + % Note that \pgfplotsplothandlersurveypoint is not a good + % choice here unless one employs its 'unbounded coords=jump' + % feature + \def\pgfplotsaxisplothasjumps{1}% + \pgfplotsaxisserializedatapoint + % + \let\pgfplotsscanlinelength@nan@pendingwork=\relax + }% + \fi + \def\pgfplotsscanlinelength@nan@isfirst{1}% }% +\let\pgfplotsscanlinelength@nan@cleanup=\relax +% +% ------------------------------------------------------------------------------- + + +\def\pgfplotsaxisfilteredcoordsaway{0}% +\def\pgfplotsaxisplothasjumps{0}% +\newif\ifpgfplotsaxisparsecoordinateok % Initialises % \pgfplots@coord@stream@start @@ -2046,235 +3563,26 @@ % be as deep as necessary - as long as all operations have the % same level of scoping. % +% @see the detailed documentation in pgfplotsplothandlers.code.tex \long\def\pgfplots@PREPARE@COORD@STREAM#1{% \ifpgfplots@curplot@threedim \global\pgfplots@threedimtrue \fi + \def\pgfplotsaxisfilteredcoordsaway{0}% + \def\pgfplotsaxisplothasjumps{0}% % + \ifpgfplots@curplot@threedim + \let\pgfplotsaxisupdatelimitsforcoordinate=\pgfplotsaxisupdatelimitsforcoordinatethreedim + \let\pgfplotsaxisparsecoordinate=\pgfplotsaxisparsecoordinatethreedim + \else + \let\pgfplotsaxisupdatelimitsforcoordinate=\pgfplotsaxisupdatelimitsforcoordinatetwodim + \let\pgfplotsaxisparsecoordinate=\pgfplotsaxisparsecoordinatetwodim + \fi \begingroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \let\E=\noexpand % - % Setup Just-In-Time-Macro Compilation: - % I compile a set of macros which is highly optimized for this - % particular plot. - % - % 1.\pgfplots@update@limits@for@one@point - % Updates the current x and y limits for point (#1,#2). - % - % To eliminate all those case distinctions, it is created with - % 'edef' and a lot of '\noexpand' calls here: - % - % - % The point coordinates may be given in floating point format, see - % below. - % - % Please note that if user specified limits are given, automatic - % limits are only applied to points which fall into the user specified - % clipping region. - % - % PRECONDITIONS: - % - the input coordinates have been parsed correctly (floating point - % format for linear axis, log applied for logarithmic ones) - % - % Arguments: - % \pgfplots@current@point@[xyz] - \xdef\pgfplots@update@limits@for@one@point{% -%\E\tracingmacros=2\E\tracingcommands=2 -%\E\pgfplots@message{Updating limits for (\E\pgfplots@current@point@x,\E\pgfplots@current@point@y) ...}% - % - % VIM SEARCH PATTERN: - % [^E]\zs\\\ze[^E] - % -> this finds '\' which is neither '\E' nor is it prefixed - % by 'E'. - % - % - % - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDfalse - % check whether we need to clip limits: - \ifpgfplots@clip@limits - \ifpgfplots@autocompute@xmin - \else - \ifpgfplots@xislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@x}{\E\pgfplots@xmin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@current@point@x}{\E\pgfplots@xmin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \ifpgfplots@autocompute@xmax - \else - \ifpgfplots@xislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \ifpgfplots@autocompute@ymin - \else - \ifpgfplots@yislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@y}{\E\pgfplots@ymin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@current@point@y}{\E\pgfplots@ymin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \ifpgfplots@autocompute@ymax - \else - \ifpgfplots@yislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \ifpgfplots@curplot@threedim - \ifpgfplots@autocompute@zmin - \else - \ifpgfplots@zislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@current@point@z}{\E\pgfplots@zmin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@current@point@z}{\E\pgfplots@zmin}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \ifpgfplots@autocompute@zmax - \else - \ifpgfplots@zislinear - \E\pgfmathfloatlessthan@{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \else - \E\pgfplotsmathlessthan{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% - \E\ifpgfmathfloatcomparison - \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue - \E\fi - \fi - \fi - \fi - \fi - % - % - % - % Update limits: - \E\ifpgfplots@update@limits@for@one@point@ISCLIPPED - \E\else - \ifpgfplots@autocompute@xmin - \ifpgfplots@xislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@xmin}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult - \else - \E\pgfplotsmathmin{\E\pgfplots@xmin}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult - \fi - \fi - \ifpgfplots@autocompute@xmax - \ifpgfplots@xislinear - \E\pgfplotsmathfloatmax{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult - \else - \E\pgfplotsmathmax{\E\pgfplots@xmax}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult - \fi - \fi - \ifpgfplots@autocompute@ymin - \ifpgfplots@yislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@ymin}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult - \else - \E\pgfplotsmathmin{\E\pgfplots@ymin}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult - \fi - \fi - \ifpgfplots@autocompute@ymax - \ifpgfplots@yislinear - \E\pgfplotsmathfloatmax{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult - \else - \E\pgfplotsmathmax{\E\pgfplots@ymax}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult - \fi - \fi - \ifpgfplots@curplot@threedim - \ifpgfplots@autocompute@zmin - \ifpgfplots@zislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@zmin}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult - \else - \E\pgfplotsmathmin{\E\pgfplots@zmin}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult - \fi - \fi - \ifpgfplots@autocompute@zmax - \ifpgfplots@zislinear - \E\pgfplotsmathfloatmax{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@zmax=\E\pgfmathresult - \else - \E\pgfplotsmathmax{\E\pgfplots@zmax}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@zmax=\E\pgfmathresult - \fi - \fi - \fi - \E\fi - % - % Compute data range: - \ifpgfplots@autocompute@all@limits - % the data range will be acquired simply from the axis - % range, see below! - \else - % Attention: it is only done for linear axis! - \ifpgfplots@xislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@data@xmin}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@data@xmin=\E\pgfmathresult - \E\pgfplotsmathfloatmax{\E\pgfplots@data@xmax}{\E\pgfplots@current@point@x}% - \E\global\E\let\E\pgfplots@data@xmax=\E\pgfmathresult - \fi - \ifpgfplots@yislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@data@ymin}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@data@ymin=\E\pgfmathresult - \E\pgfplotsmathfloatmax{\E\pgfplots@data@ymax}{\E\pgfplots@current@point@y}% - \E\global\E\let\E\pgfplots@data@ymax=\E\pgfmathresult - \fi - \ifpgfplots@curplot@threedim - \ifpgfplots@zislinear - \E\pgfplotsmathfloatmin{\E\pgfplots@data@zmin}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@data@zmin=\E\pgfmathresult - \E\pgfplotsmathfloatmax{\E\pgfplots@data@zmax}{\E\pgfplots@current@point@z}% - \E\global\E\let\E\pgfplots@data@zmax=\E\pgfmathresult - \fi - \fi - \fi -%\E\pgfplots@message{Updated limits: (\E\pgfplots@xmin,\E\pgfplots@ymin) rectangle (\E\pgfplots@xmax,\E\pgfplots@ymax).}% -%\E\tracingmacros=0\E\tracingcommands=0 - }% -%\message{Assembled update-limits \ifpgfplots@curplot@threedim 3D\else 2D\fi macro to {\meaning\pgfplots@update@limits@for@one@point}}% +%\message{Assembled update-limits \ifpgfplots@curplot@threedim 3D\else 2D\fi macro to {\meaning\pgfplotsaxisupdatelimitsforcoordinate}}% \ifpgfplots@bb@isactive \else % we are inside of @@ -2282,205 +3590,107 @@ % .. % \endpgfinterruptboundingbox % -> don't change data limits! - \global\let\pgfplots@update@limits@for@one@point=\relax + \gdef\pgfplotsaxisupdatelimitsforcoordinate##1##2##3{}% \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % - % This here is the MAIN code of \pgfplots@process@one@point . - % It is inserted below into the right, into one of two prepared - % places. - \def\pgfplots@loc@surveypoint{% - \ifpgfplots@apply@datatrafo - \ifpgfplots@datascaletrafo@initialised - % apply data transformation directly. - \ifpgfplots@apply@datatrafo@x - \E\pgfplots@datascaletrafo@x\E\pgfplots@current@point@x - \E\let\E\pgfplots@current@point@x=\E\pgfmathresult - \fi - \ifpgfplots@apply@datatrafo@y - \E\pgfplots@datascaletrafo@y\E\pgfplots@current@point@y - \E\let\E\pgfplots@current@point@y=\E\pgfmathresult - \fi - \ifpgfplots@curplot@threedim - \ifpgfplots@apply@datatrafo@z - \E\pgfplots@datascaletrafo@z\E\pgfplots@current@point@z - \E\let\E\pgfplots@current@point@z=\E\pgfmathresult - \fi - \fi - \fi - \fi - % All following routines (limit updating/stacking/error - % bars) will use float numerics if necessary (controlled - % by ifs). - \ifpgfplots@stackedmode - \E\pgfplots@stacked@preparepoint@inmacro% - \ifpgfplots@datascaletrafo@initialised% is also true if there is no scale trafo. - \E\pgfplots@stacked@finishpoint - \else - % the finishpoint routine will be invoked at - % \endaxis. - \fi - \fi - % - % Prepare \pgfplots@current@point@meta (see the preparation - % routine above): - \E\pgfplots@set@perpointmeta - % - % update also axis / data limits: - % Arguments: \pgfplots@current@point@[xy] - \E\pgfplots@update@limits@for@one@point - \ifpgfplots@errorbars@enabled - % This thing gets the 'current@point@...' context, - % that means - % \pgfplots@current@point@[xy] - % \pgfplots@current@point@[xy]@error - % \pgfplots@current@point@[xy]@unfiltered - \E\pgfplots@PREPARE@errorbar@process@x% - \E\pgfplots@PREPARE@errorbar@process@y% - \E\pgfplots@PREPARE@errorbar@process@z% - \fi - % - \ifpgfplots@collect@firstplot@astick - \ifnum\pgfplots@numplots=0 - \E\ifx\E\pgfplots@firstplot@coords@x\E\pgfutil@empty - \E\t@pgfplots@tokc={}% - \E\else - \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@x,}% - \E\fi - \E\xdef\E\pgfplots@firstplot@coords@x{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@x}% - \E\ifx\E\pgfplots@firstplot@coords@y\E\pgfutil@empty - \E\t@pgfplots@tokc={}% - \E\else - \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@y,}% - \E\fi - \E\xdef\E\pgfplots@firstplot@coords@y{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@y}% - % - \ifpgfplots@curplot@threedim - \E\ifx\E\pgfplots@firstplot@coords@z\E\pgfutil@empty - \E\t@pgfplots@tokc={}% - \E\else - \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@z,}% - \E\fi - \E\xdef\E\pgfplots@firstplot@coords@z{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@z}% - \fi + % + % Takes a coordinate which is already parsed and applies steps + % such that it becomes its final values. + % + % This implements the stacked plot feature currently. + % + % PRECONDITION: + % \pgfplotsaxisparsecoordinate has already been called. + % + % POSTCONDITION: + % the point has its final coordinates; the axis won't change it + % anymore. + \xdef\pgfplotsaxispreparecoordinate{% + \E\ifpgfplotsaxisparsecoordinateok + % All following routines (limit updating/stacking/error + % bars) will use float numerics if necessary (controlled + % by ifs). + \E\pgfplotsaxistransformfromdatacs + \ifpgfplots@stackedmode + \E\pgfplots@stacked@preparepoint@inmacro% \fi - \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}% + \E\fi }% - % The following code assembles the command which is executed for - % each coordinate. % - % To eliminate all those case distinctions, it is created with - % 'edef' and a lot of '\noexpand' calls here: + % A macro which should be called once for every data point during the + % survey phase. % - % Arguments: - % \pgfplots@current@point@[xyz] - % \pgfplots@current@point@[xyz]@error (if in argument list) - \xdef\pgfplots@process@one@point{% - % These things are necessary for error bars and are available - % as public results in math parser invocations (for meta and - % filters) - \E\let\E\pgfplots@current@point@x@unfiltered=\E\pgfplots@current@point@x - \E\let\E\pgfplots@current@point@y@unfiltered=\E\pgfplots@current@point@y - \E\let\E\pgfplots@current@point@z@unfiltered=\E\pgfplots@current@point@z - \E\def\E\pgfplots@unbounded@dir{}% - % - \E\pgfplots@prepare@xcoord{\E\pgfplots@current@point@x}% - \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{x}% - \E\let\E\pgfplots@current@point@x=\E\pgfmathresult - % - \E\pgfplots@prepare@ycoord{\E\pgfplots@current@point@y}% - \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{y}% - \E\let\E\pgfplots@current@point@y=\E\pgfmathresult - % - \ifpgfplots@curplot@threedim - \E\pgfplots@prepare@zcoord{\E\pgfplots@current@point@z}% - \E\expandafter\E\pgfplots@invoke@filter\E\expandafter{\E\pgfmathresult}{z}% - \E\let\E\pgfplots@current@point@z=\E\pgfmathresult - \fi - % - \E\pgfplots@invoke@filter@xyz - % - \ifpgfplots@xislinear - % NOTE: this handling of unbounded coords in the case of - % LOG coords is performed directly by - % \pgfplots@prepare@ycoord! - \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty - \E\else - \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@x}% - \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta - \E\ifnum\E\c@pgf@counta>2 % this clears nan, inf and -inf points. - \E\let\E\pgfplots@current@point@x=\E\pgfutil@empty - \E\def\E\pgfplots@unbounded@dir{x}% - \E\else - \E\let\E\pgfplots@current@point@x=\E\pgfmathresult - \E\fi - \E\fi - \fi - % - \ifpgfplots@yislinear - \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty - \E\else - \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@y}% - \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta - \E\ifnum\E\c@pgf@counta>2 - \E\let\E\pgfplots@current@point@y=\E\pgfutil@empty - \E\def\E\pgfplots@unbounded@dir{y}% - \E\else - \E\let\E\pgfplots@current@point@y=\E\pgfmathresult - \E\fi - \E\fi - \fi - % - \ifpgfplots@curplot@threedim + % The caller is the plot handler's point survey routine. + % + % A data point might be a complicated thing which contains + % multiple coordinates. You need to invoke + % \pgfplotsaxisparsecoordinate and + % \pgfplotsaxispreparecoordinate for each of them. But + % \pgfplotsaxisdatapointsurveyed is invoked once for the complete + % set. + % + % @PRECONDITION + % - \pgfplots@current@point@[xyz] contain final coordinates + % (i.e. output of \pgfplotsaxispreparecoordinate) + % + % @POSTCONDITION + % - stacked plot things, + % - error bars, + % - xtick=data + % are all processed. + % + \xdef\pgfplotsaxisdatapointsurveyed{% + \E\ifpgfplotsaxisparsecoordinateok + % All following routines (limit updating/stacking/error + % bars) will use float numerics if necessary (controlled + % by ifs). % - \ifpgfplots@zislinear - \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty - \E\else - \E\pgfmathfloatparsenumber{\E\pgfplots@current@point@z}% - \E\expandafter\E\pgfmathfloat@decompose@F\E\pgfmathresult\E\relax\E\c@pgf@counta - \E\ifnum\E\c@pgf@counta>2 - \E\let\E\pgfplots@current@point@z=\E\pgfutil@empty - \E\def\E\pgfplots@unbounded@dir{z}% + % Prepare \pgfplots@current@point@meta (see the preparation + % routine above): + \E\pgfplots@set@perpointmeta + % + \ifpgfplots@errorbars@enabled + % This thing gets the 'current@point@...' context, + % that means + % \pgfplots@current@point@[xy] + % \pgfplots@current@point@[xy]@error + % \pgfplots@current@point@[xy]@unfiltered + \E\pgfplots@PREPARE@errorbar@process@x% + \E\pgfplots@PREPARE@errorbar@process@y% + \E\pgfplots@PREPARE@errorbar@process@z% + \fi + % + \ifpgfplots@collect@firstplot@astick + \ifnum\pgfplots@numplots=0 + \E\ifx\E\pgfplots@firstplot@coords@x\E\pgfutil@empty + \E\t@pgfplots@tokc={}% \E\else - \E\let\E\pgfplots@current@point@z=\E\pgfmathresult + \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@x,}% \E\fi - \E\fi - \fi - \fi - % - % check if coordinates are bounded: - \E\pgfplots@loc@tmptrue - \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty - \E\pgfplots@loc@tmpfalse - \E\else - \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty - \E\pgfplots@loc@tmpfalse - \E\else - \ifpgfplots@curplot@threedim - \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty - \E\pgfplots@loc@tmpfalse + \E\xdef\E\pgfplots@firstplot@coords@x{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@x}% + \E\ifx\E\pgfplots@firstplot@coords@y\E\pgfutil@empty + \E\t@pgfplots@tokc={}% + \E\else + \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@y,}% \E\fi + \E\xdef\E\pgfplots@firstplot@coords@y{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@y}% + % + \ifpgfplots@curplot@threedim + \E\ifx\E\pgfplots@firstplot@coords@z\E\pgfutil@empty + \E\t@pgfplots@tokc={}% + \E\else + \E\t@pgfplots@tokc=\E\expandafter{\E\pgfplots@firstplot@coords@z,}% + \E\fi + \E\xdef\E\pgfplots@firstplot@coords@z{\E\the\E\t@pgfplots@tokc\E\pgfplots@current@point@z}% + \fi \fi - \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 + \fi + \E\pgfplotscoordstream@firstlast@update + \E\pgfplotsaxisserializedatapoint \E\else + % COORDINATE HAS BEEN FILTERED AWAY: + % % make ALL empty to simplify special case checking: \E\let\E\pgfplots@current@point@x=\E\pgfutil@empty \E\let\E\pgfplots@current@point@y=\E\pgfutil@empty @@ -2488,6 +3698,7 @@ % check whether we have UNBOUNDED or just unfiltered % coords: \if\pgfplots@unbounded@handler d% unbounded coords=discard + \E\def\E\pgfplotsaxisfilteredcoordsaway{1}% \ifpgfplots@warn@for@filter@discards \E\pgfplots@message{% NOTE: coordinate (\E\pgfplots@current@point@x@unfiltered,\E\pgfplots@current@point@y@unfiltered\ifpgfplots@curplot@threedim,\E\pgfplots@current@point@z@unfiltered\fi) @@ -2502,6 +3713,7 @@ \else % unbounded coords=jump \E\ifx\E\pgfplots@unbounded@dir\E\pgfutil@empty + \E\def\E\pgfplotsaxisfilteredcoordsaway{1}% \ifpgfplots@warn@for@filter@discards \E\pgfplots@message{% NOTE: coordinate (\E\pgfplots@current@point@x@unfiltered,\E\pgfplots@current@point@y@unfiltered\ifpgfplots@curplot@threedim,\E\pgfplots@current@point@z@unfiltered\fi) @@ -2509,7 +3721,8 @@ }% \fi \E\else - \pgfplots@loc@performserizalization + \E\def\E\pgfplotsaxisplothasjumps{1}% + \E\pgfplotsaxisserializedatapoint \E\fi \fi \E\fi @@ -2517,13 +3730,21 @@ % increase \pgfplots@current@point@coordindex: \E\advance\E\c@pgfplots@coordindex by1 }% + % + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endgroup -%\message{Prepared macro \string\pgfplots@update@limits@for@one@point: {\meaning\pgfplots@update@limits@for@one@point}}% + % + \def\pgfplotsaxissurveysetpointmeta{\pgfplots@set@perpointmeta}% + % +%\message{Prepared macro \string\pgfplots@update@limits@for@one@point: {\meaning\pgfplotsaxisupdatelimitsforcoordinate}}% %\message{Prepared macro \string\pgfplots@process@one@point: {\meaning\pgfplots@process@one@point}}% % \let\pgfplots@coord@stream@start@=\pgfplots@PREPARE@COORD@STREAM@start@ - \let\pgfplots@coord@stream@coord@=\pgfplots@process@one@point + \def\pgfplots@coord@stream@coord@{% + \def\pgfplots@set@perpointmeta@done{0}% + \pgfplotsplothandlersurveypoint + }% \def\pgfplots@coord@stream@end@{\pgfplots@PREPARE@COORD@STREAM@end@{#1}}% }% @@ -2539,6 +3760,16 @@ % optimized 'applistXX' structure: \pgfplotsapplistXXnewempty % + \csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname + \pgfplotsplothandlersurveystart + \pgfplotscoordstream@firstlast@init + % + \pgfkeyssetvalue{/data point/x}{\pgfplots@current@point@x}% + \pgfkeyssetvalue{/data point/y}{\pgfplots@current@point@y}% + \pgfkeyssetvalue{/data point/z}{\pgfplots@current@point@z}% + \pgfkeyssetvalue{/data point/meta}{\pgfplots@current@point@meta}% + % + \pgfplots@prepare@visualization@dependencies % \ifpgfplots@errorbars@enabled % prepare error bar processing. @@ -2577,17 +3808,21 @@ \pgfplotsmathdeclarepseudoconstant{meta}{% \let\pgfmathresult=\pgfplots@current@point@meta \ifx\pgfmathresult\pgfutil@empty - \pgfmathfloatcreate{0}{0.0}{0}% + \pgfplotscoordmath{meta}{parsenumber}{0}% \fi }% - \csname pgfpmeta@\pgfplotspointmetainputhandler @activate\endcsname % % %%%%%%%%%%%%%% % % Define \pgfplots@set@perpointmeta properly: \def\pgfplots@set@perpointmeta{% - \csname pgfpmeta@\pgfplotspointmetainputhandler @assign\endcsname + \if0\pgfplots@set@perpointmeta@done + \csname pgfpmeta@\pgfplotspointmetainputhandler @assign\endcsname + \def\pgfplots@set@perpointmeta@done{1}% + \pgfplots@set@perpointmeta@limits + \fi }% + % append limit updating to \pgfplots@set@perpointmeta : \if0\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname % We need to work with per point meta data. % So, also compute the data range on a per-plot basis! @@ -2597,37 +3832,43 @@ \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}% + \pgfplotscoordmath{meta}{min}{\pgfplots@metamin}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamin=\pgfmathresult }% \else - \pgfmathfloatparsenumber{\pgfplots@metamin}% + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamin}% \global\let\pgfplots@metamin=\pgfmathresult \fi \pgfkeysgetvalue{/pgfplots/point meta max}\pgfplots@metamax \ifx\pgfplots@metamax\pgfutil@empty \global\let\pgfplots@metamax=\pgfplots@invalidrange@metamax \t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb - \pgfplotsmathfloatmax{\pgfplots@metamax}{\pgfplots@current@point@meta}% + \pgfplotscoordmath{meta}{max}{\pgfplots@metamax}{\pgfplots@current@point@meta}% \global\let\pgfplots@metamax=\pgfmathresult }% \else - \pgfmathfloatparsenumber{\pgfplots@metamax}% + \pgfplotscoordmath{meta}{parsenumber}{\pgfplots@metamax}% \global\let\pgfplots@metamax=\pgfmathresult \fi % - \t@pgfplots@toka=\expandafter{\pgfplots@set@perpointmeta}% - \edef\pgfplots@set@perpointmeta{% - \the\t@pgfplots@toka + \edef\pgfplots@set@perpointmeta@limits{% \noexpand\ifx\noexpand\pgfplots@current@point@meta\noexpand\pgfutil@empty \noexpand\else \the\t@pgfplots@tokb \noexpand\fi }% + \def\pgfplotsaxisupdatelimitsforpointmeta##1{% + \begingroup + \def\pgfplots@current@point@meta{##1}% + \pgfplots@set@perpointmeta@limits + \endgroup + }% \else % there is no point meta: \global\let\pgfplots@metamin=\pgfutil@empty \global\let\pgfplots@metamax=\pgfutil@empty + \let\pgfplots@set@perpointmeta@limits=\relax + \def\pgfplotsaxisupdatelimitsforpointmeta##1{}% \fi }% % This is the \pgfplots@coord@stream@end@ routine which is invoked by @@ -2644,14 +3885,17 @@ % % #1,#2: see \pgfplots@PREPARE@COORD@STREAM \def\pgfplots@PREPARE@COORD@STREAM@end@#1{% + \pgfkeysvalueof{/pgfplots/execute at end survey}% + \pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfplots@current@point@coordindex}% + \pgfplotsplothandlersurveyend \ifx\pgfplots@metamin\pgfutil@empty \else \if\pgfplots@axiswide@metamin@autocompute1% - \pgfplotsmathfloatmin{\pgfplots@axiswide@metamin}{\pgfplots@metamin}% + \pgfplotscoordmath{meta}{min}{\pgfplots@axiswide@metamin}{\pgfplots@metamin}% \global\let\pgfplots@axiswide@metamin=\pgfmathresult \fi \if\pgfplots@axiswide@metamax@autocompute1% - \pgfplotsmathfloatmax{\pgfplots@axiswide@metamax}{\pgfplots@metamax}% + \pgfplotscoordmath{meta}{max}{\pgfplots@axiswide@metamax}{\pgfplots@metamax}% \global\let\pgfplots@axiswide@metamax=\pgfmathresult \fi \fi @@ -2677,7 +3921,7 @@ \ifpgfplots@stackedmode \pgfplots@stacked@endplot \fi - \ifpgfplots@coord@stream@isfirst + \ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty \pgfplots@warning{the current plot has no coordinates (or all have been filtered away)}% \else % Idea: use @@ -2688,10 +3932,12 @@ % 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% + \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,% + /pgfplots/.cd,/pgfplots/every axis plot post}% + \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% \ifpgfplots@curplot@isirrelevant % for \label commands: \expandafter\pgfplots@rememberplotspec@for@label\expandafter{\pgfplots@addplot@survey@@optionlist}% @@ -2703,12 +3949,8 @@ \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 + \pgfplotsplothandlerserializestateto\pgfplots@loc@TMPa + \t@pgfplots@tokb=\expandafter{\pgfplots@loc@TMPa}% % SERIALIZE RESULT: % % everything which has been accumulated so far (including the @@ -2745,18 +3987,21 @@ \noexpand\pgfkeyssetvalue{/pgfplots/samples at}{\pgfplots@plot@samples@at}% \noexpand\pgfkeyssetvalue{/pgfplots/mesh/rows}{\pgfkeysvalueof{/pgfplots/mesh/rows}}% \noexpand\pgfkeyssetvalue{/pgfplots/mesh/cols}{\pgfkeysvalueof{/pgfplots/mesh/cols}}% + \noexpand\pgfkeyssetvalue{/pgfplots/mesh/num points}{\pgfkeysvalueof{/pgfplots/mesh/num points}}% % either '+' or '-' : \noexpand\pgfkeyssetvalue{/pgfplots/x coord sorting}{\pgfkeysvalueof{/pgfplots/x coord sorting}}% \noexpand\pgfkeyssetvalue{/pgfplots/y coord sorting}{\pgfkeysvalueof{/pgfplots/y coord sorting}}% % \noexpand\pgfplots@initzerolevelhandler - \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}% + \noexpand\def\noexpand\pgfplots@serialized@state@plothandler{\the\t@pgfplots@tokb}% + \noexpand\def\noexpand\pgfplotsaxisfilteredcoordsaway{\pgfplotsaxisfilteredcoordsaway}% + \noexpand\def\noexpand\pgfplotsaxisplothasjumps{\pgfplotsaxisplothasjumps}% }% {% draw command: \noexpand\path% @@ -2803,234 +4048,363 @@ \pgfplots@end@plot }% -% PRECONDITION: must be called inside of -% \pgfplots@PREPARE@COORD@STREAM@end@. + +% A routine which transforms the current set of +% \pgfplots@current@point@[xyz] values to the coordinate system +% accepted by the actual axis. +\def\pgfplotsaxistransformfromdatacs{% + \pgfkeyslet{/data point/x}\pgfplots@current@point@x + \pgfkeyslet{/data point/y}\pgfplots@current@point@y + \pgfkeyslet{/data point/z}\pgfplots@current@point@z + \pgfplotsaxistransformcs + {\pgfkeysvalueof{/pgfplots/data cs}} + {\pgfkeysvalueof{/pgfplots/@expected axis cs}}% + \pgfkeysgetvalue{/data point/x}\pgfplots@current@point@x + \pgfkeysgetvalue{/data point/y}\pgfplots@current@point@y + \pgfkeysgetvalue{/data point/z}\pgfplots@current@point@z +}% + +% Changes '/data point/[xyz]' to the new coordinate system +% (cs) designated by '#2'. % -% 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}{+}% +% #1: the actual coordinate system's name +% #2: the desired coordinate system's name +% +% PRECONDITION: '/data point/[xyz]' contain the current +% point's coordinates in the '#1' system. The z coordinate is ignored for 2d plots (or +% for coordinate systems which are inherently two-dimensional). +% +% POSTCONDITION: 'data point/[xyz]' contain same point as +% before, but represented in the '#2' system. +% +% The coordinate system transformations must be defined, +% see \pgfplotsdefinecstransform. +% +% Example: +% \pgfkeyssetvalue{/data point/x}{90} +% \pgfkeyssetvalue{/data point/y}{1} +% \pgfplotsaxistransformcs{polar}{cart} +% --> +% \pgfkeysvalueof{/data point/x}= 0 +% \pgfkeysvalueof{/data point/y}= 1 +\def\pgfplotsaxistransformcs#1#2{% + \edef\pgfplots@loc@TMPa{#1}% + \edef\pgfplots@loc@TMPb{#2}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + % nothing to do \else - \pgfkeyssetvalue{/pgfplots/#1 coord sorting}{-}% + \pgfutil@ifundefined{pgfp@transform@\pgfplots@loc@TMPa @to@\pgfplots@loc@TMPb}{% + \pgfutil@ifundefined{pgfp@transform@\pgfplots@loc@TMPa @to@cart}{% + \pgfplotsaxistransformcs@error + }{% + \pgfplotsaxistransformcs{#1}{cart}% + \pgfplotsaxistransformcs{cart}{#2}% + }% + }{% + \csname pgfp@transform@\pgfplots@loc@TMPa @to@\pgfplots@loc@TMPb\endcsname + }% \fi }% -% Assigns default values to 'rows' and 'cols' in case -% their values are empty. +% Defines a new coordinate transformation for use in +% \pgfplotsaxistransformcs. +% #1: the source coordinate system +% #2: the target coordinate system +% #3: the transformation code. % -% PRECONDITION: -% The values of -% - '/pgfplots/mesh/rows' -% - '/pgfplots/mesh/cols' -% - '/pgfplots/mesh/num points' -% - \pgfplotsscanlinelength -% - '/pgfplots/mesh/ordering' -% are assigned properly. +% @see \pgfplotsaxistransformcs for what #3 should do. % -% 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% +% This does also declare a coordinate system for use in 'data cs'. +% The minimal requirements are to define the transformations from and +% to "cart" (cartesian coordinates). +% +\def\pgfplotsdefinecstransform#1#2#3{% + \expandafter\def\csname pgfp@transform@#1@to@#2\endcsname{#3}% +}% + +\pgfplotsdefinecstransform{polar}{cart}{% + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}% + \let\pgfplots@current@point@x=\pgfmathresult + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/y}}% + \let\pgfplots@current@point@y=\pgfmathresult + \pgfplotsmathpoltocart\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@x@\pgfplots@current@point@y@ + \pgfplotscoordmath{x}{parsenumber}{\pgfplots@current@point@x@}% + \pgfkeyslet{/data point/x}\pgfmathresult + \pgfplotscoordmath{y}{parsenumber}{\pgfplots@current@point@y@}% + \pgfkeyslet{/data point/y}\pgfmathresult +}% +\pgfplotsdefinecstransform{cart}{polar}{% + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}% + \let\pgfplots@current@point@x=\pgfmathresult + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/y}}% + \let\pgfplots@current@point@y=\pgfmathresult + \pgfplotsmathcarttopol\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@x@\pgfplots@current@point@y@ + \pgfplotscoordmath{x}{parsenumber}{\pgfplots@current@point@x@}% + \pgfkeyslet{/data point/x}\pgfmathresult + \pgfplotscoordmath{y}{parsenumber}{\pgfplots@current@point@y@}% + \pgfkeyslet{/data point/y}\pgfmathresult +}% + +\pgfplotsdefinecstransform{polarrad}{polar}{% + \pgfplotsgetcoordmathfor{default}\let\pgfplots@coordmath@id=\pgfplotsretval + \pgfutil@ifundefined{pgfp@polarradscale@\pgfplots@coordmath@id}{% + \pgfplotscoordmath{default}{parsenumber}{57.2957795130823}% + \expandafter\global\expandafter\let\csname pgfp@polarradscale@\pgfplots@coordmath@id\endcsname=\pgfmathresult + }{}% + % + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\csname pgfp@polarradscale@\pgfplots@coordmath@id\endcsname}}% + \pgfkeyslet{/data point/x}\pgfmathresult +}% +\pgfplotsdefinecstransform{polar}{polarrad}{% + \pgfplotsgetcoordmathfor{default}\let\pgfplots@coordmath@id=\pgfplotsretval + \pgfutil@ifundefined{pgfp@polarradiscale@\pgfplots@coordmath@id}{% + \pgfplotscoordmath{default}{parsenumber}{0.0174532925199433}% + \expandafter\global\expandafter\let\csname pgfp@polarradiscale@\pgfplots@coordmath@id\endcsname=\pgfmathresult + }{}% + % + \pgfplotscoordmath{default}{parsenumber}{\pgfkeysvalueof{/data point/x}}% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\csname pgfp@polarradiscale@\pgfplots@coordmath@id\endcsname}}% +}% +\pgfplotsdefinecstransform{polarrad}{cart}{% + \pgfplotsaxistransformcs{polarrad}{polar}% + \pgfplotsaxistransformcs{polar}{cart}% +}% +\pgfplotsdefinecstransform{cart}{polarrad}{% + \pgfplotsaxistransformcs{cart}{polar}% + \pgfplotsaxistransformcs{polar}{polarrad}% }% -% 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. +\def\pgfplotsaxistransformcs@error{% + \pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Sorry, I do not know how to transform the coordinate system '\pgfplots@loc@TMPa' to '\pgfplots@loc@TMPb'. Maybe you misspelled the 'data cs'? Or perhaps the feature is not yet implemented?}\pgfeov% +}% + +\def\pgfplotsaxisserializedatapoint{% + \pgfplotsplothandlerserializepointto\pgfplotsaxisserializedatapoint@val + \pgfplotsaxisserializedatapoint@private + \t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@val}% + \t@pgfplots@tokb=\expandafter{\pgfplotsretval}% + \edef\pgfplots@loc@TMPa{{\the\t@pgfplots@tokb;\the\t@pgfplots@toka}}% + \expandafter\pgfplotsapplistXXpushback\expandafter{\pgfplots@loc@TMPa}% +}% +\def\pgfplotsaxisserializedatapoint@private{% + \let\pgfplotsretval=\pgfplots@current@point@meta +}% +\def\pgfplotsaxisdeserializedatapointfrom@private#1{% + \def\pgfplots@current@point@meta{#1}% +}% +% Restores the variables serialized in '#1'. % -% 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. +% As a side--effect, the macro +% \pgfplotsaxisdeserializedatapointfrom@private@lastvalue will contain +% the serialized part which is specific to pgfplots (i.e. the private +% parts which can be read with +% \pgfplotsaxisdeserializedatapointfrom@private) +\def\pgfplotsaxisdeserializedatapointfrom#1{% + \expandafter\pgfplotsaxisdeserializedatapointfrom@#1\pgfplots@EOI +}% +\def\pgfplotsaxisdeserializedatapointfrom@#1;#2\pgfplots@EOI{% + \def\pgfplotsaxisdeserializedatapointfrom@private@lastvalue{#1}% + \pgfplotsaxisdeserializedatapointfrom@private{#1}% + \pgfplotsplothandlerdeserializepointfrom{#2}% +}% + +% Handle User-defined parts which should be serialized as well. +% This preparation tool should be called at the start of both, survey +% and visualization phase. +% +% @PRECONDITION +% - the macros +% \pgfplotsaxisserializedatapoint@private +% \pgfplotsaxisdeserializedatapointfrom@private +% are known and valid. +% - '/pgfplots/visualization depends on' contains its correct value. % -% POSTCONDITION: -% 'rows' and 'cols' have useful integer values. -\def\pgfplotsautocompletemeshkeys{% - \pgfplots@autocomplete@meshkeys1% -}% -\def\pgfplots@autocomplete@meshkeys#1{% - \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplotsplothandlermesh@rows - \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplotsplothandlermesh@cols - \pgfkeysgetvalue{/pgfplots/mesh/num points}\pgfplotsplothandlermesh@numpoints - \edef\pgfplotsplothandlermesh@numpoints{\pgfplotsplothandlermesh@numpoints}% - \edef\pgfplotsplothandlermesh@cols{\pgfplotsplothandlermesh@cols}% - \edef\pgfplotsplothandlermesh@rows{\pgfplotsplothandlermesh@rows}% - \ifpgfplots@curplot@threedim - \ifx\pgfplotsplothandlermesh@rows\pgfutil@empty - \ifx\pgfplotsplothandlermesh@cols\pgfutil@empty - \pgfutil@ifundefined{pgfplotsscanlinelength}{\def\pgfplotsscanlinelength{-1}}{}% - \ifpgfplots@scanline@verbose - \ifnum\pgfplotsscanlinelength>0 - % we have scanlinelength set! Use it: - \message{PGFPlots: Scanline length is \pgfplotsscanlinelength.}% - \else - \ifnum\pgfplotsscanlinelength=-2 - \message{PGFPlots: Scanline length could not be determined since multiple, different scan line lengths have been found.}% - \else - \message{PGFPlots: No end-of-scanline marker found in input stream.}% - \fi - \fi - \fi - \ifnum\pgfplotsscanlinelength>0 - % we have scanlinelength set! Use it: - \if\pgfplots@plot@mesh@ordering0% - % ordering = x varies= rowwise -> scanline is cols! - \edef\pgfplotsplothandlermesh@cols{\pgfplotsscanlinelength}% - \else - % ordering = y varies = colwise: scanline is rows! - \edef\pgfplotsplothandlermesh@rows{\pgfplotsscanlinelength}% - \fi - \else - \if1#1% - % try to get reasonable values: - \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty - \pgfplots@error{Sorry, 'plot mesh' needs either '[mesh/rows=<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 +% @POSTCONDITION +% Both, +% \pgfplotsaxisserializedatapoint@private +% and +% \pgfplotsaxisdeserializedatapointfrom@private +% have been patched to incorporate the '/pgfplots/visualization +% depends on' feature. +% +\def\pgfplots@prepare@visualization@dependencies{% + \pgfkeysgetvalue{/pgfplots/visualization depends on/list}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + % SERIALIZATION format: + % visualization depends on={{value1}\as \macro1, {<value2>}\as \macro2,...} + % -> + % {<original private data>}<\macro1>{<value1>}<\macro2>{<value2>}...<\macroN>{<valueN>} + % + % prepare + % \t@pgfplots@tokb={<\macro1>{<value1>}<\macro2>{<value2>}...<\macroN>{<valueN>}} + \t@pgfplots@tokb={}% + % + % prepare + % \t@pgfplots@tokc={<\macro1><\macro2><\macro3>...} + \t@pgfplots@tokc={}% + \expandafter\pgfplotsutilforeachcommasep\expandafter{\pgfplots@loc@TMPa}\as\pgfplots@loc@TMPa{% + \ifx\pgfplots@loc@TMPa\pgfutil@empty \else - \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 + \expandafter\pgfplots@prepare@visualization@depends@on\pgfplots@loc@TMPa\pgfplots@EOI% + \fi + }% + % Step 1: modify the SERIALIZATION method: + \t@pgfplots@toka=\expandafter{\pgfplotsaxisserializedatapoint@private}% + \edef\pgfplotsaxisserializedatapoint@private{% + \the\t@pgfplots@tokc + \the\t@pgfplots@toka + % nothing is expanded here, only \t@pgfplots@tokb + \noexpand\t@pgfplots@toka=\noexpand\expandafter{\noexpand\pgfplotsretval}% + \noexpand\edef\noexpand\pgfplotsretval{{\noexpand\the\t@pgfplots@toka},\the\t@pgfplots@tokb}% + }% + % Step 2: modify the DESERIALIZATION method: + \let\pgfplotsaxisdeserializedatapointfrom@private@orig=\pgfplotsaxisdeserializedatapointfrom@private + \let\pgfplotsaxisdeserializedatapointfrom@private=\pgfplotsaxisdeserializedatapointfrom@private@withdeplist + \fi + % + \pgfkeysgetvalue{/pgfplots/execute for finished point}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key + \else + \expandafter\def\expandafter\pgfplotsaxisserializedatapoint@private\expandafter{% + \pgfplotsaxisserializedatapoint@private + \pgfkeysvalueof{/pgfplots/execute for finished point}% + }% + \fi +}% +\def\pgfplots@prepare@visualization@depends@on#1\pgfplots@EOI{% + \pgfutil@in@\as{#1}% + \ifpgfutil@in@ + % ok, we have the '<content>\as<\macro>' syntax: + \pgfplots@prepare@visualization@depends@on@#1\pgfplots@EOI + \else + \pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value\pgfplots@EOI + \ifpgfutil@in@ + % ok, then it should be 'value <\macro>'. + % extract the <\macro>: + \def\pgfplots@loc@TMPa value{\pgfplots@loc@TMPb}% + \def\pgfplots@loc@TMPb##1{\pgfplots@loc@TMPc ##1}% this step should remove leading white spaces + \def\pgfplots@loc@TMPc##1\pgfplots@EOI{% + % sanitize: check if ##1 is a defined macro: + \begingroup + \escapechar=-1 + \xdef\pgfplots@glob@TMPa{\string##1}% + \endgroup + \pgfutil@ifundefined{\pgfplots@glob@TMPa}{% \begingroup - \c@pgf@counta=\pgfplotsplothandlermesh@numpoints\relax - \divide\c@pgf@counta by\pgfplotsplothandlermesh@rows\relax - \xdef\pgfplots@glob@TMPa{\the\c@pgf@counta}% + \t@pgfplots@toka={##1}% + \pgfplotsthrow{invalid argument} + {\pgfplots@loc@TMPa}% + {Sorry, `visualization depends on=value <\string\macro>' expected a defined control sequence name instead of `\the\t@pgfplots@toka'. Please make sure `\the\t@pgfplots@toka' is a properly defined macro or use the `visualization depends on=value <content> \string\as <\string\macro>' syntax instead}% + \pgfeov \endgroup - \let\pgfplotsplothandlermesh@cols=\pgfplots@glob@TMPa - \fi - \fi - \ifx\pgfplotsplothandlermesh@numpoints\pgfutil@empty - \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@rows\relax - \multiply\c@pgfplots@scanlineindex by \pgfplotsplothandlermesh@cols\relax - \edef\pgfplotsplothandlermesh@numpoints{\the\c@pgfplots@scanlineindex}% - \fi - % - \c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@rows\relax - \multiply\c@pgfplots@scanlineindex by\pgfplotsplothandlermesh@cols\relax - \ifnum\c@pgfplots@scanlineindex=\pgfplotsplothandlermesh@numpoints\relax - \else - \ifcase\pgfplots@mesh@checkmode\relax - % mesh/check=false - \def\pgfplots@loc@TMPa##1{}% - \or - % mesh/check=warning - \def\pgfplots@loc@TMPa##1{\pgfplots@warning{##1}}% - \or - % mesh/check=error - \def\pgfplots@loc@TMPa##1{\pgfplots@error{##1}}% - \fi - \pgfplots@loc@TMPa{the arguments of [mesh/rows=\pgfplotsplothandlermesh@rows,mesh/cols=\pgfplotsplothandlermesh@cols] assume \the\c@pgfplots@scanlineindex\space points, but I got actually N = \pgfplotsplothandlermesh@numpoints\space points! The data matrix appears to be incomplete or overcomplete!? [Use mesh/check=false to disable this message]}% - \fi + }{% + \def\pgfplots@loc@TMPa{% + \pgfplots@prepare@visualization@depends@on@ value}% + \expandafter\pgfplots@loc@TMPa##1\as##1\pgfplots@EOI + }% + }% + \pgfplots@loc@TMPa#1\pgfplots@EOI + \else + % then, I expect '<\macro>'. + % sanitize: check if #1 is a defined macro: + \begingroup + \escapechar=-1 + \xdef\pgfplots@glob@TMPa{\string#1}% + \endgroup + \pgfutil@ifundefined{\pgfplots@glob@TMPa}{% + \begingroup + \t@pgfplots@toka={#1}% + \pgfplotsthrow{invalid argument} + {\pgfplots@loc@TMPa}% + {Sorry, `visualization depends on' expected a defined control sequence name instead of `\the\t@pgfplots@toka'. Please make sure `\the\t@pgfplots@toka' is a properly defined macro or use the `visualization depends on=<expression> \string\as <\string\macro>' syntax instead}% + \pgfeov + \endgroup + }{% + \expandafter\pgfplots@prepare@visualization@depends@on@#1\as#1\pgfplots@EOI + }% \fi + \fi +}% +\def\pgfplots@prepare@visualization@depends@on@#1\as#2\pgfplots@EOI{% + \pgfplots@prepare@visualization@depends@on@preparetype{#1}\as{#2}% + % prepare the serialization: + \t@pgfplots@tokb=\expandafter{\the\t@pgfplots@tokb\noexpand#2{\csname\string#2@value\endcsname}}% + \t@pgfplots@tokc=\expandafter{\the\t@pgfplots@tokc#2}% +}% +\def\pgfplots@prepare@visualization@depends@on@preparetype#1\as#2{% + \pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value\pgfplots@EOI + \ifpgfutil@in@ + \pgfplots@prepare@visualization@depends@on@preparetype@value#1\as{#2}% no braces here. \else - % 2d visualization has no mesh: - \edef\pgfplotsplothandlermesh@rows{\pgfplotsplothandlermesh@numpoints}% - \def\pgfplotsplothandlermesh@cols{1}% + \pgfplots@prepare@visualization@depends@on@preparetype@expr{#1}\as{#2}% + \fi +}% +\def\pgfplots@prepare@visualization@depends@on@preparetype@expr#1\as#2{% + \pgflibraryfpuifactive{% + \def#2{% + \pgfmathparse{#1}% + \pgfmathfloattofixed{\pgfmathresult}% + \expandafter\let\csname \string#2@value\endcsname=\pgfmathresult + }% + }{% + \def#2{% + \pgfmathparse{#1}% + \expandafter\let\csname \string#2@value\endcsname=\pgfmathresult + }% + }% +} +\def\pgfplots@prepare@visualization@depends@on@preparetype@checkvalue#1value#2\pgfplots@EOI{% + \def\pgfplots@loc@TMPa{#1}% + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \pgfutil@in@true + \else + \pgfutil@in@false + \fi +}% +\def\pgfplots@prepare@visualization@depends@on@preparetype@value value#1\as#2{% + \begingroup + % remove spaces from #1: + \pgfkeys@spdef\pgfplots@loc@TMPa{#1}% + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% + \t@pgfplots@tokb=\expandafter{\csname\string#2@value\endcsname}% + \xdef\pgfplots@glob@TMPa{% + \noexpand\def\the\t@pgfplots@tokb{\the\t@pgfplots@toka}% + }% + \endgroup + \let#2=\pgfplots@glob@TMPa +} + +\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist#1{% + \pgfplotsaxisdeserializedatapointfrom@private@withdeplist@#1\pgfplots@EOI +}% +\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@#1,{% + \pgfplotsaxisdeserializedatapointfrom@private@orig{#1}% + \pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@ +}% +\def\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@#1{% + \def\pgfplots@loc@TMPa{#1}% + \ifx\pgfplots@loc@TMPa\pgfplots@EOI + \else + \afterassignment\pgfplotsaxisdeserializedatapointfrom@private@withdeplist@@ + \expandafter\def\expandafter#1% \fi - % - \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}% +}% + +% PRECONDITION: must be called inside of +% \pgfplots@PREPARE@COORD@STREAM@end@. +% +% POSTCONDITION: +% assigns '/pgfplots/#1 coord sorting=[+-]' +% i.e. whether #1 (x or y or z) coordinates are in ascending (+) ordering or in +% descending order (-). +\def\pgfplots@PREPARE@COORD@STREAM@end@determinecoordsorting#1{% + \pgfplotscoordmath{#1}{if less than} + {\csname pgfplots@currentplot@firstcoord@#1\endcsname}% + {\csname pgfplots@currentplot@lastcoord@#1\endcsname}% + {\pgfkeyssetvalue{/pgfplots/#1 coord sorting}{+}}% + {\pgfkeyssetvalue{/pgfplots/#1 coord sorting}{-}}% }% % Prepares a macro \pgfplots@PREPARE@process@errorbar@for@dir##1 @@ -3100,7 +4474,7 @@ \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\pgfplotsaxisupdatelimitsforcoordinate\E\pgfplots@current@point@x\E\pgfplots@current@point@y\E\pgfplots@current@point@z \E\let\expandafter\E\csname pgfplots@current@point@#1\endcsname=\E\pgfplots@current@point@@old \E\edef\E\pgfplots@loc@TMPa{\the\t@pgfplots@toka}% \E\expandafter\E\pgfplots@streamerrorbarcoords\E\pgfplots@loc@TMPa @@ -3115,41 +4489,48 @@ \pgfplots@if{pgfplots@#1islinear}{% \ifcase\csname pgfplots@errorbars@#1mode\endcsname\relax % fixed absolute error. - \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1fixed\endcsname}% + \pgfplotscoordmath{#1}{parsenumber}{\csname pgfplots@errorbars@#1fixed\endcsname}% \expandafter\let\csname pgfplots@error@coord@#1\endcsname=\pgfmathresult \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% \if +##1% - \pgfmathfloatadd@ - {\csname pgfplots@current@point@#1\endcsname}% - {\csname pgfplots@error@coord@#1\endcsname}% + \def\pgfplots@loc@TMPb{add}% \else - \pgfmathfloatsubtract@ - {\csname pgfplots@current@point@#1\endcsname}% - {\csname pgfplots@error@coord@#1\endcsname}% + \def\pgfplots@loc@TMPb{subtract}% \fi + \pgfplotscoordmath{#1}{op}{\pgfplots@loc@TMPb}{% + {\csname pgfplots@current@point@#1\endcsname}% + {\csname pgfplots@error@coord@#1\endcsname}% + }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% fixed relative error: - \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1rel\endcsname}% + \pgfplotscoordmath{#1}{parsenumber}{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: - \pgfmathfloatcreate{1}{1.0}{0}% + \pgfplotscoordmath{#1}{parsenumber}{1}% \let\pgfplots@loc@TMPa=\pgfmathresult % % Prepare '1 + err': - \pgfmathfloatadd@{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}% + \pgfplotscoordmath{#1}{op}{add}{% + {\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}% + \pgfplotscoordmath{#1}{op}{subtract}{% + {\pgfplots@loc@TMPa}% + {\pgfplots@loc@TMPb}% + }% \expandafter\let\csname pgfplots@error@coord@#1@-\endcsname=\pgfmathresult % \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% - \pgfmathfloatmultiply@ + \pgfplotscoordmath{#1}{op}{multiply}{% {\csname pgfplots@current@point@#1\endcsname} {\csname pgfplots@error@coord@#1@##1\endcsname}% + }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% @@ -3158,20 +4539,20 @@ \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else - \pgfmathfloatparsenumber{\pgfplots@error@coord}% + \pgfplotscoordmath{#1}{parsenumber}{\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}% + \def\pgfplots@loc@TMPb{add}% \else - \pgfmathfloatsubtract@ - {\csname pgfplots@current@point@#1\endcsname}% - {\pgfplots@error@coord}% + \def\pgfplots@loc@TMPb{subtract}% \fi + \pgfplotscoordmath{#1}{op}{\pgfplots@loc@TMPb}{% + {\csname pgfplots@current@point@#1\endcsname}% + {\pgfplots@error@coord}% + }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \fi @@ -3183,9 +4564,10 @@ \else \pgfmathparse{1##1\pgfplots@error@coord}% \let\pgfplots@error@coord=\pgfmathresult - \pgfmathfloatmultiply@ + \pgfplotscoordmath{#1}{multiply}{% {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% + }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \fi @@ -3204,52 +4586,58 @@ % \ifcase\csname pgfplots@errorbars@#1mode\endcsname % fixed absolute, log( x +- e_x ) - \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1fixed\endcsname}% + % + \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@errorbars@#1fixed\endcsname}% \expandafter\let\csname pgfplots@error@coord@#1\endcsname=\pgfmathresult \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% - \pgfmathfloatparsenumber{\csname pgfplots@current@point@#1@unfiltered\endcsname}% + \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% - \pgfmathfloatadd@ - {\pgfplots@loc@TMPa}% - {\csname pgfplots@error@coord@#1\endcsname}% + \def\pgfplots@loc@op{add}% \else - \pgfmathfloatsubtract@ - {\pgfplots@loc@TMPa}% - {\csname pgfplots@error@coord@#1\endcsname}% + \def\pgfplots@loc@op{subtract}% \fi - \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% + \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% + {\pgfplots@loc@TMPa}% + {\csname pgfplots@error@coord@#1\endcsname}% + }% + \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% + \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname }% \or% fixed relative, log( x ( 1+-e_x ) ) = log(x) + log(1+-e_x) - \pgfmathfloatparsenumber{\csname pgfplots@errorbars@#1rel\endcsname}% + \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@errorbars@#1rel\endcsname}% \let\pgfplots@loc@TMPb=\pgfmathresult % % +1: - \pgfmathfloatcreate{1}{1.0}{0}% + \pgfplotscoordmath{default}{one}% \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 + \pgfplotscoordmath{default}{op}{add}{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}}% + \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% + \pgfplotscoordmath{#1}{log}{\pgfmathresult}% + \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% + }{% % 1 + err <= 0 and log(1+err) is undefined: - \pgfmathfloattofixed{\pgfplots@loc@TMPb}% - \pgfplots@error{Sorry, log(1+\pgfmathresult) is undefined. Please provide a different argument for '/pgfplots/error bar/#1 fixed relative'.}% + \pgfplotscoordmath{default}{tostring}{\pgfplots@loc@TMPb}% + \pgfplots@error{Sorry, log(1 + \pgfmathresult) is undefined. Please provide a different argument for '/pgfplots/error bar/#1 fixed relative'.}% \let\pgfmathresult=\pgfutil@empty - \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'.}% + \pgfplotscoordmath{default}{op}{subtract}{{\pgfplots@loc@TMPa}{\pgfplots@loc@TMPb}}% + \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% + \pgfplotscoordmath{#1}{log}{\pgfmathresult}% + \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% + }{% + % 1 - err <= 0 and log(1+err) is undefined: + \pgfplotscoordmath{default}{tostring}{\pgfplots@loc@TMPb}% + \pgfplots@error{Sorry, log(1 - \pgfmathresult) (\pgfplots@loc@TMPa - \pgfplots@loc@TMPb) is undefined. Please provide a different argument for '/pgfplots/error bar/#1 fixed relative'.}% \let\pgfmathresult=\pgfutil@empty - \fi + }% \expandafter\let\csname pgfplots@error@coord@#1@-\endcsname=\pgfmathresult % \expandafter\def\csname pgfplots@PREPARE@errorbar@process@#1@\endcsname##1{% @@ -3268,23 +4656,24 @@ \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else - \pgfmathfloatparsenumber{\pgfplots@error@coord}% + \pgfplotscoordmath{default}{parsenumber}{\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}% + \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@current@point@#1@unfiltered\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% - \pgfmathfloatadd@ - {\pgfplots@loc@TMPa}% - {\pgfplots@error@coord}% + \def\pgfplots@loc@op{add}% \else - \pgfmathfloatsubtract@ - {\pgfplots@loc@TMPa}% - {\pgfplots@error@coord}% + \def\pgfplots@loc@op{subtract}% \fi - \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% + \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% + {\pgfplots@loc@TMPa}% + {\pgfplots@error@coord}% + }% + \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% + \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname \fi @@ -3296,34 +4685,36 @@ \edef\pgfplots@error@coord{\csname pgfplots@current@point@#1@error\endcsname}% \ifx\pgfplots@error@coord\pgfutil@empty \else - \pgfmathfloatparsenumber{\pgfplots@error@coord}% + \pgfplotscoordmath{default}{parsenumber}{\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}% + \pgfplotscoordmath{default}{one}% \let\pgfplots@loc@TMPa=\pgfmathresult \if +##1% - \pgfmathfloatadd@ - {\pgfplots@loc@TMPa}% - {\pgfplots@error@coord}% + \def\pgfplots@loc@op{add}% \else - \pgfmathfloatsubtract@ - {\pgfplots@loc@TMPa}% - {\pgfplots@error@coord}% + \def\pgfplots@loc@op{subtract}% \fi - \csname pgfplotsmathlog@#1@float\endcsname{\pgfmathresult}% + \pgfplotscoordmath{default}{op}{\pgfplots@loc@op}{% + {\pgfplots@loc@TMPa}% + {\pgfplots@error@coord}% + }% + \pgfplotscoordmath{default}{tostring}{\pgfmathresult}% + \pgfplotscoordmath{#1}{log}{\pgfmathresult}% \let\pgfplots@error@coord=\pgfmathresult - \ifx\pgfplots@error@coord\pgfutil@empty - % -> log( <= 0 ) -> do nothing. - \else - \pgfmath@basic@add@ + \pgfplotscoordmath{#1}{if is bounded}{\pgfmathresult}{% + \pgfplotscoordmath{#1}{op}{add}{% {\csname pgfplots@current@point@#1\endcsname} {\pgfplots@error@coord}% + }% \let\pgfplots@error@coord=\pgfmathresult \csname pgfplots@PREPARE@errorbar@stream@it@#1\endcsname - \fi + }{% + % -> log( <= 0 ) -> do nothing. + }% \fi }% % @@ -3366,107 +4757,134 @@ % If there is no data range (for example because meta information is % not available or is not of numeric type), the trafo will simply % copy the input argument symbolically. +% +% Note: it does not hurt to call it multiple times. It checks automatically whether it already is up-to-date. \def\pgfplots@perpointmeta@preparetrafo{% - \let\pgfplots@current@point@meta=\pgfutil@empty - \pgfutil@ifundefined{pgfplots@metamax}{\let\pgfplots@metamax=\pgfutil@empty}{} - \ifpgfplots@warn@for@filter@discards - \global\let\pgfplots@perpointmeta@unboundedwarning@stop=\relax - \def\pgfplots@perpointmeta@unboundedwarning##1{% - \ifx\pgfplots@perpointmeta@unboundedwarning@stop\relax - \begingroup - \pgfmathfloattofixed{##1}% - \pgfplots@warning{The per point meta data `\pgfmathresult' (##1) (and probably others as well) is unbounded - using the minimum value instead.}% - \endgroup - \gdef\pgfplots@perpointmeta@unboundedwarning@stop{1}% - \fi - }% - \else - \def\pgfplots@perpointmeta@unboundedwarning##1{}% - \fi - \if m\pgfplots@colormap@access - % colormap access=map - \ifx\pgfplots@metamax\pgfutil@empty - \def\pgfplots@perpointmeta@trafo##1{% - \pgfmathfloatiffinite{##1}{% - \pgfmathfloattofixed@{##1}% - }{% - \def\pgfmathresult{0}% - \pgfplots@perpointmeta@unboundedwarning{##1}% - }% + \def\pgfplotspointmetarangeexponent{1}% pre-fill + \pgfutil@ifundefined{pgfplots@perpointmeta@trafo}{% + \let\pgfplots@current@point@meta=\pgfutil@empty + \pgfutil@ifundefined{pgfplots@metamax}{\let\pgfplots@metamax=\pgfutil@empty}{} + \ifpgfplots@warn@for@filter@discards + \global\let\pgfplots@perpointmeta@unboundedwarning@stop=\relax + \def\pgfplots@perpointmeta@unboundedwarning##1{% + \ifx\pgfplots@perpointmeta@unboundedwarning@stop\relax + \begingroup + \pgfplotscoordmath{meta}{tostring}{##1}% + \pgfplots@warning{The per point meta data `\pgfmathresult' (##1) (and probably others as well) is unbounded - using the minimum value instead.}% + \endgroup + \gdef\pgfplots@perpointmeta@unboundedwarning@stop{1}% + \fi }% - \def\pgfplots@perpointmeta@traforange{0:1000}% - \edef\pgfplotspointmetarange{0:1000}% \else - % The transformation is - % - % phi(m) = ( m- meta_min) * 1000/ (meta_max-meta_min). - % - % -> precompute the scaling factor! - \edef\pgfplots@loc@TMPa{\pgfplotscolormaprange}% - \ifnum\pgfplots@loc@TMPa=1000 - \else - \pgfplots@error{LOGIC ERROR: sorry, I have hard-coded the assumption \string\pgfplotscolormaprange = 1000, but now it is \pgfplots@loc@TMPa.}% - \fi - \if\pgfplots@perpointmeta@rel@choice0% - % point meta rel=axis wide: - \edef\pgfplotspointmetarange{\pgfplots@axiswide@metamin:\pgfplots@axiswide@metamax}% - % Now, prepare the trafo as such. - % It assigns \pgfmathresult (in fixed point). + \def\pgfplots@perpointmeta@unboundedwarning##1{}% + \fi + \if m\pgfplots@colormap@access + % colormap access=map + \ifx\pgfplots@metamax\pgfutil@empty \def\pgfplots@perpointmeta@trafo##1{% - \pgfmathfloatiffinite{##1}{% - \pgfmathfloatsubtract@{##1}{\pgfplots@axiswide@metamin}% - \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}% - \expandafter\pgfmathfloattofixed@\expandafter{\pgfmathresult}% - }{% + \pgfplotscoordmath{meta}{if is}{##1}{u} + {% \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}% + \pgfplotscoordmath{meta}{tofixed}{##1}% }% }% - \pgfmathfloatsubtract@{\pgfplots@metamax}{\pgfplots@metamin}% + \def\pgfplots@perpointmeta@traforange{0:1000}% + \edef\pgfplotspointmetarange{0:1000}% + \else + % The transformation is + % + % phi(m) = ( m- meta_min) * 1000/ (meta_max-meta_min). + % + % -> precompute the scaling factor! + \edef\pgfplots@loc@TMPa{\pgfplotscolormaprange}% + \ifnum\pgfplots@loc@TMPa=1000 + \else + \pgfplots@error{LOGIC ERROR: sorry, I have hard-coded the assumption \string\pgfplotscolormaprange = 1000, but now it is \pgfplots@loc@TMPa.}% + \fi + \if\pgfplots@perpointmeta@rel@choice0% + % point meta rel=axis wide: + \pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@axiswide@}% + \else + \pgfplots@perpointmeta@preparetrafo@initfrom{pgfplots@}% + \fi \fi - \let\pgfplots@loc@TMPa=\pgfmathresult - \pgfmathfloatcreate{1}{1.0}{3}% - \expandafter\pgfmathfloatdivide@\expandafter{\pgfmathresult}{\pgfplots@loc@TMPa}% - \let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult - % - % Expands to the transformation range as 'a:b': - \def\pgfplots@perpointmeta@traforange{0:1000}% - \fi - \else - % colormap access=direct - \def\pgfplots@perpointmeta@trafo##1{ - \pgfmathfloatiffinite{##1}{% - \pgfmathfloattofixed@{##1}% - }{% - \def\pgfmathresult{0}% - \pgfplots@perpointmeta@unboundedwarning{##1}% + \else + % colormap access=direct + \def\pgfplots@perpointmeta@trafo##1{% + \pgfplotscoordmath{meta}{if is}{##1}{u}{% + \def\pgfmathresult{0}% + \pgfplots@perpointmeta@unboundedwarning{##1}% + }{% + \pgfplotscoordmath{meta}{tofixed}{##1}% + }% }% - }% - \def\pgfplots@perpointmeta@traforange{0:0}% - \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% - \fi - \edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}% + \def\pgfplots@perpointmeta@traforange{0:0}% + \edef\pgfplotspointmetarange{\pgfplots@metamin:\pgfplots@metamax}% + \fi + \edef\pgfplotspointmetatransformedrange{\pgfplots@perpointmeta@traforange}% + }{}% }% -\def\pgfplots@perpointmeta@trafo@APPLY{% + +% Employs \csname #1metamin\endcsname and its metamax counterpart to +% initialize the trafo. +% +% This unifies the approaches for \pgfplots@axiswide@metamax and +% \pgfplots@metamax. +\def\pgfplots@perpointmeta@preparetrafo@initfrom#1{% + \edef\pgfplotspointmetarange{\csname #1metamin\endcsname:\csname #1max\endcsname}% + % Now, prepare the trafo as such. + % It assigns \pgfmathresult (in fixed point). + \def\pgfplots@perpointmeta@trafo##1{% + \pgfplotscoordmath{meta}{if is}{##1}{u}{% + \def\pgfmathresult{0}% + \pgfplots@perpointmeta@unboundedwarning{##1}% + }{% + \pgfplotscoordmath{meta}{op}{subtract}{{##1}{\csname #1metamin\endcsname}}% + \pgfplotscoordmath{meta}{op}{multiply}{{\pgfmathresult}{\pgfplots@perpointmeta@trafo@factor}}% + \pgfplotscoordmath{meta}{tofixed}{\pgfmathresult}% + }% + }% + \pgfplotscoordmath{meta}{op}{subtract}{{\csname #1metamax\endcsname}{\csname #1metamin\endcsname}}% + \let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotscoordmath{meta}{parsenumber}{1000}% + \pgfplotscoordmath{meta}{op}{divide}{{\pgfmathresult}{\pgfplots@loc@TMPa}}% + \let\pgfplots@perpointmeta@trafo@factor=\pgfmathresult + % + % Expands to the transformation range as 'a:b': + \def\pgfplots@perpointmeta@traforange{0:1000}% + % + \expandafter\let\expandafter\pgfplots@loc@TMPa\csname #1metamax\endcsname + \pgfplotscoordmath{meta}{tostring}{\pgfplots@loc@TMPa}% + \pgfmathfloatparsenumber\pgfmathresult + \pgfmathfloatgetexponent\pgfmathresult\c@pgf@countd + \edef\pgfplotspointmetarangeexponent{\the\c@pgf@countd}% +} + +% A command which is readily available during the visualization phase of each plot. +% +% It takes existing point meta data and transforms it, i.e. it defines +% \pgfplotspointmetatransformed. +% +% The command won't be invoked automatically, it is task of a plot +% handler to decide if it is needed. It's application is relatively +% fast, however. +% +% PRECONDITION: +% - point meta has been set up during the survey phase (i.e. the +% /pgfplots/point meta!=none), +% - there *is* point meta data for the current data point. +% +% POSTCONDITION: +% - the macros \pgfplotspointmeta and \pgfplotspointmetatransformed +% are defined. +% +% @see also \pgfplotsaxisifhaspointmeta +\def\pgfplotsaxisvisphasetransformpointmeta{% \ifx\pgfplots@current@point@meta\pgfutil@empty% \pgfplots@error{could not access the 'point meta' (used for example by scatter plots and color maps). Maybe you need to add '\string\addplot[point meta=y]' or something like that?}% - \pgfmathfloatcreate{1}{1.0}{0}% + \pgfplotscoordmath{meta}{one}% \let\pgfplotspointmeta=\pgfmathresult \def\pgfplotspointmetatransformed{1.0}% \else @@ -3536,7 +4954,11 @@ \pgfplots@error{Sorry, I could not read the plot coordinates near '#1'. Please check for format mistakes.}% }% \long\def\pgfplots@foreach@plot@coord@ITERATE@gobbleone#1{\pgfplots@foreach@plot@coord@ITERATE}% -\def\pgfplots@foreach@plot@coord@NEXT(#1,#2){% +\def\pgfplots@foreach@plot@coord@NEXT(#1){% + \edef\pgfmathresult{#1}% + \expandafter\pgfplots@foreach@plot@coord@NEXT@\expandafter(\pgfmathresult)% +} +\def\pgfplots@foreach@plot@coord@NEXT@(#1,#2){% \ifpgfplots@plot@coords@mathparser \pgfmathparse{#1}\let\pgfplots@current@point@x=\pgfmathresult \pgfmathparse{#2}\let\pgfplots@current@point@y=\pgfmathresult @@ -3613,7 +5035,11 @@ }% } \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@foreach@plot@coord@threedim@NEXT(#1){% + \edef\pgfmathresult{#1}% + \expandafter\pgfplots@foreach@plot@coord@threedim@NEXT@\expandafter(\pgfmathresult)% +} +\def\pgfplots@foreach@plot@coord@threedim@NEXT@(#1,#2,#3){% \ifpgfplots@plot@coords@mathparser \pgfmathparse{#1}\let\pgfplots@current@point@x=\pgfmathresult \pgfmathparse{#2}\let\pgfplots@current@point@y=\pgfmathresult @@ -3668,42 +5094,168 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % -% The same in normalized coordinates of the form -% x1,y1,z1,m1;x2,y2,z2,m2;...;xN,yN,zN,mN; -% if the plot is not threedim, zi is empty. +% A coordinate stream which works like this: +% +% ------------- +% \pgfplots@coord@stream@start +% +% foreach encoded coordinate: +% \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded{<encoded data>}% +% \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced{{<encoded data>}}% note the extra braces. +% \pgfplotsaxisdeserializedatapointfrom{<encoded data>} +% \pgfplots@coord@stream@coord % -% The mi are Meta Values associated to point coordinates. They are -% usually empty, but can be used to realize per-point marker -% modifications (scatter plots, especially for colormaps). +% \pgfplots@coord@stream@end +% ------------- +% +% The format of #1 is +% {<datapoint>}{<datapoint>}...{<datapoint>} +% Each data point is decoded with +% \pgfplotsaxisserializedatapoint +% and then, \pgfplots@coord@stream@coord will be called. \long\def\pgfplots@coord@stream@foreach@NORMALIZED#1{% \pgfplots@coord@stream@start - \pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1\pgfplots@EOI + \pgfplotscoordstream@firstlast@init + \pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1\pgfplots@EOI% \pgfplots@coord@stream@end }% - -% A looping command to loop through plot coordinates. -% For every point, #1{X}{Y} will be invoked. -% % No scoping is used during this operation, so you can access outer % variables. -\def\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE{% - \pgfutil@ifnextchar\pgfplots@EOI{% - \pgfplots@foreach@plot@coord@FINISH% - }{% - \pgfplots@foreach@plot@coord@NORMALIZED@NEXT% - }% +\def\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE#1{% + \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded{#1}% + \ifx\pgfplots@coord@stream@foreach@NORMALIZED@curencoded\pgfplots@EOI + \else + \def\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced{{#1}}% + \pgfplotsaxisdeserializedatapointfrom{#1}% + \pgfplots@coord@stream@coord + \pgfplotscoordstream@firstlast@update + \expandafter\pgfplots@foreach@plot@coord@NORMALIZED@ITERATE + \fi } -\def\pgfplots@foreach@plot@coord@NORMALIZED@NEXT#1,#2,#3,#4;{% - \def\pgfplots@current@point@x{#1}% - \def\pgfplots@current@point@y{#2}% - \def\pgfplots@current@point@z{#3}% - \def\pgfplots@current@point@meta{#4}% - \pgfplots@coord@stream@coord - \pgfplots@foreach@plot@coord@NORMALIZED@ITERATE + + +% A common routine which resets internal data structures for the +% survey phase, i.e. it is the shared implementation for all \addplot +% variations. +% +% It takes all options which are provided to \addplot, sets them (at +% least partially) and remembers them for the command serialization. +% +% #1: arguments to \addplot plot[#1] +% -> these are called 'behavior' options in the manual; they are set +% immediately. +% +% PRECONDITION: +% \pgfplots@addplotimpl@plot@withoptions has already been invoked +% +% POSTCONDITION: +% - internal datastructures are initialised (coordinate indexing, fpu) +% - all keys which are required for the current plot are determined +% (and set if necessary). +% They are stored into +% \pgfplots@addplot@survey@@optionlist. +% +\def\pgfplots@start@plot@with@behavioroptions#1{% + %\begingroup%<-- has been moved to \pgfplots@addplotimpl@plot@withoptions + \c@pgfplots@coordindex=0 + \def\pgfplots@current@point@coordindex{\the\c@pgfplots@coordindex}% can be used inside of coordinate filters. + \def\coordindex{\pgfplots@current@point@coordindex}% valid inside of \addplot + \def\pgfplots@addplot@running{1}% + % + \def\pgfplots@colorbar@set@src{0}% + \pgfkeysdef{/pgfplots/colorbar source}{% + \pgfplotsutilifstringequal{##1}{true}{% + \def\pgfplots@colorbar@set@src{1}% + }{% + \pgfplotsutilifstringequal{##1}{false}{% + \def\pgfplots@colorbar@set@src{0}% + }{% + \pgfplots@error{Sorry, I don't know the value `colorbar source={##1}' and I am going to ignore it. Maybe you misspelled it?}% + }% + }% + }% + % + % these styles may contain behavior options (error bars, + % samples,... ) activate them! + % + % As of february 20, 2009, #1 will contain BOTH, /pgfplots + % and /tikz options. The /tikz ones are primarily for drawing + % and are UNIMPORTANT at this stage of processing. + % In fact, transparency etc. will only confuse everything. + % + % So: ignore them and set only /pgfplots keys here: + % This may actually redefine styles, for example + % \addplot[every mark/.append style={}] will use + % /pgfplots/every mark/.append style. + % But that doesn't hurt here. + % + % there are some exceptions like /tikz/id etc. These + % exceptions need special styles in the /pgfplots root - or I + % need to change the .unknown handler. See the available + % compatibility styles! + % +% \pgfkeysdef{/pgfplots/.unknown}{% +%\message{In \string\addplot[#1]: I am silently ignoring key `\pgfkeyscurrentkeyRAW' during the preparation phase.}% +% }% + % ATTENTION: + % as of january 30, 2010, I will set /tikz keys as well. This won't hurt + % too much, I hope... there are no graphics operations anyway. But it *is* + % necessary since I *need* the plot handler for the new version. And the plot + % handler is, most likely, a /tikz key. + % + % it is possible that '#1' contains 'forget plot'. So, we need to + % set the options before checking \ifpgfplots@curplot@isirrelevant: + \pgfplotsset{/pgfplots/every axis plot,#1}% + % + \ifpgfplots@curplot@isirrelevant + \def\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every forget plot}% + \pgfplotsset{/pgfplots/every forget plot,/pgfplots/every axis plot post}% + \else + \edef\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% + \pgfplotsset{/pgfplots/every axis plot no \the\pgfplots@numplots/.try,/pgfplots/every axis plot post}% + \fi + % + % enable FPU after any \pgfplotsset operations. Otherwise things like + % linewidth=... which use the math parser might fail. + \ifpgfplots@usefpu + \pgfkeys{/pgf/fpu=true}% + \fi + % + % make sure it is reset, just in case it is not supported by the + % input method. + \pgfplotsscanlinelengthinitzero + % + \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler + \pgfplotsresetplothandler + \pgfplots@basiclevel@plothandler + % + \pgfplots@countplots@init + % + % hooks: + \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% + \pgfkeysvalueof{/pgfplots/execute at begin plot}% + % + \if1\pgfplots@colorbar@set@src + \expandafter\def\expandafter\pgfplots@addplot@survey@@optionlist\expandafter{\pgfplots@addplot@survey@@optionlist,% + /pgfplots/point meta rel=per plot}% + \fi + % + \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1' + \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% + % + % + \pgfplots@validate@plot@domain@arguments } +\long\def\pgfplotsplothandlersurveyaddoptions#1{% + \pgfplotsset{/pgfplots/execute at end survey/.add={}{% + \t@pgfplots@tokc=\expandafter{\pgfplots@addplot@survey@@optionlist,#1}% this allows '#' inside of '#1' + \edef\pgfplots@addplot@survey@@optionlist{\the\t@pgfplots@tokc}% + },% + #1% + }% +}% -\newif\ifpgfplots@curplot@threedim % The main interface to draw a plot into an axis. % @@ -3775,56 +5327,54 @@ }% } -\long\def\pgfplots@addplotimplAPPEND+[{% +\def\pgfplots@addplotimplAPPEND+{\pgfutil@ifnextchar[{\pgfplots@addplotimplAPPEND@}{\pgfplots@addplotimplAPPEND@[]}}% this allows to gobble spaces and to skip the '[]' +\def\pgfplots@addplotimplAPPEND@[{% \expandafter\pgfplots@addplotimpl\expandafter[\nextplotspec,% } \long\def\pgfplots@addplotimpl[#1]{% - \pgfutil@ifnextchar p{% + \pgfplotsutil@ifnextchar p{% \pgfplots@addplotimpl@plot{#1}% }{% \pgfplots@addplotimpl@plot{#1}plot }% } -\def\pgfplots@addplotimpl@plot#1plot{% - \pgfutil@ifnextchar[{% +\long\def\pgfplots@addplotimpl@plot#1plot{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@plot@withoptions{#1}% }{% \pgfplots@addplotimpl@plot@withoptions{#1}[]% }% } -\def\pgfplots@addplotimpl@plot@withoptions#1[#2]{ +\long\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{% + \pgfplotsutil@ifnextchar c{% \pgfplots@addplotimpl@coordinates{#1}{#2}plot }{% - \pgfutil@ifnextchar f{% + \pgfplotsutil@ifnextchar f{% \pgfplots@addplotimpl@f{#1}{#2}% }{% - \pgfutil@ifnextchar t{% + \pgfplotsutil@ifnextchar t{% + \def\pgfplotssurveyphaseinputclass{table}% \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% \pgfplots@addplotimpl@table{#1,#2}% }{% - \pgfutil@ifnextchar ({% + \pgfplotsutil@ifnextchar ({% \pgfplots@addplotimpl@expression{#1}{#2}% }{% - \pgfutil@ifnextchar\bgroup{% + \pgfplotsutil@ifnextchar\bgroup{% \pgfplots@addplotimpl@expression@curly{#1}{#2}% }{% - \pgfutil@ifnextchar e{% + \pgfplotsutil@ifnextchar e{% \pgfplots@addplotimpl@expression@e{#1}{#2}% }{% - \pgfutil@ifnextchar g{% + \pgfplotsutil@ifnextchar g{% \pgfplots@addplotimpl@g{#1}{#2}% }{% - \pgfutil@ifnextchar s{% + \pgfplotsutil@ifnextchar s{% \pgfplots@addplotimpl@shell{#1}{#2}% }{% @@ -3839,8 +5389,8 @@ }% }% } -\def\pgfplots@addplotimpl@f#1#2f{% - \pgfutil@ifnextchar i{% +\long\def\pgfplots@addplotimpl@f#1#2f{% + \pgfplotsutil@ifnextchar i{% \pgfplots@addplotimpl@file{#1}{#2}% }{% \pgfplots@addplotimpl@function{#1}{#2}% @@ -3902,9 +5452,32 @@ \edef\pgfplots@plot@var@y{\expandafter\noexpand\csname \pgfplots@plot@var@y\endcsname}% \fi % - % Check if we have to sample a line. - \def\b@pgfplots@should@sample@LINE{0}% - \ifpgfplots@curplot@threedim + % Check if we have to sample a line or a matrix. + % + \pgfkeysgetvalue{/pgfplots/sample dim}\pgfplots@loc@TMPa + \def\pgfplots@loc@TMPb{auto}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \ifpgfplots@curplot@threedim + \def\b@pgfplots@should@sample@LINE{0}% + \else + \def\b@pgfplots@should@sample@LINE{1}% + \fi + \else + \ifcase\pgfplots@loc@TMPa\relax + % sample dim=0 not useful!? + \def\b@pgfplots@should@sample@LINE{1}% + \or + \def\b@pgfplots@should@sample@LINE{1}% + \or + \def\b@pgfplots@should@sample@LINE{0}% + \else + \pgfplots@error{Sorry, sample dim=\pgfplots@loc@TMPa\space is unsupported (use either 1 or 2)}% + \fi + \fi + % + \if0\b@pgfplots@should@sample@LINE + % sample a matrix. Check the keys; if they are one + % dimensional, switch back to line sampling: \pgfkeysgetvalue{/pgfplots/y domain}{\pgfplots@plot@ydomain}% \edef\pgfplots@plot@ydomain{\pgfplots@plot@ydomain}% \def\pgfplots@loc@TMPa{0:0}% @@ -3932,7 +5505,10 @@ \pgfkeyssetvalue{/pgfplots/mesh/rows}{\pgfkeysvalueof{/pgfplots/samples y}}% \pgfkeyssetvalue{/pgfplots/mesh/cols}{\pgfkeysvalueof{/pgfplots/samples}}% \if1\b@pgfplots@should@sample@LINE + \pgfkeyssetvalue{/pgfplots/sample dim}{1}% \pgfkeyssetvalue{/pgfplots/mesh/cols}{1}% + \else + \pgfkeyssetvalue{/pgfplots/sample dim}{2}% \fi % }% @@ -3945,7 +5521,8 @@ \long\def\pgfplots@addplotimpl@expression#1#2(#3,#4)#5;{\pgfplots@addplotimpl@expression@{#1}{#2}{#3}{#4}{#5}}% % \addplot[#1] [#2] (#3,#4) #5; \long\def\pgfplots@addplotimpl@expression@#1#2#3#4#5{% - \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/mesh/ordering/x varies}% + \def\pgfplotssurveyphaseinputclass{expression}% + \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/mesh input=lattice,/pgfplots/mesh/ordering/x varies}% \pgfplots@plot@expression@preparekeys % \pgfplots@PREPARE@COORD@STREAM{#5}% @@ -4008,7 +5585,11 @@ % 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}}}% + {% + \noexpand\pgfplotsforeachungrouped\expandafter\noexpand\tikz@plot@var in {\pgfplots@expression@xdomain} {##1}% + \noexpand\pgfplotsplothandlernotifyscanlinecomplete + }% + }% \else % sample a line: \def\pgfplots@plot@ydomain{0:0}% @@ -4044,6 +5625,7 @@ \fi \fi \if\pgfplots@samples@logarithmically1% + \def\pgfplotsforeachlogarithmicmathid{x}% use \pgfplotscoordmath{x} % sample logarithmically: \edef\pgfplots@plot@data##1{% \noexpand\pgfplotsforeachlogarithmicungrouped[\pgfplots@plot@samples] @@ -4114,6 +5696,11 @@ \let\pgfplots@addplotimpl@expression@pseudoconst@y=\pgfmathy@ % % + % Warning for use fpu=false: evaluation '\x^3' might be different from 'x^3' for + % negative arguments: + % \x^3 ---> -0.2^3 but x^3 = (-0.2)^3 . + % This does not happen for use fpu=true. + % \pgfplots@plot@data{% \let\pgfmathx@=\pgfplots@addplotimpl@expression@pseudoconst@x \let\pgfmathy@=\pgfplots@addplotimpl@expression@pseudoconst@y @@ -4151,13 +5738,14 @@ }% \expandafter\pgfplots@loc@TMPa\pgfplots@loc@TMPb{#4}% \else - \def\pgfplots@loc@TMPa{\pgfplots@addplotimpl@expression@{#1}{#2}}% + \t@pgfplots@tokc={\pgfplots@addplotimpl@expression@{#1}{#2}}% + \def\pgfplots@loc@TMPa{\the\t@pgfplots@tokc}% this construction allows '#' in either '#1' or '#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{% - \pgfutil@ifnextchar[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@expression@e@{#1}{#2}% }{% \pgfplots@addplotimpl@expression@e@{#1}{#2}[]% @@ -4184,7 +5772,7 @@ \xdef\pgfplots@gnuplot@format{set format "%.7e";} } \def\pgfplots@addplotimpl@g#1#2g{% - \pgfutil@ifnextchar r{% + \pgfplotsutil@ifnextchar r{% \pgfplots@addplotimpl@graphics{#1}{#2}% }{% \pgfplots@addplotimpl@gnuplot{#1}{#2}% @@ -4196,7 +5784,7 @@ % \addplot[#1] plot[#2] function[#3] {#4} #5; \def\pgfplots@addplotimpl@function#1#2unction{% - \pgfutil@ifnextchar[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@function@opt{#1}{#2}% }{% \pgfplots@addplotimpl@function@opt{#1}{#2}[]% @@ -4207,6 +5795,7 @@ \def\pgfplots@addplotimpl@function@opt@#1#2#3#4#5{% % FIXME : what about the key search paths if the user changes % them!? + \def\pgfplotssurveyphaseinputclass{gnuplot}% \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3,/pgfplots/mesh/ordering/x varies}% % \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% @@ -4271,6 +5860,7 @@ \expandafter\def\expandafter\pgfplots@gnuplot@logdirs\expandafter{\pgfplots@gnuplot@logdirs z}% \fi \fi + % \ifpgfplots@curplot@threedim \if1\b@pgfplots@should@sample@LINE \pgfplots@error{Sorry, I do not know how to sample 3D LINE plots with gnuplot... I only know 2D line and 3D mesh. You may want to help the author of pgfplots to improve this feature.}% @@ -4395,7 +5985,7 @@ % \addplot[#1] plot[#2] shell[#3] {#4} #5; \def\pgfplots@addplotimpl@shell#1#2shell{% - \pgfutil@ifnextchar[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@shell@opt{#1}{#2}% }{% \pgfplots@addplotimpl@shell@opt{#1}{#2}[]% @@ -4404,6 +5994,7 @@ \def\pgfplots@addplotimpl@shell@opt#1#2[#3]#4#5;{\pgfplots@addplotimpl@shell@opt@{#1}{#2}{#3}{#4}{#5}}% % \addplot[#1] [#2] shell[#3] {#4} #5; \def\pgfplots@addplotimpl@shell@opt@#1#2#3#4#5{% + \def\pgfplotssurveyphaseinputclass{shell}% \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,/pgfplots/.cd,#3}% \pgfplots@gettikzinternal@keyval{prefix}{tikz@plot@prefix}{\jobname.}% \pgfplots@gettikzinternal@keyval{id}{tikz@plot@id}{pgf-shell}% @@ -4440,7 +6031,7 @@ % \addplot[#1] [#2] file{#3} #4; \def\pgfplots@addplotimpl@file#1#2ile{% - \pgfutil@ifnextchar[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@file@opt{#1}{#2}% }{% \pgfplots@addplotimpl@file@opt{#1}{#2}[]% @@ -4452,6 +6043,7 @@ \def\pgfplots@addplotimpl@file@opt@#1#2#3#4#5{% % invoke this here - allows to share the 'plot file' impl with % 'plot gnuplot'. + \def\pgfplotssurveyphaseinputclass{file}% \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% \pgfplots@addplotimpl@file@opt@@{#1,#2}{#3}{#4}{#5}% } @@ -4463,13 +6055,18 @@ \pgfqkeys{/pgfplots/plot file}{#2}% \fi \pgfplots@PREPARE@COORD@STREAM{#4}% + \pgfplots@addplotimpl@file@streamit{#3}% + \endgroup +}% +% #1: the file name +\def\pgfplots@addplotimpl@file@streamit#1{% \pgfplots@coord@stream@start \pgfplotsscanlinelengthinitzero - \openin\r@pgfplots@reada=#3 + \openin\r@pgfplots@reada=#1 \ifeof\r@pgfplots@reada - \pgfplots@error{sorry, plot file{#3} could not be opened}% + \pgfplots@error{sorry, plot file{#1} could not be opened}% \else - \pgfplots@logfileopen{#3}% + \pgfplots@logfileopen{#1}% \let\pgfplots@current@point@x@error=\pgfutil@empty \let\pgfplots@current@point@y@error=\pgfutil@empty \let\pgfplots@current@point@z@error=\pgfutil@empty @@ -4490,7 +6087,6 @@ \fi \pgfplotsscanlinelengthcleanup \pgfplots@coord@stream@end - \endgroup }% \def\pgfplots@addplotimpl@file@readall{% \read\r@pgfplots@reada to\pgfplots@file@LINE @@ -4539,7 +6135,7 @@ \def\pgfplots@addplotimpl@graphics#1#2raphics{% - \pgfutil@ifnextchar[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@graphics@{#1}{#2}% }{% \pgfplots@addplotimpl@graphics@{#1}{#2}[]% @@ -4548,7 +6144,13 @@ % \addplot[#1] plot[#2] graphics[#3] {#4} #5; \long\def\pgfplots@addplotimpl@graphics@#1#2[#3]#4#5;{\pgfplots@addplotimpl@graphics@@{#1}{#2}{#3}{#4}{#5}}% \long\def\pgfplots@addplotimpl@graphics@@#1#2#3#4#5{% - \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2,% + \def\pgfplotssurveyphaseinputclass{graphics}% + \pgfplots@start@plot@with@behavioroptions{% + /pgfplots/filter discard warning=false, + /pgfplots/mesh/rows=2,% allow \addplot[surf] graphics ... --> yields a good legend. + /pgfplots/mesh/cols=2, + /pgfplots/mesh/check=false, + #1,/pgfplots/.cd,#2,% /pgfplots/plot graphics/@prepare legend, /pgfplots/plot graphics,% /pgfplots/plot graphics/.cd,% @@ -4557,8 +6159,27 @@ /tikz/mark=}% \pgfplots@PREPARE@COORD@STREAM{#5}% \pgfplots@coord@stream@start + % + \pgfkeysgetvalue{/pgfplots/plot graphics/points}{\pgfplots@current@point@points}% + \ifx\pgfplots@current@point@points\pgfutil@empty + \else + \let\pgfplotsplothandlergraphicspointmappoint=\pgfplotsplothandlergraphics@survey@pointmappoint + \expandafter\pgfplots@plot@handler@graphics@parsepointmap\expandafter{\pgfplots@current@point@points}% + \ifpgfplots@plot@graphics@autoadjustaxis + \pgfplotsplothandlergraphicspointmapcomputerequiredview + \ifx\pgfplotsretval\pgfutil@empty + \else + \expandafter\pgfplotssetlateoptions\expandafter{\pgfplotsretval}% + \fi + \fi + % + \def\pgfplots@addplotimpl@graphics@@error##1{}% + \fi + % \pgfkeysgetvalue{/pgfplots/plot graphics/xmin}{\pgfplots@current@point@x}% \pgfkeysgetvalue{/pgfplots/plot graphics/ymin}{\pgfplots@current@point@y}% + % + % these sanity checks do nothing of the 'plot graphics/points' feature has been used: \ifx\pgfplots@current@point@x\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{xmin}\fi \ifx\pgfplots@current@point@y\pgfutil@empty\pgfplots@addplotimpl@graphics@@error{ymin}\fi \ifpgfplots@curplot@threedim @@ -4638,7 +6259,7 @@ % 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[{% + \pgfplotsutil@ifnextchar[{% \pgfplots@addplotimpl@table@getopts{#1}% }{% \pgfplots@addplotimpl@table@getopts{#1}[]% @@ -4651,10 +6272,10 @@ \pgfplots@addplotimpl@table@installkeypath \pgfplotstableset{#2}% % - \pgfutil@ifnextchar s{% + \pgfplotsutil@ifnextchar s{% \pgfplots@addplotimpl@table@fromshell{#1}{#2}% }{% - \pgfutil@ifnextchar f{% + \pgfplotsutil@ifnextchar f{% \pgfplots@addplotimpl@table@fromstructure@gobble@space{#1}{#2}% }{% \pgfplots@addplotimpl@table@fromfile@gobble@space{#1}{#2}% @@ -4715,6 +6336,7 @@ % \addplot[#1] table[#2] from {#3} #4 ; \long\def\pgfplots@addplotimpl@table@fromstructure@#1#2#3#4{% \begingroup + \def\pgfplotstablename{#3}% store the name of the currently processed table. \pgfplotstablegetscanlinelength{#3}{\pgfplotsscanlinelength}% % FIXME : this thing here has runtime O(N^2) ! % I fear it is faster to simply reload the data .... !? @@ -4731,6 +6353,8 @@ % % % high level user interface functions: + \let\pgfplotstable@coordindex@old=\coordindex + \def\coordindex{\pgfplotstablerow}% \let\lineno=\coordindex% is the same here % \expandafter\pgfplotstablegetcolumnbyname\expandafter{\pgfplots@plot@tbl@x}\of#3\to\addplot@tbl@x @@ -4778,6 +6402,8 @@ \let\pgfplots@current@point@z@error=\pgfutil@empty \fi % + \let\coordindex=\pgfplotstable@coordindex@old + % \pgfplots@PREPARE@COORD@STREAM{#4}% \pgfplots@coord@stream@start \pgfutil@loop @@ -5197,106 +6823,6 @@ \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 - \c@pgfplots@coordindex=0 - \def\pgfplots@current@point@coordindex{\the\c@pgfplots@coordindex}% can be used inside of coordinate filters. - \def\coordindex{\pgfplots@current@point@coordindex}% valid inside of \addplot - \def\pgfplots@addplot@running{1}% - \def\pgfplots@colorbar@set@src{0}% - \pgfkeysdef{/pgfplots/colorbar source}{% - \pgfplotsutilifstringequal{##1}{true}{% - \def\pgfplots@colorbar@set@src{1}% - }{% - \pgfplotsutilifstringequal{##1}{false}{% - \def\pgfplots@colorbar@set@src{0}% - }{% - \pgfplots@error{Sorry, I don't know the value `colorbar source={##1}' and I am going to ignore it. Maybe you misspelled it?}% - }% - }% - }% - % - % these styles may contain behavior options (error bars, - % samples,... ) activate them! - % - % As of february 20, 2009, #1 will contain BOTH, /pgfplots - % and /tikz options. The /tikz ones are primarily for drawing - % and are UNIMPORTANT at this stage of processing. - % In fact, transparency etc. will only confuse everything. - % - % So: ignore them and set only /pgfplots keys here: - % This may actually redefine styles, for example - % \addplot[every mark/.append style={}] will use - % /pgfplots/every mark/.append style. - % But that doesn't hurt here. - % - % there are some exceptions like /tikz/id etc. These - % exceptions need special styles in the /pgfplots root - or I - % need to change the .unknown handler. See the available - % compatibility styles! - % - % ATTENTION: starting with more recent versions (since the - % unstable version), I will also set /tikz keys here! This should - % work. It is well tested for the unstable... I hope it will also - % work for the master branch. - %\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}% - % - \ifpgfplots@curplot@isirrelevant - \def\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every forget plot}% - \pgfplotsset{/pgfplots/every forget plot,/pgfplots/every axis plot post}% - \else - \edef\pgfplots@addplot@survey@@optionlist{/pgfplots/every axis plot,/pgfplots/every axis plot no \the\pgfplots@numplots/.try}% - \pgfplotsset{/pgfplots/every axis plot no \the\pgfplots@numplots/.try,/pgfplots/every axis plot post}% - \fi - % - \ifpgfplots@usefpu - \pgfkeys{/pgf/fpu=true}% - \fi - \pgfplots@countplots@init - % - % hooks: - \pgfkeysvalueof{/pgfplots/execute at begin plot@@}% - \pgfkeysvalueof{/pgfplots/execute at begin plot}% - % - \if1\pgfplots@colorbar@set@src - \expandafter\def\expandafter\pgfplots@addplot@survey@@optionlist\expandafter{\pgfplots@addplot@survey@@optionlist,% - /pgfplots/point meta rel=per plot}% - \fi - % - \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 -} - - % This is a backwards-compatibility method to ensure that % \axis[ybar] % and @@ -5310,7 +6836,7 @@ % 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/ybar/.@cmd}\pgfplotskeys@orig@ybar \pgfkeysgetvalue{/pgfplots/xbar interval/.@cmd}\pgfplotskeys@orig@xbari \pgfkeysgetvalue{/pgfplots/ybar interval/.@cmd}\pgfplotskeys@orig@ybari \pgfkeysdef{/pgfplots/xbar}{% @@ -5375,12 +6901,6 @@ }% }% % -% This macro may be overwritten inside of the \tikz@plot@handler -% macro. This here is just the default implementation. -% -% @INTERNAL HINT: I think the unstable version has another -% implementation. make sure it's not overwritten! -\def\pgfplotsplothandlername{\meaning\tikz@plot@handler}% % \def\pgfplots@countplots@init{% % @@ -5420,6 +6940,7 @@ \long\def\pgfplots@addplotimpl@coordinates#1#2plot coordinates#3#4;{\pgfplots@addplotimpl@coordinates@{#1}{#2}{#3}{#4}}% % \addplot[#1] [#2] coordinates {#3} #4; \long\def\pgfplots@addplotimpl@coordinates@#1#2#3#4{% + \def\pgfplotssurveyphaseinputclass{coordinates}% \pgfplots@start@plot@with@behavioroptions{#1,/pgfplots/.cd,#2}% \pgfplots@PREPARE@COORD@STREAM{#4}% \ifpgfplots@curplot@threedim @@ -5504,6 +7025,9 @@ }% } +\def\pgfplots@invoke@prefilter{% + \pgfkeysvalueof{/pgfplots/pre filter/.@cmd}\pgfeov% +}% \def\pgfplots@invoke@filter#1#2{% \pgfkeysvalueof{/pgfplots/#2 filter/.@cmd}#1\pgfeov% }% @@ -5528,6 +7052,12 @@ \def\pgfplots@stream@withmeta#1#2#3{\def\pgfplots@current@point@meta{#3}\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} \def\pgfplots@stream@withmeta@#1#2#3#4{\def\pgfplots@current@point@coordindex{#1}\pgfplots@stream@withmeta{#2}{#3}{#4}} +\def\pgfplots@stream@decode@and@apply#1#2#3#4{% + \def\pgfplots@current@point@coordindex{#1}% + \pgfplotsaxisdeserializedatapointfrom@private{#2}% + \pgfplotstreampoint{\pgfqpoint{#3}{#4}}% +} + \newif\ifpgfplots@record@marker@stream % Takes a sequence of PREPARED coordinates which are given in floating % point representation and applies the data scaling trafo (if @@ -5546,6 +7076,7 @@ \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% % + % \ifpgfplots@clip@limits \else % "clip marker paths=true" actually doesn't checks anything -- @@ -5554,6 +7085,9 @@ \pgfplots@clip@marker@pathstrue \fi % + \pgfplots@perpointmeta@preparetrafo + % + \pgfplots@prepare@visualization@dependencies % \def\pgfplots@loc@TMPa{0}% <-- if (collectmark positions) \ifpgfplots@scatterplotenabled @@ -5563,7 +7097,6 @@ \else \def\pgfplots@loc@TMPa{1}% \fi - % \if\pgfplots@loc@TMPa0% % mark=none : no need to waste time collecting marker % positions. @@ -5598,7 +7131,9 @@ \pgfplots@stacked@beginplot \fi \fi + \pgfplotsresetplothandler \pgfplots@basiclevel@plothandler + \expandafter\pgfplotsplothandlerdeserializestatefrom\expandafter{\pgfplots@serialized@state@plothandler}% \pgfplotstreamstart \let\pgfplots@data@scaletrafo@result=\pgfutil@empty \ifpgfplots@record@marker@stream @@ -5625,6 +7160,17 @@ %\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}% \fi }% + \def\pgfplots@visualize@performserialization{% + % ATTENTION: a similar thing is REPLICATED for stacked plots! + \t@pgfplots@tokb=\expandafter{\pgfplotsaxisdeserializedatapointfrom@private@lastvalue}% + \edef\pgfplots@loc@TMPa{% + \noexpand\pgfplots@stream@decode@and@apply + {\the\c@pgfplots@coordindex} + {\the\t@pgfplots@tokb}% + {\the\pgf@x}{\the\pgf@y} + }% + \expandafter\pgfplotsapplistXXpushback\expandafter{\pgfplots@loc@TMPa}% + }% \begingroup \let\E=\noexpand %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -5632,19 +7178,6 @@ % % Will be inserted in one of two possible places below (to collect % marker positions) - \def\pgfplots@visualize@performserizalization{% - % ATTENTION: this here is replicated for stacked plots! - \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\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\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 - }% % This finalize command maps the logical coordinate into PGF's % point space. Furthermore, it collects marker coordinates % (properly clipped by position) if markers are required (see @@ -5655,109 +7188,119 @@ \ifpgfplots@curplot@threedim \E\pgfplotsqpointxyz{\E\pgfplots@current@point@x}{\E\pgfplots@current@point@y}{\E\pgfplots@current@point@z}% \else - \ifpgfplots@threedim - \E\pgfplotsqpointxyz{\E\pgfplots@current@point@x}{\E\pgfplots@current@point@y}{0.0}% - \else - \E\pgfplotsqpointxy{\E\pgfplots@current@point@x}{\E\pgfplots@current@point@y}% - \fi + \E\pgfplotsqpointxy{\E\pgfplots@current@point@x}{\E\pgfplots@current@point@y}% \fi + % \ifpgfplots@record@marker@stream - \E\pgf@xa=\E\pgfplots@current@point@x pt % FIXME : SCOPE REGISTERS!? - \E\pgf@ya=\E\pgfplots@current@point@y pt % - \ifpgfplots@curplot@threedim - \E\pgf@yb=\E\pgfplots@current@point@z pt % - \fi + % remember the position (x,y) for markers. + % remember it before \pgfplotstreampoint (which might change (x,y) ) \ifpgfplots@clip - \E\ifdim\E\pgf@xa<\E\pgfplots@xmin@reg - \E\else - \E\ifdim\E\pgf@xa>\E\pgfplots@xmax@reg - \E\else - \E\ifdim\E\pgf@ya<\E\pgfplots@ymin@reg - \E\else - \E\ifdim\E\pgf@ya>\E\pgfplots@ymax@reg - \E\else - \ifpgfplots@curplot@threedim - \E\ifdim\E\pgf@yb<\E\pgfplots@zmin@reg - \E\else - \E\ifdim\E\pgf@yb>\E\pgfplots@zmax@reg - \E\else - \pgfplots@visualize@performserizalization - \E\fi - \E\fi - \else - \pgfplots@visualize@performserizalization - \fi - \E\fi - \E\fi - \E\fi - \E\fi + % check for clip marker paths: + \E\pgfplotsaxisifcontainspoint{\E\pgfplots@visualize@performserialization}{}% \else - \pgfplots@visualize@performserizalization + \E\pgfplots@visualize@performserialization \fi \fi + % \E\pgfplotstreampoint{}% it will simply take \pgf@x and \pgf@y! + % \advance\c@pgfplots@coordindex by1 }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endgroup % -%\message{Prepared macro \string \pgfplots@apply@data@scaletrafo@to@one@point {\meaning\pgfplots@apply@data@scaletrafo@to@one@point}}% +%\message{Prepared macro \string \pgfplotsaxisvisphasetransformcoordinate {\meaning\pgfplotsaxisvisphasetransformcoordinate}}% %\message{Prepared macro \string \pgfplots@coord@stream@finalize@currentpt {\meaning\pgfplots@coord@stream@finalize@currentpt}}% - \ifpgfplots@apply@datatrafo - \def\pgfplots@coord@stream@coord@{% - \pgfplots@apply@data@scaletrafo@to@one@point% - \pgfplots@coord@stream@finalize@currentpt - }% - \else - \def\pgfplots@coord@stream@coord@{% + \def\pgfplots@coord@stream@coord@{% + \ifx\pgfplots@current@point@x\pgfutil@empty% this realizes `unbounded coords=jump', for example + \pgfplotsplothandlervisualizejump + \else + \pgfplotsaxisvisphasetransformcoordinate\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@z% + \pgfplotsaxisvisphasepreparedatapoint \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 - % + \fi + }% } -\def\pgfplots@plothandler@unbounded@visualize@jump{% - \pgfplotstreamend - \pgfplotstreamstart +\def\pgfplots@check@for@default@plot@mark{% + % make sure there is a mark set! + \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% + \def\pgfplots@loc@TMPa{none}% + \ifx\tikz@plot@mark\pgfplots@loc@TMPa + % this here happens only in older versions of pgf. + \let\tikz@plot@mark\pgfutil@empty + \fi + \ifx\tikz@plot@mark\pgfutil@empty + \pgfplots@getcurrent@plothandler\pgfplots@basiclevel@plothandler + \ifx\pgfplots@basiclevel@plothandler\pgfplothandlerdiscard + % oh, the "only marks" plot handler-- and no plot mark!? + % what's that!? + \ifpgfplots@scatterplotenabled + % scatter handles this in /pgfplots/scatter/true + % automatically. + \else + % that appears to be nonsense... + \def\tikz@plot@mark{*}% + \fi + \fi + \fi }% -% Defines an optimized and matching \pgfplots@apply@data@scaletrafo@to@one@point + +% Defines an optimized and matching \pgfplotsaxisvisphasetransformcoordinate % during the coordinate finalization step in \end{axis}. \def\pgfplots@coord@stream@INIT@finalize@storedcoords@prepare@scaletrafomacro{% \begingroup \let\E=\noexpand - % The command which is called for every non-yet-finished point. + % + % \pgfplotsaxisvisphasetransformcoordinate + % Maps a point to the low level xyz coordinate system by applying + % data scaling transformations. + % + % This method should be invoked for every coordinate before it can + % be drawn. % % It is prepared here to eliminate if's. % % Arguments: - % \pgfplots@current@point@[xyz] - % \pgfplots@current@point@[xyz]@error (if in argument list) - \xdef\pgfplots@apply@data@scaletrafo@to@one@point{% + % #1 : a MACRO containing the x value + % #2 : a MACRO containing the y value + % #3 : a MACRO containing the z value + % + % PRECONDITION: + % - the visualization phase is running. + % - #1,#2,#3 are defined and contain + % values resulting from the survey phase. + % + % POSTCONDITION + % - #1,#2,#3 will be redefined to contain data which is + % readily usable by low level pgf plot handlers for + % visualization. + % + % @see \pgfplotsaxisvisphasepreparedatapoint + \xdef\pgfplotsaxisvisphasetransformcoordinate##1##2##3{% \ifpgfplots@apply@datatrafo@x - \E\pgfplots@datascaletrafo@x{\E\pgfplots@current@point@x}% - \E\let\E\pgfplots@current@point@x=\E\pgfmathresult + \E\pgfplotscoordmath{x}{datascaletrafo}{##1}% + \E\let##1=\E\pgfmathresult \fi \ifpgfplots@apply@datatrafo@y - \E\pgfplots@datascaletrafo@y{\E\pgfplots@current@point@y}% - \E\let\E\pgfplots@current@point@y=\E\pgfmathresult + \E\pgfplotscoordmath{y}{datascaletrafo}{##2}% + \E\let##2=\E\pgfmathresult \fi \ifpgfplots@curplot@threedim \ifpgfplots@apply@datatrafo@z - \E\pgfplots@datascaletrafo@z{\E\pgfplots@current@point@z}% - \E\let\E\pgfplots@current@point@z=\E\pgfmathresult + \E\pgfplotscoordmath{z}{datascaletrafo}{##3}% + \E\let##3=\E\pgfmathresult \fi \fi + % \t@pgfplots@tokc=\expandafter{\pgfplots@data@scaletrafo@result}% + % \edef\pgfplots@data@scaletrafo@result{\the\t@pgfplots@tokc(\pgfplots@current@point@x,\pgfplots@current@point@y)}% + }% + % + % Just before the visualization phase can call the low level + % interface, this method is called to handle final changes. + % It is currently only used by the stacked plot interface. + \xdef\pgfplotsaxisvisphasepreparedatapoint{% \ifpgfplots@stackedmode % all these calls work with pgfmath; no more floating point % arithmetics are applied. @@ -5765,15 +7308,13 @@ \E\pgfplots@stacked@finishpoint% \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)}% }% % \endgroup } \def\pgfplots@addplot@get@named@startendpoints@command#1{% - \ifpgfplots@coord@stream@isfirst + \ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty % empty plot. \def#1{% \pgfcoordinate{current plot begin}{\pgfplotspointaxisorigin}% @@ -5849,6 +7390,8 @@ \t@pgfplots@tokb=\expandafter{\pgfplots@stored@current@cmd[current plot style]}% \t@pgfplots@tokc=\expandafter{\pgfplots@recorded@marker@stream}% \edef\pgfplots@loc@TMPa{% + \noexpand\pgfkeysvalueof{/pgfplots/execute at begin plot visualization}% + \noexpand\def\noexpand\tikz@plot@mark{\tikz@plot@mark}% make sure we restore the environment setting \noexpand\pgfkeysdef{/tikz/current plot style}{\the\t@pgfplots@toka}% % de-activate the FPU here if it was active! I fear its number % format may cause errors when used in low-level @@ -5864,7 +7407,9 @@ \noexpand\pgfplots@install@plotmark@handler \the\t@pgfplots@tokc \noexpand\endpgfextra - ;}% + ;% + \noexpand\pgfkeysvalueof{/pgfplots/execute at end plot visualization}% + }% \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% \t@pgfplots@tokb=\expandafter{\pgfplots@stored@current@precmd}% \edef\pgfplots@loc@TMPa{\the\t@pgfplots@tokb\the\t@pgfplots@toka}% @@ -5876,6 +7421,7 @@ \pgfplots@gettikzinternal@keyval{mark indices}{tikz@mark@list}{}% \pgfplots@gettikzinternal@keyval{mark}{tikz@plot@mark}{}% % + % % do not reset \tikz@options: draw color may be acquired % from 'current plot style' %\let\tikz@options=\pgfutil@empty% @@ -5905,6 +7451,9 @@ % \fi %-------------------------------------------------- \pgfplots@perpointmeta@preparetrafo + % + \pgfplots@prepare@visualization@dependencies + % % this here is the MAIN marker code. % It may be modified if scatter plot is enabled, see below. \def\pgfplots@loc@TMPa{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}} @@ -5923,7 +7472,7 @@ % Prepare arguments for '@pre/@post' macros: \t@pgfplots@toka={% \begingroup - \pgfplots@perpointmeta@trafo@APPLY + \pgfplotsaxisvisphasetransformpointmeta \pgfkeysvalueof{/pgfplots/scatter/@pre marker code/.@cmd}\pgfeov }% \t@pgfplots@tokb=\expandafter{\pgfplots@loc@TMPa}% @@ -5958,18 +7507,18 @@ \def\pgfplots@errorbar@draw@float(#1,#2)(#3,#4){% \ifpgfplots@apply@datatrafo@x - \pgfplots@datascaletrafo@x{#1}% + \pgfplotscoordmath{x}{datascaletrafo}{#1}% \let\pgfplots@xarg=\pgfmathresult% - \pgfplots@datascaletrafo@x{#3}% + \pgfplotscoordmath{x}{datascaletrafo}{#3}% \let\pgfplots@error@xarg=\pgfmathresult% \else \def\pgfplots@xarg{#1}% \def\pgfplots@error@xarg{#3}% \fi \ifpgfplots@apply@datatrafo@y - \pgfplots@datascaletrafo@y{#2}% + \pgfplotscoordmath{y}{datascaletrafo}{#2}% \let\pgfplots@yarg=\pgfmathresult% - \pgfplots@datascaletrafo@y{#4}% + \pgfplotscoordmath{y}{datascaletrafo}{#4}% \let\pgfplots@error@yarg=\pgfmathresult% \else \def\pgfplots@yarg{#2}% @@ -5981,27 +7530,27 @@ } \def\pgfplots@errorbar@draw@float@threedim(#1,#2,#3)(#4,#5,#6){% \ifpgfplots@apply@datatrafo@x - \pgfplots@datascaletrafo@x{#1}% + \pgfplotscoordmath{x}{datascaletrafo}{#1}% \let\pgfplots@xarg=\pgfmathresult% - \pgfplots@datascaletrafo@x{#4}% + \pgfplotscoordmath{x}{datascaletrafo}{#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}% + \pgfplotscoordmath{y}{datascaletrafo}{#2}% \let\pgfplots@yarg=\pgfmathresult% - \pgfplots@datascaletrafo@y{#5}% + \pgfplotscoordmath{y}{datascaletrafo}{#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}% + \pgfplotscoordmath{z}{datascaletrafo}{#3}% \let\pgfplots@zarg=\pgfmathresult% - \pgfplots@datascaletrafo@z{#6}% + \pgfplotscoordmath{z}{datascaletrafo}{#6}% \let\pgfplots@error@zarg=\pgfmathresult% \else \def\pgfplots@zarg{#3}% @@ -6084,24 +7633,29 @@ \def\pgfplots@prepare@ZERO@coordinates{% \ifpgfplots@xislinear \ifpgfplots@apply@datatrafo@x - \pgfmathfloatcreate{0}{0.0}{0}% - \pgfplots@datascaletrafo@x{\pgfmathresult}% + \pgfplotscoordmath{x}{parsenumber}{0}% + \pgfplotscoordmath{x}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@x{0}% \fi + % this works in standard fixed pt math: \pgfplotsmathmax{\pgfplots@logical@ZERO@x}{\pgfplots@xmin}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \pgfplotsmathmin{\pgfplots@logical@ZERO@x}{\pgfplots@xmax}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else - \global\let\pgfplots@logical@ZERO@x=\pgfplots@xmin% + \if\pgfplots@log@origin@choice@x0% + \global\let\pgfplots@logical@ZERO@x=\pgfplots@xmin% + \else + \gdef\pgfplots@logical@ZERO@x{1}% + \fi \fi % \ifpgfplots@yislinear \ifpgfplots@apply@datatrafo@y - \pgfmathfloatcreate{0}{0.0}{0}% - \pgfplots@datascaletrafo@y{\pgfmathresult}% + \pgfplotscoordmath{y}{parsenumber}{0}% + \pgfplotscoordmath{y}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@y{0}% @@ -6111,14 +7665,18 @@ \pgfplotsmathmin{\pgfplots@logical@ZERO@y}{\pgfplots@ymax}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else - \global\let\pgfplots@logical@ZERO@y=\pgfplots@ymin% + \if\pgfplots@log@origin@choice@y0% + \global\let\pgfplots@logical@ZERO@y=\pgfplots@ymin% + \else + \gdef\pgfplots@logical@ZERO@y{1}% + \fi \fi % \ifpgfplots@threedim \ifpgfplots@zislinear \ifpgfplots@apply@datatrafo@z - \pgfmathfloatcreate{0}{0.0}{0}% - \pgfplots@datascaletrafo@z{\pgfmathresult}% + \pgfplotscoordmath{z}{parsenumber}{0}% + \pgfplotscoordmath{z}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@z{0}% @@ -6128,7 +7686,11 @@ \pgfplotsmathmin{\pgfplots@logical@ZERO@z}{\pgfplots@zmax}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else - \global\let\pgfplots@logical@ZERO@z=\pgfplots@zmin% + \if\pgfplots@log@origin@choice@z0% + \global\let\pgfplots@logical@ZERO@z=\pgfplots@zmin% + \else + \gdef\pgfplots@logical@ZERO@z{1}% + \fi \fi \fi % @@ -6151,40 +7713,623 @@ % coordinates. \def\pgfplotsplothandlergraphics{% \def\pgf@plotstreamstart{% - \global\let\pgfplots@plot@handler@graphics@bb@first=\pgfutil@empty - \global\let\pgfplots@plot@handler@graphics@bb@second=\pgfutil@empty + \gdef\pgfplots@plot@handler@graphics@bb@first{\pgf@x=16000pt \pgf@y=16000pt }% + \gdef\pgfplots@plot@handler@graphics@bb@second{\pgf@x=-16000pt \pgf@y=-16000pt }% \global\let\pgf@plotstreampoint=\pgfplots@plot@handler@graphics@collectbb% \global\let\pgf@plotstreamspecial=\pgfutil@gobble% \global\let\pgf@plotstreamend=\pgfplots@plot@handler@graphics@finish% - \def\pgfplots@plothandler@unbounded@visualize@jump{% + \def\pgfplotsplothandlervisualizejump{% \pgfplots@error{Sorry, plot graphics does not support 'unbounded coords=jump'.}% }% }% }% \def\pgfplots@plot@handler@graphics@collectbb#1{% \pgf@process{#1}% - \ifx\pgfplots@plot@handler@graphics@bb@first\pgfutil@empty - % ok, this is the lower left corner. - \xdef\pgfplots@plot@handler@graphics@bb@first{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgfplots@plot@handler@graphics@bb@first + \ifdim\pgf@xa<\pgf@x \pgf@x=\pgf@xa\fi + \ifdim\pgf@ya<\pgf@y \pgf@y=\pgf@ya\fi + \xdef\pgfplots@plot@handler@graphics@bb@first{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + % + \pgfplots@plot@handler@graphics@bb@second + \ifdim\pgf@xa>\pgf@x \pgf@x=\pgf@xa\fi + \ifdim\pgf@ya>\pgf@y \pgf@y=\pgf@ya\fi + \xdef\pgfplots@plot@handler@graphics@bb@second{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + % +}% +\def\pgfplots@plot@handler@graphics@finish{% + \let\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + % + % check if we have a pointmap. If so, the pointmap should be used + % to place the graphics. + \pgfkeysgetvalue{/pgfplots/plot graphics/points}\pgfplots@plot@handler@graphics@pointmap + \ifx\pgfplots@plot@handler@graphics@pointmap\pgfutil@empty \else - \ifx\pgfplots@plot@handler@graphics@bb@second\pgfutil@empty - % ok, this is the upper right corner. - \xdef\pgfplots@plot@handler@graphics@bb@second{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \let\pgfplots@plot@handler@graphics@parsepointmap@error=\relax + \expandafter\pgfplots@plot@handler@graphics@parsepointmap\expandafter{\pgfplots@plot@handler@graphics@pointmap}% + \fi + % + % + \ifx\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + % no pointmap. Good; then squeze graphics into the bounding + % box: + \pgfplots@plot@handler@graphics@usebb + \else + % oh, a pointmap! Process it. + \pgfplots@plot@handler@graphics@process@pointmap + \fi +}% + +% Parses the argument of '/pgfplots/plot graphics/points'. +% +% #1: the argument of the key above. +\def\pgfplots@plot@handler@graphics@parsepointmap#1{% + \let\pgfplots@plot@handler@graphics@pointmap@A@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@B@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@B@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@C@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@C@img\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@D@canvas\pgfutil@empty + \let\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \pgfplots@plot@handler@graphics@parsepointmap@loop#1\pgfplots@EOI + \ifpgfplots@plot@graphics@autoadjustaxis + \ifx\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty \else - \pgfplots@error{Error using 'plot graphics': I encountered more than two coordinates!? I expected only the lower left and upper right corners!}% + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \def\pgfplots@loc@TMPa{#1}% + \pgfplots@plot@handler@graphics@parsepointmap@error + \fi \fi \fi }% -\def\pgfplots@plot@handler@graphics@finish{% - \ifx\pgfplots@plot@handler@graphics@bb@first\pgfutil@empty +\def\pgfplots@plot@handler@graphics@parsepointmap@error{% + \pgfplots@error{plot graphics/points={\pgfplots@loc@TMPa} cannot be processed: I need at least *four* inner anchor points to automatically adjust the axis, i.e. 4 points of the form (x,y,z) => (imgx,imgy). Use 'plot graphics/auto adjust axis=false' to disable this feature}% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop{% + \pgfutil@ifnextchar\pgfplots@EOI{% + \pgfplots@gobble@until@EOI + }{% + \pgfplots@plot@handler@graphics@parsepointmap@loop@ + }% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@(#1,#2){% + \pgfutil@ifnextchar={% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)% + }{% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)=>(,)% + }% +}% +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@@(#1,#2)=>{% + \pgfutil@ifnextchar({% + \pgfplots@plot@handler@graphics@parsepointmap@loop@@@(#1,#2)% + }{% + \pgfplots@error{Syntax error for plot graphics/pointmap: expected '(#1,#2) => (...,...)'}% + \pgfplots@gobble@until@EOI + }% +} +\def\pgfplots@plot@handler@graphics@parsepointmap@loop@@@(#1,#2)(#3,#4){% + \def\pgfplotsplothandlergraphicspointmappointindex{}% + \def\pgfplots@loc@TMPc{#4}% + \ifx\pgfplots@loc@TMPc\pgfutil@empty + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@A@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{A}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@B@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{B}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@C@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{C}% + \else + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \def\pgfplotsplothandlergraphicspointmappointindex{D}% + \else + \def\pgfplotsplothandlergraphicspointmappointindex{*}% + %\pgfplots@error{Sorry, the argument '(#1,#2) => (#3,#4)' of plot graphics/pointmap is superfluos; ignoring it.}% + \fi + \fi + \fi + \fi + \pgfmathparse{#3}% + \let\pgfplots@loc@TMPb=\pgfmathresult + % + \pgfmathparse{#4}% + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @img\endcsname{{\pgfplots@loc@TMPb}{\pgfmathresult}}% + \fi + % + % + \pgfutil@in@,{#2}% + \ifpgfutil@in@ + \def\pgfplots@loc@TMPa##1,##2\relax{% + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @logical\endcsname{{#1}{##1}{##2}}% + % + \pgfplotsplothandlergraphicspointmappoint(#1,##1,##2)(#3,#4) + }% + \pgfplots@loc@TMPa#2\relax + \else + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @logical\endcsname{{#1}{#2}{}}% + \pgfplotsplothandlergraphicspointmappoint(#1,#2,)(#3,#4) + \fi + \pgfplots@plot@handler@graphics@parsepointmap@loop +} + +\def\pgfplotsplothandlergraphics@survey@pointmappoint(#1,#2,#3)(#4,#5){% + \def\pgfplots@current@point@x{#1}% + \def\pgfplots@current@point@y{#2}% + \def\pgfplots@current@point@z{#3}% + \pgfplots@coord@stream@coord +}% + +% PRECONDITION: +% \pgfplotsplothandlergraphicspointmappointindex is +% empty if and only if (#4,#5) is empty +% or it is an index among all points with non--empty (#4,#5) image +% coordinates. +\def\pgfplotsplothandlergraphicspointmappoint(#1,#2,#3)(#4,#5){% + \ifx\pgfplotsplothandlergraphicspointmappointindex\pgfutil@empty + \else + \def\pgfplots@loc@TMPc{#3}% + \ifx\pgfplots@loc@TMPc\pgfutil@empty + \pgfplotspointaxisxy{#1}{#2}% + \else + \pgfplotspointaxisxyz{#1}{#2}{#3}% + \fi + \expandafter\edef\csname pgfplots@plot@handler@graphics@pointmap@\pgfplotsplothandlergraphicspointmappointindex @canvas\endcsname{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + \fi +}% + +% Computes view-related keys which should be communicated to the axis +% in order to render the plot graphics correctly. +% +% @POSTCONDITION: \pgfplotsretval contains any required keys. +\def\pgfplotsplothandlergraphicspointmapcomputerequiredview{% + \begingroup + \let\pgfplotsretval=\pgfutil@empty + \ifx\pgfplots@plot@handler@graphics@pointmap@D@img\pgfutil@empty + \else + \pgfkeysgetvalue{/pgfplots/plot graphics/debug}\pgfplots@loc@TMPa + \def\pgfplots@loc@TMPb{true}% + \ifx\pgfplots@loc@TMPa\pgfplots@loc@TMPb + \def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug{1}% + \else + \def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug{0}% + \fi + % The following implementation computes the 'unit vector + % ratio' of the IMAGE. + % + % It then tells PGFPlots to use the very same unit vector + % ratio for its axis. + % + % + % The actual implementation is dumb; it requires 4 (!) points for + % which BOTH, the 3D coordinates and the projected 2D + % coordinates relative to the image's lower left corner are + % available. + % + % Since the 2D projected coordinates are generated by the map + % + % T(x,y,z) = o + x e_x + y e_y + z e_z in R^2 + % with o,e_x,e_y,e_z in R^2, + % + % I have 8 degrees of freedom (two for each of the four + % involved vectors). Thus, a simple approach is to provide 4 + % linearly independend points to get 8 equations. + % + % Then, I solve for o,e_x,e_y,e_z + % + \pgfplotsmatrixnewempty\pgfplotsmatrix + \pgfplotsmatrixresize\pgfplotsmatrix88% + % + \pgfplotsarraynewempty\pgfplotsE + \pgfplotsarrayresize\pgfplotsE8% + % + \def\pgfplots@extractimg##1##2{% + \def\pgfplots@img@x{##1}% + \def\pgfplots@img@y{##2}% + }% + \def\pgfplots@extractlogical##1##2##3{% + \def\pgfplots@logical@x{##1}% + \def\pgfplots@logical@y{##2}% + \def\pgfplots@logical@z{##3}% + }% + % Assemble the linear system such that + % x = [ + % exx + % exy + % eyx + % eyy + % ezx + % ezy + % ox + % oy] + % are the degrees of freedom. + \c@pgfplots@coordindex=0 + \pgfplotsutilforeachcommasep{A,B,C,D}\as\pgfplots@loc@TMPa{% + \expandafter\expandafter\expandafter\pgfplots@extractimg\csname pgfplots@plot@handler@graphics@pointmap@\pgfplots@loc@TMPa @img\endcsname + \expandafter\expandafter\expandafter\pgfplots@extractlogical\csname pgfplots@plot@handler@graphics@pointmap@\pgfplots@loc@TMPa @logical\endcsname + \ifx\pgfplots@logical@z\pgfutil@empty + \else + % + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,0\of\pgfplotsmatrix=\pgfplots@logical@x% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,1\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,2\of\pgfplotsmatrix=\pgfplots@logical@y% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,3\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,4\of\pgfplotsmatrix=\pgfplots@logical@z% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,5\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,6\of\pgfplotsmatrix\to{1}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,7\of\pgfplotsmatrix\to{0}% + % + \pgfplotsarrayletentry\c@pgfplots@coordindex\of\pgfplotsE=\pgfplots@img@x + % + \advance\c@pgfplots@coordindex by1 + \pgfplotsmatrixset \the\c@pgfplots@coordindex,0\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,1\of\pgfplotsmatrix=\pgfplots@logical@x% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,2\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,3\of\pgfplotsmatrix=\pgfplots@logical@y% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,4\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixletentry \the\c@pgfplots@coordindex,5\of\pgfplotsmatrix=\pgfplots@logical@z% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,6\of\pgfplotsmatrix\to{0}% + \pgfplotsmatrixset \the\c@pgfplots@coordindex,7\of\pgfplotsmatrix\to{1}% + % + \pgfplotsarrayletentry\c@pgfplots@coordindex\of\pgfplotsE=\pgfplots@img@y + % + \advance\c@pgfplots@coordindex by1 + \fi + }% + \ifx\pgfplots@logical@z\pgfutil@empty + \else + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + \pgfplotsplothandlergraphics@debug@matrix@to@string + \fi + % + % + \pgfplotsmatrixsolveLEQS\pgfplotsmatrix=\pgfplotsE + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem0\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@xx=\pgfmathresult + \edef\pgfmathresult{\pgfplotsarrayvalueofelem1\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@xy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/x dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@xx{-\pgfplots@xx}% + \edef\pgfplots@xy{-\pgfplots@xy}% + \fi + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem2\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@yx=\pgfmathresult + \edef\pgfmathresult{\pgfplotsarrayvalueofelem3\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@yy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/y dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@yx{-\pgfplots@yx}% + \edef\pgfplots@yy{-\pgfplots@yy}% + \fi + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem4\of\pgfplotsE}% + \pgfkeysgetvalue{/pgfplots/plot graphics/snap z}\pgfplots@loc@TMPa + \ifx\pgfplots@loc@TMPa\pgfutil@empty + \else + \let\pgfplots@zx=\pgfmathresult + \pgfplotscoordmath{default}{op}{veclen}{% + {\pgfplotsarrayvalueofelem4\of\pgfplotsE}% + {\pgfplotsarrayvalueofelem5\of\pgfplotsE}% + }% + \let\pgfplotszlen=\pgfmathresult + % + % compute 'snap z' relative to + % '\pgfplotszlen' + \pgfplotscoordmath{default}{parsenumber}{\pgfplots@loc@TMPa}% + \pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\pgfplotszlen}}% + \let\pgfplots@loc@TMPa=\pgfmathresult + % + \pgfplotscoordmath{default}{op}{abs}{{\pgfplots@zx}}% + \pgfplotscoordmath{default}{if less than}{\pgfmathresult}{\pgfplots@loc@TMPa}{% + \pgfplotscoordmath{default}{zero}% + }{% + \let\pgfmathresult=\pgfplots@zx + }% + \fi + \pgfplotscoordmath{default}{tofixed}\pgfmathresult% + \let\pgfplots@zx=\pgfmathresult + % + \edef\pgfmathresult{\pgfplotsarrayvalueofelem5\of\pgfplotsE}% + \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}% + \let\pgfplots@zy=\pgfmathresult + \if r\pgfkeysvalueof{/pgfplots/z dir/value}% + % they will be reversed again during the final + % processing: + \edef\pgfplots@zx{-\pgfplots@zx}% + \edef\pgfplots@zy{-\pgfplots@zy}% + \fi + % + % + \edef\pgfplotsretval{% + x={(\pgfplots@xx,\pgfplots@xy)},% + y={(\pgfplots@yx,\pgfplots@yy)},% + z={(\pgfplots@zx,\pgfplots@zy)},% + scale mode=scale uniformly,% + }% + % + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + \pgfplotsplothandlergraphicspointmapcomputerequiredview@debug@output + \fi + % + \ifx\pgfplotsretval\pgfutil@empty + \pgfplots@error{plot graphics failed to perform the 'auto adjust axis' feature \csname on@line\endcsname\space\space (compare 'plot graphics[debug]). The graphics might be scaled incorrectly. Perhaps the provided 'points' are not linearly independent?}% + \else + \begingroup + \pgfkeysgetvalue{/pgfplots/plot graphics/src}\pgfplots@loc@TMPa + \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% + \immediate\write + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug 16\else -1\fi + {PGFPlots plot graphics[auto adjust axis=true] {\the\t@pgfplots@tokc} \csname on@line\endcsname: determined options '\pgfplotsretval'. + \if1\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug + See \the\t@pgfplots@tokc.dat for debug output. + \else + Use 'plot graphics[debug] to generate debug output files. + \fi + ^^J}% + \endgroup + \fi + % + \fi + \fi + \pgfmath@smuggleone\pgfplotsretval + \endgroup +}% +\def\pgfplotsplothandlergraphics@debug@matrix@to@string{% + \pgfplotsmatrixtotext\pgfplotsmatrix + \let\pgfplotsmatrix@text=\pgfplotsretval + \pgfplotsarraytotext\pgfplotsE + \let\pgfplotsrhs@text=\pgfplotsretval +}% +\def\pgfplotsplothandlergraphicspointmapcomputerequiredview@debug@output{% + \begingroup + \immediate\openout\w@pgf@writea=\pgfkeysvalueof{/pgfplots/plot graphics/src}.dat + \pgfplotsarrayselect0\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect1\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img x unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/x dir/value}(reversed due to x dir=reverse)\fi,}% + \pgfplotsarrayselect2\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect3\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img y unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/y dir/value}(reversed due to y dir=reverse)\fi,}% + \pgfplotsarrayselect4\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect5\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img z unit=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb,}% + \pgfplotsarrayselect6\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPa=\pgfmathresult + \pgfplotsarrayselect7\of\pgfplotsE\to\pgfmathresult \pgfplotscoordmath{default}{tofixed}{\pgfmathresult}\let\pgfplots@loc@TMPb=\pgfmathresult + \immediate\write\w@pgf@writea{img origin=\pgfplots@loc@TMPa\space\pgfplots@loc@TMPb\if r\pgfkeysvalueof{/pgfplots/z dir/value}(reversed due to z dir=reverse)\fi,}% + \def\n{^^J}% + \def\t{^^I}% + \immediate\write\w@pgf@writea{canvasmapmatrix=[\pgfplotsmatrix@text];^^Jcanvasmaprhs = [\pgfplotsrhs@text];^^J}% + \immediate\closeout\w@pgf@writea + \endgroup +}% + +\def\pgfplots@plot@handler@graphics@process@pointmap{% + \begingroup + % determine natural size: + \pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel get natural size/.@cmd}{}% + \def\pgfplots@loc@TMPa##1##2{% + \global\pgf@x=##1 + \global\pgf@y=##2 + }% + \expandafter\pgfplots@loc@TMPa\pgfmathresult + \edef\pgfplots@W{\pgf@sys@tonumber\pgf@x}% natural WIDTH + \edef\pgfplots@H{\pgf@sys@tonumber\pgf@y}% natural HEIGHT + % + \def\pgfplots@extractimg##1##2{% + \def\pgfplots@img@x{##1}% + \def\pgfplots@img@y{##2}% + }% + \def\pgfplots@extractimgaspoint##1##2{% + \pgfqpoint{##1pt}{##2pt}% + }% + \expandafter\pgfplots@extractimg\pgfplots@plot@handler@graphics@pointmap@A@img% anchor 1 in image + \let\pgfplots@Ax=\pgfplots@img@x + \let\pgfplots@Ay=\pgfplots@img@y + % + \pgfplots@plot@handler@graphics@pointmap@A@canvas% the canvas coordinate corresponding to 'A' + \edef\pgfplots@ax{\pgf@sys@tonumber\pgf@x}% call it 'a' + \edef\pgfplots@ay{\pgf@sys@tonumber\pgf@y}% + % + % compute the CANVAS diagonal between the two anchors points a,b, + % dd := b-a + \pgfpointdiff + \pgfplots@plot@handler@graphics@pointmap@A@canvas + \pgfplots@plot@handler@graphics@pointmap@B@canvas + \edef\pgfplots@ddx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@ddy{\pgf@sys@tonumber\pgf@y}% + % + % compute the IMAGE diagonal between the two image anchor points A,B, + % DD := B - A + \pgfpointdiff + {\expandafter\pgfplots@extractimgaspoint\pgfplots@plot@handler@graphics@pointmap@A@img} + {\expandafter\pgfplots@extractimgaspoint\pgfplots@plot@handler@graphics@pointmap@B@img}% + \pgfplots@loop@CONTINUEtrue + \ifdim\pgf@x=0pt \pgfplots@loop@CONTINUEfalse \fi + \ifdim\pgf@y=0pt \pgfplots@loop@CONTINUEfalse \fi + \ifpgfplots@loop@CONTINUE + \else + \pgfplots@error{Sorry, the first two points with '=>' in plot graphics[points={}] are expected to have different image Y coordinates. Please reorder the sequence.}% + \fi + \edef\pgfplots@DDx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@DDy{\pgf@sys@tonumber\pgf@y}% + % + % What I need now is a shift and the CANVAS dimensions of the + % image. Both can be computed using the relative sizes dd/DD. + % + % The shift is needed to compute the lower left corner of the + % CANVAS image. thus, the lower left CANVAS image corresponds to + % the (0,0) coordinate in the IMAGE. + % + % Remember that 'A' is the anchor 1 in IMAGE coordinates. It is a + % vector from (0,0) --> (A_x,A_y) in IMAGE coordinates. + % + % Now, I want a vector (v_x,v_y) such that q + v = a in CANVAS + % coordinates. Here, 'q' is the lower left corner; it corresponds + % to the (0,0) in IMAGE coordinates. Thus, we have + % v = (a-q). Taking the relative sizes of dd and DD, we find + % + % DD_x / A_x = dd_x / v_x + % DD_y / A_y = dd_y / v_y + % + % and finally q = a-v is the lower left CANVAS coordinate. + \pgfmath@basic@divide@{\pgfplots@ddx}{\pgfplots@DDx}% + \let\pgfplots@x@rel=\pgfmathresult + % + \pgfmath@basic@divide@{\pgfplots@ddy}{\pgfplots@DDy}% + \let\pgfplots@y@rel=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Ax}{\pgfplots@x@rel}% + \let\pgfplots@vx=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Ay}{\pgfplots@y@rel}% + \let\pgfplots@vy=\pgfmathresult + % + % + % + % + % now, the canvas width. It is even simpler because it holds + % + % DD_x / dd_x = W / w + % DD_y / dd_y = H / h + % + % where (W,H) is the natural size (i.e. in IMAGE coordinates) of the picture and + % (w,h) is the size the picture will occupy in CANVAS coordinates. + % + \pgfmath@basic@multiply@{\pgfplots@x@rel}{\pgfplots@W}% + \let\pgfplots@w=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@y@rel}{\pgfplots@H}% + \let\pgfplots@h=\pgfmathresult + % + \edef\pgfplots@plot@handler@graphics@DRAW@{% + \noexpand\pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{% + {\pgfplots@w pt}% width + {\pgfplots@h pt}% height + }% + }% + \pgfpointadd + {\pgfplots@plot@handler@graphics@pointmap@A@canvas}% the canvas coordinate corresponding to 'A' + {\pgfqpointscale{-1} + {\pgfqpoint{\pgfplots@vx pt}{\pgfplots@vy pt}}% + }% + \edef\pgfplots@plot@handler@graphics@pointmap@lowerleft@canvas{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% +% + % + % + \begingroup + \pgftransformshift{}% simply take \pgf@x and \pgf@y + % + \node[/pgfplots/plot graphics/node] {% + \pgfplots@plot@handler@graphics@DRAW@ + };% + \endgroup + \ifx\pgfplots@plot@handler@graphics@pointmap@C@canvas\pgfutil@empty + \ifpgfplots@threedim + \pgfplots@warning{plot graphics in 3D axis has just two inner anchors (those with '(x,y,z)=>(imgx,imgy)'). You should provide a third one such that I can check for correct scaling.}% + \fi + \else + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{C}% + \ifx\pgfplots@plot@handler@graphics@pointmap@D@canvas\pgfutil@empty + \else + \pgfplots@plot@handler@graphics@pointmap@sanitize@scaling{D}% + \fi + \fi + \endgroup +}% + +% Checks if the logical and canvas coordinates of the point identified +% by #1 are correct. +% +% #1: a character in {A,B,C...}. +% +\def\pgfplots@plot@handler@graphics@pointmap@sanitize@scaling#1{% + \begingroup + \expandafter\let\expandafter\pgfplots@point@img\csname pgfplots@plot@handler@graphics@pointmap@#1@img\endcsname + \expandafter\let\expandafter\pgfplots@point@canvas\csname pgfplots@plot@handler@graphics@pointmap@#1@canvas\endcsname + \expandafter\let\expandafter\pgfplots@point@logical\csname pgfplots@plot@handler@graphics@pointmap@#1@logical\endcsname + \expandafter\pgfplots@extractimgaspoint\pgfplots@point@img% anchor 3 in image + \edef\pgfplots@Cx{\pgf@sys@tonumber\pgf@x}% + \edef\pgfplots@Cy{\pgf@sys@tonumber\pgf@y}% + % + \pgfmath@basic@multiply@{\pgfplots@Cx}{\pgfplots@x@rel}% + \let\pgfplots@Cx=\pgfmathresult + % + \pgfmath@basic@multiply@{\pgfplots@Cy}{\pgfplots@y@rel}% + \let\pgfplots@Cy=\pgfmathresult + \pgfpointadd + {\pgfplots@plot@handler@graphics@pointmap@lowerleft@canvas}% + {\pgfpoint\pgfplots@Cx\pgfplots@Cy}% + \edef\pgfplots@point@canvas@check{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% + \pgfpointdiff + {\pgfplots@point@canvas@check}% + {\pgfplots@point@canvas}% + \ifdim\pgf@x<0pt \pgf@x=-\pgf@x\fi + \ifdim\pgf@y<0pt \pgf@y=-\pgf@y\fi + \def\pgfplots@is@the@same@point{1}% + \ifdim\pgf@x>\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol} + \def\pgfplots@is@the@same@point{0}% + \else + \ifdim\pgf@y>\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol} + \def\pgfplots@is@the@same@point{0}% + \fi + \fi + \if0\pgfplots@is@the@same@point + % + \begingroup + \pgfkeysgetvalue{/pgfplots/plot graphics/src}\pgfplots@loc@TMPa + \t@pgfplots@tokc=\expandafter{\pgfplots@loc@TMPa}% + \def\pgfplots@extractcoord##1##2##3{##1,##2,##3}% + \pgfplots@error{sorry, I can't fix the scaling of 'plot graphics {\the\t@pgfplots@tokc}'. + The points (\expandafter\pgfplots@extractcoord\pgfplots@plot@handler@graphics@pointmap@A@logical) and (\expandafter\pgfplots@extractcoord\pgfplots@plot@handler@graphics@pointmap@B@logical) are correct, but the point (\expandafter\pgfplots@extractcoord\pgfplots@point@logical) is wrong (its position vector has an error of (\the\pgf@x,\the\pgf@y) which is larger than 'squeeze tol=\pgfkeysvalueof{/pgfplots/plot graphics/squeeze tol}'). This is probably caused by improper relations between the axis' unit vectors because the view is incorrect.^^J + - Is the 'view' argument correct (matlab: [h,v] = view)? ^^J + - Does your image have a non-trivial 'plot box ratio' (matlab: ratio = pbaspect)?^^J + Please refer to the pgfplots manual for details. If you continue now, I'll show the points in the image}% + \endgroup + % + % + \scope + \pgfsetstrokecolor{black}% + \pgfsetfillcolor{red}% + \pgfpathcircle{\pgfplots@point@canvas@check}{2pt}% + \pgfusepath{stroke,fill}% + \pgfsetfillcolor{green}% + \pgfpathcircle{\pgfplots@point@canvas}{2pt}% + \pgfusepath{stroke,fill}% + \draw[->,red] + \pgfextra{ + \pgfpathmoveto{\pgfplots@point@canvas@check}% + \pgfpathlineto{\pgfplots@point@canvas}}; + \endscope + \fi + \endgroup +} + +\def\pgfplots@plot@handler@graphics@usebb{% + \pgfpointdiff{\pgfplots@plot@handler@graphics@bb@first}{\pgfplots@plot@handler@graphics@bb@second}% + \def\pgfplots@plot@handler@graphics@finish@ok{1}% + \ifdim\pgf@x=0pt + \def\pgfplots@plot@handler@graphics@finish@ok{0}% + \else + \ifdim\pgf@y=0pt + \def\pgfplots@plot@handler@graphics@finish@ok{0}% + \fi + \fi + \if0\pgfplots@plot@handler@graphics@finish@ok \pgfplots@error{Error using 'plot graphics': I got too few coordinates! I expected the lower left and upper right corners!}% \xdef\pgfplots@plot@handler@graphics@bb@first{\noexpand\pgfqpoint{0pt}{0pt}}% + \xdef\pgfplots@plot@handler@graphics@bb@first{\noexpand\pgfqpoint{0pt}{0pt}}% \fi - \ifx\pgfplots@plot@handler@graphics@bb@second\pgfutil@empty - \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 \begingroup % determine the lower left / upper right corners. \pgfplots@plot@handler@graphics@bb@first @@ -6233,11 +8378,44 @@ \ifx\pgfplots@loc@TMPd\pgfutil@empty \pgfplots@error{Error using 'plot graphics': I don't have a graphics file name! Please set the '/pgfplots/plot graphics/src' key to the image file name. Skipping this plot.}% \else + \begingroup + \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPc}% + % + \def\pgfplots@loc@TMPa{#1}% + \def\pgfplots@loc@TMPb{#2}% + % + \edef\pgfplots@loc@TMPc{% + \the\t@pgfplots@toka,% + \ifx\pgfplots@loc@TMPa\pgfutil@empty\else width=#1,\fi + \ifx\pgfplots@loc@TMPb\pgfutil@empty\else height=#2,\fi + }% + \pgfmath@smuggleone\pgfplots@loc@TMPc + \endgroup + % \def\pgfplots@loc@TMPa{\pgfkeysvalueof{/pgfplots/plot graphics/includegraphics cmd}}% - \expandafter\pgfplots@loc@TMPa\expandafter[\pgfplots@loc@TMPc,width=#1,height=#2]{\pgfplots@loc@TMPd}% + \expandafter\pgfplots@loc@TMPa\expandafter[\pgfplots@loc@TMPc]{\pgfplots@loc@TMPd}% \fi }% +\def\pgfplots@plot@handler@graphics@getnaturalsize{% + \begingroup + \setbox0=\hbox{% + \pgfplots@invoke@pgfkeyscode{/pgfplots/plot graphics/lowlevel draw/.@cmd}{{}{}}% + }% + \pgf@x=\wd0 + \pgf@y=\ht0 + \ifdim\dp0>0pt + \advance\pgf@y by\dp0 + \else + \ifdim\dp0<0pt + \advance\pgf@y by-\dp0 + \fi + \fi + \xdef\pgfplots@glob@TMPb{{\the\pgf@x}{\the\pgf@y}}% + \endgroup + \let\pgfmathresult=\pgfplots@glob@TMPb +}% + % legends for plot graphics should not use 'plot graphics' themselfes % (for obvious reasons). % This key handles that. Furthermore, it remembers the plot mark for @@ -6263,668 +8441,6 @@ } -% 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{\global\pgf@x=-16000.0pt \global\pgf@y=-16000.0pt }% - }% - \let\pgfplotsplothandlermesh@check@unbounded=\pgfplotsplothandlermesh@check@unbounded@setbool - \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: - % in fact, this does only remember the maximum capacity; - % it doesn't fill the 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 - }% -}% - -\def\pgfplotsplothandlermesh@check@unbounded@setbool#1#2\relax{% - \ifdim#1=-16000pt - \pgfplots@loc@tmpfalse - \fi -}% - -\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/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{\global\pgf@x=##1 \global\pgf@y=##2 }{##3}% - }% - \c@pgfplots@scanlineindex=0 - \pgfutil@loop - \ifnum\c@pgfplots@scanlineindex<\pgfplotsplothandlermesh@rows\relax - \expandafter\pgfplotsapplistXlet\expandafter\pgfplots@loc@TMPd\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@TMPd - \advance\c@pgfplots@scanlineindex by1 - \pgfutil@repeat - \let\pgfplots@loc@TMPd=\relax -}% - -\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{% - \global\pgf@x=#1\relax - \global\pgf@y=#2\relax -}% -\def\pgfplotsplothandlermesh@unpack@mean@accum#1#2#3{% - \global\pgf@x=#1\relax - \global\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. % @@ -6974,8 +8490,7 @@ \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}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{reversed}% }% \def\pgfplots@coord@stream@end{% \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversed}% @@ -6997,8 +8512,7 @@ }% }% \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}% + \expandafter\pgfplots@zbuffer@local@SETCUR\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded}% \advance\c@pgfplots@scanlineindex by1 }% \def\pgfplots@coord@stream@end{% @@ -7010,7 +8524,7 @@ \pgfkeysdef{/pgfplots/array/unscope pre}{% \pgfplotsapplistXnewempty{\pgfp@sortedlist}% \pgfplotsarrayforeachungrouped\pgfplots@zbuffer@local\as\curelem{% - \expandafter\pgfplotsapplistXpushback\curelem\to{\pgfp@sortedlist}% + \expandafter\pgfplotsapplistXpushback\expandafter{\expandafter{\curelem}}\to{\pgfp@sortedlist}% }% \pgfplotsapplistXlet\pgfplots@loc@TMPa={\pgfp@sortedlist}% \global\let\pgfplotsglobalretval=\pgfplots@loc@TMPa @@ -7034,44 +8548,58 @@ % only need to know whether [xy] coordinates are sorted % ascending or descending. This information is already ready. % - \begingroup - \if+\pgfkeysvalueof{/pgfplots/x coord sorting}% - \def\pgfplots@minmaxvalue@x{0}% - \else - \def\pgfplots@minmaxvalue@x{0}% - \fi - \if+\pgfkeysvalueof{/pgfplots/y coord sorting}% - \def\pgfplots@minmaxvalue@y{0}% - \else - \def\pgfplots@minmaxvalue@y{1}% - \fi - \pgfplotsifaxissurfaceisforeground{\pgfplots@minmaxvalue@x vv}{% - \def\pgfplots@reverse@x{1}% - }{% - \def\pgfplots@reverse@x{0}% - }% - \pgfplotsifaxissurfaceisforeground{v\pgfplots@minmaxvalue@y v}{% - \def\pgfplots@reverse@y{1}% - }{% - \def\pgfplots@reverse@y{0}% - }% - \if1\pgfplots@reverse@x - \if1\pgfplots@reverse@y - \pgfkeys{/pgfplots/z buffer=reverse xy seq}% + \if1\pgfplotsplothandlermesh@matrixinput + % mesh input=lattice + \begingroup + \if+\pgfkeysvalueof{/pgfplots/x coord sorting}% + \def\pgfplots@minmaxvalue@x{0}% + \else + \def\pgfplots@minmaxvalue@x{0}% + \fi + \if+\pgfkeysvalueof{/pgfplots/y coord sorting}% + \def\pgfplots@minmaxvalue@y{0}% + \else + \def\pgfplots@minmaxvalue@y{1}% + \fi + \pgfplotsifaxissurfaceisforeground{\pgfplots@minmaxvalue@x vv}{% + \def\pgfplots@reverse@x{1}% + }{% + \def\pgfplots@reverse@x{0}% + }% + \pgfplotsifaxissurfaceisforeground{v\pgfplots@minmaxvalue@y v}{% + \def\pgfplots@reverse@y{1}% + }{% + \def\pgfplots@reverse@y{0}% + }% + \if1\pgfplots@reverse@x + \if1\pgfplots@reverse@y + \pgfkeys{/pgfplots/z buffer=reverse xy seq}% + \else + \pgfkeys{/pgfplots/z buffer=reverse x seq}% + \fi \else - \pgfkeys{/pgfplots/z buffer=reverse x seq}% + \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 \else - \if1\pgfplots@reverse@y - \pgfkeys{/pgfplots/z buffer=reverse y seq}% + % mesh input=patches + \ifpgfplots@threedim + \if\pgfplots@meshmode n% + \else + \pgfkeys{/pgfplots/z buffer=sort}% + \fi \else \pgfkeys{/pgfplots/z buffer=none}% \fi + \gdef\pgfplotsglobalretval{#1}% \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% @@ -7079,10 +8607,8 @@ \gdef\pgfplotsglobalretval{#1}% \else % mesh=true - \begingroup \pgfkeysalso{/pgfplots/z buffer=auto}% \pgfplots@apply@zbuffer{#1}% - \endgroup \fi \fi }% @@ -7109,8 +8635,7 @@ \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}% + \expandafter\pgfplotsprependlistXpushfront\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{reversedscanline}% \advance\c@pgfplots@scanlineindex by1 \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax \pgfplotsprependlistXlet\pgfplots@loc@TMPa={reversedscanline}% @@ -7145,8 +8670,7 @@ \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}% + \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@coord@stream@foreach@NORMALIZED@curencoded@braced}\to{\scanline}% \advance\c@pgfplots@scanlineindex by1 \ifnum\c@pgfplots@scanlineindex=\pgfplotsscanlinelength\relax \pgfplotsapplistXlet\pgfplots@loc@TMPa={\scanline}% @@ -7175,12 +8699,14 @@ % 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 + \pgfplotsaxisdeserializedatapointfrom{#1}% + \pgfplotsmathfloatviewdepthxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@current@point@z}% \let\pgfplots@apply@zbuffer@SORT@iflessthan@a=\pgfmathresult - \edef\pgfplots@loc@TMPb{#2}% - \expandafter\pgfplots@apply@zbuffer@SORT@iflessthan@\pgfplots@loc@TMPb\relax + % + \pgfplotsaxisdeserializedatapointfrom{#2}% + \pgfplotsmathfloatviewdepthxyz{\pgfplots@current@point@x}{\pgfplots@current@point@y}{\pgfplots@current@point@z}% \let\pgfplots@apply@zbuffer@SORT@iflessthan@b=\pgfmathresult + % \pgfmathfloatlessthan@{\pgfplots@apply@zbuffer@SORT@iflessthan@b}{\pgfplots@apply@zbuffer@SORT@iflessthan@a}% \ifpgfmathfloatcomparison #3\relax @@ -7189,14 +8715,6 @@ \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 @@ -7321,7 +8839,7 @@ \if1\csname pgfpmeta@\pgfplotspointmetainputhandler @issymbolic\endcsname \else % ok, be fault tolerant and round to an integer: - \pgfmathfloattofixed{\pgfplotspointmeta}% + \pgfplotscoordmath{meta}{tofixed}{\pgfplotspointmeta}% \begingroup \pgfkeys{/pgf/number format/precision=0}% \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% |