%-------------------------------------------- % % Package pgfplots, library for ternary plots (triangular axes). % % Copyright 2010 by Christian Feuersänger. % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % % % This is a library to draw ternary diagrams. % % A ternary diagram visualizes percentages of three components in a % triangle. % % Sometimes there is also contour data drawn on top of the ternary % diagram, i.e. data (x,y,z, T(x,y,z) ), but I can't do that yet. % % How to read a ternary diagram: http://csmres.jmu.edu/geollab/fichter/SedRx/readternary.html % % Another usage example: http://www.sv.vt.edu/classes/MSE2094_NoteBook/96ClassProj/experimental/ternary2.html % % Drawing ternary diagrams: http://staff.aist.go.jp/a.noda/programs/ternary/ternary-en.html % % computing these coordinates: http://www.gamedev.net/community/forums/topic.asp?topic_id=451357 % \pgfplotsdefineaxistype{ternary}{% \pgfplots@ternary@activate }% \newif\ifpgfplots@ternary@rellimits \pgfplotsset{ /pgfplots/ternary limits relative/.is if=pgfplots@ternary@rellimits, /pgfplots/ternary limits relative=true, /pgfplots/ternary limits relative/.default=true, /pgfplots/ternary relative limits/.style={/pgfplots/ternary limits relative=#1}, /pgfplots/ternary start x/.initial=, % FIXME : implement /pgfplots/ternary start y/.initial=, /pgfplots/ternary start z/.initial=, /pgfplots/every ternary axis/.style={ /pgfplots/tick align=outside, grid=major, xticklabel style={anchor=west}, % yticklabel style={anchor=south east}, % zticklabel style={anchor=north}, /pgfplots/every 3d description/.style={}, /pgfplots/every axis x label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},% /pgfplots/every axis y label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},% /pgfplots/every axis z label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},% /pgfplots/every x tick scale label/.style={at={(xticklabel cs:0.95,5pt)},anchor=near xticklabel,inner sep=0pt}, /pgfplots/every y tick scale label/.style={at={(yticklabel cs:0.95,5pt)},anchor=near yticklabel,inner sep=0pt}, /pgfplots/every z tick scale label/.style={at={(yticklabel cs:0.95,5pt)},anchor=near yticklabel,inner sep=0pt}, /pgfplots/every axis title shift=15pt, /pgfplots/every axis legend/.style={% cells={anchor=center}, inner xsep=3pt,inner ysep=2pt,nodes={inner sep=2pt,text depth=0.15em}, shape=rectangle,% fill=white,% draw=black, at={(1.03,1.03)}, anchor=north west,% }, annot/point format 3d/.initial={(\%.2f, \%.2f, \%.2f)}, }, } \def\pgfplots@ternary@activate{% \let\pgfplotsqpointxy=\pgfplotsqpointxy@ternary \let\pgfplotsqpointxy@orthogonal=\pgfplotsqpointxy \let\pgfplotsqpointxyz=\pgfplotsqpointxyz@ternary \let\pgfplots@draw@axis=\pgfplots@draw@axis@ternary \def\pgfplots@drawaxis@outerlines@separate@onorientedsurf##1##2{}% \def\pgfplots@drawaxis@innerlines@onorientedsurf##1##2##3{}% \let\pgfplots@draw@axis@post=\pgfplots@draw@axis@post@ternary \let\pgfplots@initsizes=\pgfplots@initsizes@ternary \let\pgfplots@limits@ready=\pgfplots@limits@ready@ternary \let\pgfplotspoint@initialisation@axes=\pgfplotspoint@initialisation@axes@ternary \let\pgfplotspoint@initialisation@units=\pgfplotspoint@initialisation@units@ternary \let\pgfplots@initsizes@setunitvector=\pgfplots@initsizes@setunitvector@ternary \let\pgfplots@computeunitvectorlengths=\pgfplots@computeunitvectorlengths@ternary \let\pgfplotspointouternormalvectorofaxis@=\pgfplotspointouternormalvectorofaxis@ternary \let\pgfplots@prepare@ZERO@coordinates=\pgfplots@prepare@ZERO@coordinates@ternary \def\pgfplots@scaleaxes@to@BB@##1##2{}% \let\pgfplotsgetnormalforcurrentview=\relax \def\pgfplots@drawtickgridlines@INSTALLCLIP@onorientedsurf##1{}% \let\pgfplots@clippath@prepare@for@axistype=\pgfplots@clippath@prepare@for@axistype@ternary % \pgfkeys{/pgfplots/oriented surf installed/.add={}{% \let\pgfplotspointonorientedsurfaceab@ternary@orig=\pgfplotspointonorientedsurfaceab \let\pgfplotspointonorientedsurfaceab=\pgfplotspointonorientedsurfaceab@ternary }}% \let\pgfplotspointonorientedsurfaceabwithbshift=\pgfplotspointonorientedsurfaceabwithbshift@ternary \pgfkeyssetvalue{/pgfplots/view/az}{}% \pgfkeyssetvalue{/pgfplots/view/el}{}% \let\pgfplots@set@options@sanitize=\relax \let\pgfplots@set@options@sanitizemode=\relax % \expandafter\def\expandafter\pgfplots@notify@options@are@set\expandafter{\pgfplots@notify@options@are@set \ifpgfplots@ternary@rellimits \pgfplotsset{scaled ticks=false,ticklabel style={/pgf/number format/precision=0}}% \let\pgfplots@show@ticklabel@orig=\pgfplots@show@ticklabel@ \let\pgfplots@show@ticklabel@=\pgfplots@show@ticklabel@ternary@relative \fi }% % % this here is set *before* 'every ternary axis' is invoked. \pgfplotsset{ /pgfplots/footnotesize/.append style= {/pgfplots/every axis title shift=15pt},% /pgfplots/tiny/.append style= {/pgfplots/every axis title shift=15pt},% enlargelimits=false, xmin=0,xmax=1, ymin=0,ymax=1, zmin=0,zmax=1, annot/point format/.style={/pgfplots/annot/point format 3d={##1}}, }% \def\pgfplots@xticklabel@pos{}% \def\pgfplots@yticklabel@pos{}% \def\pgfplots@zticklabel@pos{}% %\def\pgfplots@xaxislinesnum{1}% %\def\pgfplots@yaxislinesnum{3}% %\def\pgfplots@zaxislinesnum{3}% \def\pgfplotsifaxissurfaceisforeground##1##2##3{##2}% \def\pgfplots@init@ticklabelaxisspecfor##1##2{}% \def\pgfplots@xticklabelaxisspec{v00}% \def\pgfplots@yticklabelaxisspec{0v0}% \def\pgfplots@zticklabelaxisspec{00v}% \def\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@##1##2##3{% \pgfplotspointonorientedsurfaceabtolinespec v##1% \edef\pgfplots@loc@TMPe{\csname pgfplots@\pgfplotspointonorientedsurfaceA ticklabelaxisspec\endcsname}% \ifx\pgfplots@loc@TMPe\pgfplotsretval %\message{pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@{##1}---> TRUE.}% ##2% \else %\message{pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@{##1}---> FALSE.}% ##3% \fi }% \def\pgfplots@ifgridlines@onorientedsurf@should@be@drawn##1##2{% ##1% FIXME }% \def\pgfplotspointonorientedsurfaceabmatchaxisline##1##2{% \pgfplotspointonorientedsurfaceabtolinespec v0% FIXME that's just a bad guess! \edef\pgfplots@loc@TMPe{##1}% \ifx\pgfplots@loc@TMPe\pgfplotsretval \def##2{0}% \else \def##2{}% \fi }% \let\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn=\pgfplots@ifaxisline@B@onorientedsurf@should@be@drawn@% % % % cartesian cs \tikzdeclarecoordinatesystem{cartesian}{\edef\pgfplots@loc@TMPa{##1}\expandafter\pgfplotspointcartesian@\pgfplots@loc@TMPa\pgfplots@coord@end} }% \def\pgfplots@show@ticklabel@ternary@relative#1#2{% \csname pgfplots@ternary@map@to@unit@#1\endcsname{#2}% \pgfmathfloatparsenumber\pgfmathresult \pgfmathfloatshift@\pgfmathresult{2}% \let\tick=\pgfmathresult }% \def\pgfplotspointcartesian@#1,#2\pgfplots@coord@end{% \pgfpointxy@orig{#1}{#2}% }% % This here is *the* key point why ternary axes can be processed with % almost the same code as rectangular axes. % % Recall that rectangular axes are drawn using "oriented surfaces", % the complete code is based on them. The "a" axis is the direction in % which we have tick positions and the "b" axis is the direction in % which tick lines (or grid lines) shall be drawn). % % Now, ternary axes do not directly fit into the "oriented surface" % framework. But they have a lot of structure which allows to use it % with a specialed "pointonorientedsurfaceab" routine: by noting that % - there are only three axes, % - the axis containing tick lines (and grid lines) *always* has one % component set to 0 (lower limit), and the remaining two components % sum to 1. Thus, we can simply use one value (for example the "a" % value) and compute the remaining one, % - \pgfplotspointonorientedsurfaceab is *always* invoked with % b set to either the lower or the upper limit. % The lower limit is easy, see above. The upper limit is mainly used % for grid lines, more precisely it denotes the target point of the grid line. % I use special handling to find this target point (by exchanging % coordinate components, see the implementation). % % #1: the "a" value on the oriented surf % #2: the "b" value. Note that *only* the lower *or* the upper limit % on the "b" axis are supported here! % \def\pgfplotspointonorientedsurfaceab@ternary#1#2{% \let\pgfplotspointonorientedsurfaceab@ternary@fixedx=\pgfplotspointonorientedsurfaceabsetupfor@fixedx \let\pgfplotspointonorientedsurfaceab@ternary@fixedy=\pgfplotspointonorientedsurfaceabsetupfor@fixedy \let\pgfplotspointonorientedsurfaceab@ternary@fixedz=\pgfplotspointonorientedsurfaceabsetupfor@fixedz % %\message{\string\pgfplotspointonorientedsurfaceab{#1}{#2} -----> }% \ifpgfplots@ternary@next@is@unitinterval \edef\pgfplotspointonorientedsurfaceab@ternary@A{#1}% \edef\pgfplotspointonorientedsurfaceab@ternary@B{#2}% \else \csname pgfplots@ternary@map@to@unit@\pgfplotspointonorientedsurfaceA\endcsname{#1}% \let\pgfplotspointonorientedsurfaceab@ternary@A=\pgfmathresult % \csname pgfplots@ternary@map@to@unit@\pgfplotspointonorientedsurfaceB\endcsname{#2}% \let\pgfplotspointonorientedsurfaceab@ternary@B=\pgfmathresult \fi \if0\pgfplotspointonorientedsurfacespecsymbol \else \pgfplots@error{Internal processing error: only \string\pgfplotspointonorientedsurfaceab\space for ternary axes works only for oriented surfs fixed to LOWER or UPPER axis limits.}% \fi %\message{A=\pgfplotspointonorientedsurfaceab@ternary@A; B=\pgfplotspointonorientedsurfaceab@ternary@B -----> }% \ifdim\pgfplotspointonorientedsurfaceab@ternary@B pt=0pt \pgfmath@basic@subtract@{1}{\pgfplotspointonorientedsurfaceab@ternary@A}% \let\pgfplotspointonorientedsurfaceab@ternary@B=\pgfmathresult \expandafter\def\csname pgfplotspointonorientedsurfaceabsetupfor@fixed\pgfplotspointonorientedsurfaceN\endcsname{0}% \else %\let\pgfplots@loc@TMPa=\pgfplotspointonorientedsurfaceab@ternary@A %\pgfmath@basic@subtract@{1}{\pgfplotspointonorientedsurfaceab@ternary@A}% %\let\pgfplotspointonorientedsurfaceab@ternary@A=\pgfmathresult %\let\pgfplotspointonorientedsurfaceab@ternary@B=\pgfplots@loc@TMPa \pgfmath@basic@subtract@{1}{\pgfplotspointonorientedsurfaceab@ternary@A}% \def\pgfplotspointonorientedsurfaceab@ternary@B{0}% \expandafter\let\csname pgfplotspointonorientedsurfaceabsetupfor@fixed\pgfplotspointonorientedsurfaceN\endcsname=\pgfmathresult% \fi % \global\pgfplots@ternary@next@is@unitintervaltrue %\message{\string\pgfplotspointonorientedsurfaceab@orig{\pgfplotspointonorientedsurfaceab@ternary@A}{\pgfplotspointonorientedsurfaceab@ternary@B}[fixedsymbol=\pgfplotspointonorientedsurfacespecsymbol; a=\pgfplotspointonorientedsurfaceA,b=\pgfplotspointonorientedsurfaceB.]}% \pgfplotspointonorientedsurfaceab@ternary@orig {\pgfplotspointonorientedsurfaceab@ternary@A}% {\pgfplotspointonorientedsurfaceab@ternary@B}% % \let\pgfplotspointonorientedsurfaceabsetupfor@fixedx=\pgfplotspointonorientedsurfaceab@ternary@fixedx \let\pgfplotspointonorientedsurfaceabsetupfor@fixedy=\pgfplotspointonorientedsurfaceab@ternary@fixedy \let\pgfplotspointonorientedsurfaceabsetupfor@fixedz=\pgfplotspointonorientedsurfaceab@ternary@fixedz }% \def\pgfplotspointonorientedsurfaceabwithbshift@ternary#1#2#3{% % implement the shift in "b" direction explicitly: % \pgfplotspointonorientedsurfaceab@ternary{#1}{#2}% \edef\pgfplots@loc@TMPe{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% \pgfpointadd {\pgfplots@loc@TMPe}% {% \begingroup % I need a '-' here because for ternary axes, the "b" axis % points to the *outside* instead of the inside. \pgf@xa=-#3\relax \if r\pgfkeysvalueof{/pgfplots/\pgfplotspointonorientedsurfaceB\space dir/value}% % oh. a reversed axis. \pgf@xa=-\pgf@xa \fi \edef\pgfplots@loc@TMPa{\pgf@sys@tonumber\pgf@xa}% \pgfmath@basic@multiply@{\csname pgfplots@\pgfplotspointonorientedsurfaceB @inverseveclength\endcsname}{\pgfplots@loc@TMPa}% \pgfmath@smuggleone\pgfmathresult \endgroup \let\pgfplots@loc@TMPa=\pgfmathresult \pgfqpointscale{\pgfplots@loc@TMPa}{\csname pgfplotspointunit\pgfplotspointonorientedsurfaceB\endcsname}% }% } \let\pgfplots@initsizes@ternary@orig=\pgfplots@initsizes \def\pgfplots@initsizes@ternary{% \ifpgfplots@threedim \else \pgfplots@error{Sorry, 'axis type=ternary' needs a three dimensional axes. Make sure you supplied three dimensional coordinates (using \string\addplot3, for example). This error is critical; I can't recover}% \fi % \pgfplots@initsizes@get@width@withoutlabels \pgf@x=\pgfmathresult \edef\pgfplots@width@ternary{\pgf@sys@tonumber\pgf@x}% % \pgfplots@initsizes@ternary@orig % }% \let\pgfplots@limits@ready@original=\pgfplots@limits@ready \def\pgfplots@limits@ready@ternary{% \pgfplots@limits@ready@original % %\message{ternary with limits x=[\pgfplots@xmin:\pgfplots@xmax], y=[\pgfplots@ymin:\pgfplots@ymax]; z=[\pgfplots@zmin:\pgfplots@zmax].}% \pgfplots@ternary@init@map@to@unit x% \pgfplots@ternary@init@map@to@unit y% \pgfplots@ternary@init@map@to@unit z% }% \def\pgfplots@ternary@init@map@to@unit#1{% \begingroup \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@#1max\endcsname}% \let\pgfplots@loc@TMPa=\pgfmathresult \pgfplotscoordmath{default}{parsenumber}{\csname pgfplots@#1min\endcsname}% \let\pgfplots@map@to@unit@scale@diff=\pgfmathresult \pgfplotscoordmath{default}{op}{subtract}{{\pgfplots@loc@TMPa}{\pgfmathresult}}% \pgfplotscoordmath{default}{op}{reciprocal}{{\pgfmathresult}}% \let\pgfplots@map@to@unit@scale=\pgfmathresult % \expandafter\xdef\csname pgfplots@ternary@map@to@unit@#1\endcsname##1{% \noexpand\pgfplotscoordmath{default}{parsenumber}{##1}% \noexpand\pgfplotscoordmath{default}{op}{subtract}{{\noexpand\pgfmathresult}{\pgfplots@map@to@unit@scale@diff}}% \noexpand\pgfplotscoordmath{default}{op}{multiply}{{\noexpand\pgfmathresult}{\pgfplots@map@to@unit@scale}}% \noexpand\pgfplotscoordmath{default}{tofixed}{\noexpand\pgfmathresult}% }% \endgroup } \def\pgfplots@initsizes@setunitvector@ternary#1#2#3#4{% % ternary axis are DIFFERENT here. % They don't use the (xx,xy), (yx,yy), (zx,zy) vectors, so we can % use them to implement *cartesian* coordinates. % % Thus, any \draw (0,0) inside of a ternary axis will yield % cartesian coordinates. % % The relevant quantities to *draw* the diagram are the three % axis, they are also prepared here. % \def#4{0}% whether we have (#1,0) or (0,#1) \ifcase#2% \pgfsetxvec{% \pgfqpoint{\pgfplots@width@ternary pt}{0pt}% }% \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary001} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary100}% \or \pgfsetyvec{% \pgfqpoint{0pt}{\pgfplots@width@ternary pt}% }% \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary100} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary010}% \or \pgfsetzvec{% \pgfpointorigin }% \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary010} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary001}% \fi \expandafter\xdef\csname pgfplotspoint#1axis\endcsname{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% % %\message{-> got unitvector(#1) = (\the\csname pgf@#1x\endcsname, \the\csname pgf@#1y\endcsname).}% }% \def\pgfplots@computeunitvectorlengths@ternary{% \pgfplots@computeunitvectorlengths@ternary@ x% \pgfplots@computeunitvectorlengths@ternary@ y% \pgfplots@computeunitvectorlengths@ternary@ z% } \def\pgfplots@computeunitvectorlengths@ternary@#1{% \csname pgfplotspoint#1axis\endcsname \pgfmathveclen{\pgf@x}{\pgf@y}% \expandafter\let\csname pgfplots@#1@veclength\endcsname=\pgfmathresult \pgfplotsmath@ifzero{\pgfmathresult}{% \expandafter\def\csname pgfplots@#1@inverseveclength\endcsname{infty}% }{% \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% \expandafter\let\csname pgfplots@#1@inverseveclength\endcsname=\pgfmathresult }% \expandafter\xdef\csname pgfplotspoint#1axislength\endcsname{\pgfplots@x@veclength pt}% % }% \newif\ifpgfplots@ternary@next@is@unitinterval % Deduce z = 1-x-y after transformation to relative coordinates. \def\pgfplotsqpointxy@ternary#1#2{% \pgf@process{% \ifpgfplots@ternary@next@is@unitinterval \dimen1=#1pt \dimen2=#2pt \else \pgfplots@ternary@map@to@unit@x{#1}% \dimen1=\pgfmathresult pt % \pgfplots@ternary@map@to@unit@y{#2}% \dimen2=\pgfmathresult pt \fi \dimen4=\dimen1 \advance\dimen4 by\dimen2 \dimen3=1pt \advance\dimen3 by-\dimen4 % \global\pgfplots@ternary@next@is@unitintervalfalse \pgfplotsqpointxyz@ternary@ }% }% % gx(x,y,z) = 0.5 * (x + 2*z)/(x+y+z) % gy(x,y,z) = (sqrt(3) / 2) * x / (x+y+z) \def\pgfplotsqpointxyz@ternary#1#2#3{% \pgf@process{% \ifpgfplots@ternary@next@is@unitinterval \dimen1=#1pt \dimen2=#2pt \dimen3=#3pt \else \pgfplots@ternary@map@to@unit@x{#1}% \dimen1=\pgfmathresult pt % \pgfplots@ternary@map@to@unit@y{#2}% \dimen2=\pgfmathresult pt % \pgfplots@ternary@map@to@unit@z{#3}% \dimen3=\pgfmathresult pt \fi \global\pgfplots@ternary@next@is@unitintervalfalse % \pgfplotsqpointxyz@ternary@ }% }% \def\pgfplotsqpointxyz@ternary@{% %\dimen1=#1 %\dimen2=#2 %\dimen3=#3 % FIXME . I didn't understand that stuff. \if r\pgfkeysvalueof{/pgfplots/x dir/value}% reversed %\multiply\dimen1 by-1 %\advance\dimen1 by1pt %\dimen1=#2 %\dimen2=#3 %\dimen3=#1 \fi %-------------------------------------------------- % \if r\pgfkeysvalueof{/pgfplots/y dir/value}% reversed % \multiply\dimen2 by-1 % \advance\dimen2 by1pt % \fi % \if r\pgfkeysvalueof{/pgfplots/z dir/value}% reversed % \multiply\dimen3 by-1 % \advance\dimen3 by1pt % \fi %-------------------------------------------------- \pgfplotsqpointxyz@ternary@@% }% \def\pgfplotsqpointxyz@ternary@@{% % Disable renormalization!? %\dimen4=\dimen1 %\advance\dimen4 by\dimen2 %\advance\dimen4 by\dimen3 %\edef\pgfplots@ternary@sum{\pgf@sys@tonumber{\dimen4}}% %\pgfmathapproxequalto@{1}{\pgfplots@ternary@sum}% \pgfmathcomparisontrue \ifpgfmathcomparison \let\pgfplots@ternary@scale=\pgfplots@width@ternary \else \pgfmath@basic@divide@ {\pgfplots@width@ternary}% {\pgfplots@ternary@sum}% \let\pgfplots@ternary@scale=\pgfmathresult \fi % \dimen4=2\dimen3 \advance\dimen4 by \dimen1 \divide\dimen4 by2 \pgf@x=\pgfplots@ternary@scale\dimen4 % \dimen4=\dimen1 \dimen4=0.866025403784\dimen4 % *= sqrt(3)/2 \pgf@y=\pgfplots@ternary@scale\dimen4 % }% \def\pgfplotspoint@initialisation@units@ternary{% \let\pgfplotspointunitx\pgfplotspointxaxis \let\pgfplotspointunity\pgfplotspointyaxis \let\pgfplotsunitxlength=\pgfplots@x@veclength \let\pgfplotsunitylength=\pgfplots@y@veclength \let\pgfplotsunitxinvlength=\pgfplots@x@inverseveclength \let\pgfplotsunityinvlength=\pgfplots@y@inverseveclength \ifpgfplots@threedim \let\pgfplotspointunitz=\pgfplotspointzaxis \let\pgfplotsunitzlength=\pgfplots@z@veclength \let\pgfplotsunitzinvlength=\pgfplots@z@inverseveclength \fi }% % POSTCONDITION: the macros % \pgfplotspointminminmin % \pgfplotspoint[xyz]axis % \pgfplotspoint[xyz]axislength % are defined (globally). \def\pgfplotspoint@initialisation@axes@ternary{% \xdef\pgfplotspointminminmin{\noexpand\pgfpointorigin}% % \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary001} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary100}% \if r\pgfkeysvalueof{/pgfplots/x dir/value}% reverse \pgfqpointscale{-1}{}% \fi \xdef\pgfplotspointxaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% \pgfmathveclen{\pgf@x}{\pgf@y}% \expandafter\let\csname pgfplots@x@veclength\endcsname=\pgfmathresult \pgfplotsmath@ifzero{\pgfmathresult}{% \expandafter\def\csname pgfplots@x@inverseveclength\endcsname{infty}% }{% \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% \expandafter\let\csname pgfplots@x@inverseveclength\endcsname=\pgfmathresult }% \xdef\pgfplotspointxaxislength{\pgfplots@x@veclength pt}% % \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary100} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary010}% \if r\pgfkeysvalueof{/pgfplots/y dir/value}% reverse \pgfqpointscale{-1}{}% \fi \xdef\pgfplotspointyaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% \pgfmathveclen{\pgf@x}{\pgf@y}% \expandafter\let\csname pgfplots@y@veclength\endcsname=\pgfmathresult \pgfplotsmath@ifzero{\pgfmathresult}{% \expandafter\def\csname pgfplots@y@inverseveclength\endcsname{infty}% }{% \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% \expandafter\let\csname pgfplots@y@inverseveclength\endcsname=\pgfmathresult }% \xdef\pgfplotspointyaxislength{\pgfplots@y@veclength pt}% % \pgfpointdiff {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary010} {\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz@ternary001}% \if r\pgfkeysvalueof{/pgfplots/z dir/value}% reverse \pgfqpointscale{-1}{}% \fi \xdef\pgfplotspointzaxis{\noexpand\pgf@x=\the\pgf@x\space\noexpand\pgf@y=\the\pgf@y\space}% \pgfmathveclen{\pgf@x}{\pgf@y}% \expandafter\let\csname pgfplots@z@veclength\endcsname=\pgfmathresult \pgfplotsmath@ifzero{\pgfmathresult}{% \expandafter\def\csname pgfplots@z@inverseveclength\endcsname{infty}% }{% \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% \expandafter\let\csname pgfplots@z@inverseveclength\endcsname=\pgfmathresult }% \xdef\pgfplotspointzaxislength{\pgfplots@z@veclength pt}% % } \def\pgfplots@prepare@ZERO@coordinates@ternary{% \ifpgfplots@xislinear \ifpgfplots@apply@datatrafo@x \pgfplotscoordmath{x}{parsenumber}{0}% \pgfplotscoordmath{x}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@x{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@x}{\pgfplots@xmin}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \pgfplotsmathmin{\pgfplots@logical@ZERO@x}{\pgfplots@xmax}% \global\let\pgfplots@logical@ZERO@x=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@x=\pgfplots@xmin% \fi % \ifpgfplots@yislinear \ifpgfplots@apply@datatrafo@y \pgfplotscoordmath{y}{parsenumber}{0}% \pgfplotscoordmath{y}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@y{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@y}{\pgfplots@ymin}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \pgfplotsmathmin{\pgfplots@logical@ZERO@y}{\pgfplots@ymax}% \global\let\pgfplots@logical@ZERO@y=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@y=\pgfplots@ymin% \fi % \ifpgfplots@threedim \ifpgfplots@zislinear \ifpgfplots@apply@datatrafo@z \pgfplotscoordmath{z}{parsenumber}{0}% \pgfplotscoordmath{z}{datascaletrafo}{\pgfmathresult}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else \gdef\pgfplots@logical@ZERO@z{0}% \fi \pgfplotsmathmax{\pgfplots@logical@ZERO@z}{\pgfplots@zmin}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \pgfplotsmathmin{\pgfplots@logical@ZERO@z}{\pgfplots@zmax}% \global\let\pgfplots@logical@ZERO@z=\pgfmathresult \else \global\let\pgfplots@logical@ZERO@z=\pgfplots@zmin% \fi \fi % % \global\pgfplots@ternary@next@is@unitintervaltrue \pgfplotsqpointxyz100% \xdef\pgfplots@ZERO@x{\the\pgf@x}% \xdef\pgfplots@ZERO@y{\the\pgf@y}% \xdef\pgfplotspointaxisorigin{\noexpand\pgf@x=\pgfplots@ZERO@x\space\noexpand\pgf@y=\pgfplots@ZERO@y\space}% }% \def\pgfplots@draw@axis@ternary{% % % this should become the line for varying y: \pgfplotspointonorientedsurfaceabsetupforsetz{\pgfplots@zmin}{0}% \pgfplots@draw@axis@insurface yxz % % this should become the line for varying z: \pgfplotspointonorientedsurfaceabsetupforsetx{\pgfplots@xmin}{0}% \pgfplots@draw@axis@insurface zyx % % % this should become the line for varying x: \pgfplotspointonorientedsurfaceabsetupforsety{\pgfplots@ymin}{0}% \pgfplots@draw@axis@insurface xzy % \pgfplots@ternary@draw@axislines }% \def\pgfplots@ternary@draw@axislines{% \if r\pgfkeysvalueof{/pgfplots/x dir/value}% reverse \pgfplots@separate@axis@linestrue \fi \if r\pgfkeysvalueof{/pgfplots/y dir/value}% reverse \pgfplots@separate@axis@linestrue \fi \if r\pgfkeysvalueof{/pgfplots/z dir/value}% reverse \pgfplots@separate@axis@linestrue \fi \ifpgfplots@separate@axis@lines \scope[/pgfplots/every outer x axis line, xdiscont,decoration={pre length=\csname xdisstart\endcsname, post length=\csname xdisend\endcsname}] \draw decorate { \pgfextra \if r\pgfkeysvalueof{/pgfplots/x dir/value}% reverse \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \else \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \fi \endpgfextra }; \endscope % \scope[/pgfplots/every outer y axis line, ydiscont,decoration={pre length=\csname ydisstart\endcsname, post length=\csname ydisend\endcsname}] \draw decorate { \pgfextra \if r\pgfkeysvalueof{/pgfplots/y dir/value}% reverse \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \else \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \fi \endpgfextra }; \endscope % \scope[/pgfplots/every outer z axis line, zdiscont,decoration={pre length=\csname zdisstart\endcsname, post length=\csname zdisend\endcsname}] \draw decorate { \pgfextra \if r\pgfkeysvalueof{/pgfplots/z dir/value}% reverse \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \else \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \fi \endpgfextra }; \endscope \else \draw[ /pgfplots/every outer x axis line, % FIXME! these outer styles need much more attention :-( /pgfplots/every outer y axis line] \pgfextra{% \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \pgfpathclose }; \fi }% \def\pgfplots@clippath@prepare@for@axistype@ternary{% \def\pgfplots@clippath@install##1{% \pgfpathmoveto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz001}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz100}% \pgfpathlineto{\global\pgfplots@ternary@next@is@unitintervaltrue\pgfplotsqpointxyz010}% \pgfpathclose \pgfplots@clippath@use@{##1}% }% }% \def\pgfplots@draw@axis@post@ternary{% % do nothing. There is no 3d box to draw here. }% \def\pgfplotspointouternormalvectorofaxis@ternary#1#2#3\relax{% \edef\pgfplots@loc@TMPa{\if r\pgfkeysvalueof{/pgfplots/x dir/value}-\fi}% reverse \edef\pgfplots@loc@TMPb{\if r\pgfkeysvalueof{/pgfplots/y dir/value}-\fi}% reverse \edef\pgfplots@loc@TMPc{\if r\pgfkeysvalueof{/pgfplots/z dir/value}-\fi}% reverse \if v#1% \pgfpointadd {\pgfqpointscale{\pgfplots@loc@TMPb-1}{\pgfplotspointyaxis}}% {\pgfqpointscale{\pgfplots@loc@TMPc}{\pgfplotspointzaxis}}% \else \if v#2% \pgfpointadd {\pgfqpointscale{\pgfplots@loc@TMPa}{\pgfplotspointxaxis}}% {\pgfqpointscale{\pgfplots@loc@TMPc-1}{\pgfplotspointzaxis}}% \else \pgfpointadd {\pgfqpointscale{\pgfplots@loc@TMPa-1}{\pgfplotspointxaxis}}% {\pgfqpointscale{\pgfplots@loc@TMPb}{\pgfplotspointyaxis}}% \fi \fi \pgf@process{\pgfpointnormalised{}}% \endgroup }% \def\pgfplotsclickable@check@enable@axistype@ternaryaxis{% \def\pgfplotsretval{1}% }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % tieline plots % \pgfplotsset{ tieline/.code={% \let\tikz@plot@handler=\pgfplotsplothandlertieline \pgfkeysifdefined{/pgfplots/table/tie end x}{}{% % provide these keys locally: \pgfkeyslet{/pgfplots/table/tie end x}\pgfutil@empty% \pgfkeyslet{/pgfplots/table/tie end y}\pgfutil@empty% \pgfkeyslet{/pgfplots/table/tie end z}\pgfutil@empty% \pgfkeyslet{/pgfplots/table/tie end x index}\pgfutil@empty% \pgfkeyslet{/pgfplots/table/tie end y index}\pgfutil@empty% \pgfkeyslet{/pgfplots/table/tie end z index}\pgfutil@empty% }% \pgfqkeys{/pgfplots/tieline}{#1}% }, tieline/every tieline/.style={}, tieline/tieline style/.style={/pgfplots/tieline/every tieline/.append style={#1}}, tieline/every curve/.style={}, tieline/curve style/.style={/pgfplots/tieline/every curve/.append style={#1}}, tieline/each nth tie/.initial=, } \def\pgfplotsplothandlertieline{% \pgfplotsresetplothandler \let\pgf@plotstreamstart=\pgfplotsplothandlervisbegin@tieline \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@tieline \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@tieline \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@tieline }% \def\pgfplotsplothandlervisbegin@tieline{% \pgfplotsapplistXnewempty\pgfp@binodal@A \pgfplotsapplistXnewempty\pgfp@ties \pgfplotsprependlistXnewempty{pgfp@binodal@B@reverse} \def\b@pgfplotsplothandlersurveystart@tieline@even{1}% % \global\let\pgf@plotstreampoint=\pgfplotsplothandlervis@streampoint@tieline \global\let\pgf@plotstreamend=\pgfplotsplothandlervis@streamend@tieline % \pgfkeysgetvalue{/pgfplots/tieline/each nth tie}\pgfplots@eachnth@tie \ifx\pgfplots@eachnth@tie\pgfutil@empty \def\pgfplots@eachnth@tie{1}% \fi \let\c@pgfplots@tiecounter=\c@pgfplotstable@counta \c@pgfplots@tiecounter=0 }% \def\pgfplotsplothandlervis@streampoint@tieline#1{% \pgf@process{#1}% \edef\pgfplots@loc@TMPa{% \noexpand\pgfplots@stream@withmeta@ {\pgfplots@current@point@coordindex}% {\the\pgf@x}{\the\pgf@y}% {\pgfplots@current@point@meta}% }% \if1\b@pgfplotsplothandlersurveystart@tieline@even \let\pgfplotsplothandlervis@streampoint@tieline@last=\pgfplots@loc@TMPa \expandafter\pgfplotsapplistXpushback\pgfplots@loc@TMPa\to\pgfp@binodal@A \def\b@pgfplotsplothandlersurveystart@tieline@even{0}% \else \expandafter\pgfplotsprependlistXpushfront\pgfplots@loc@TMPa\to{pgfp@binodal@B@reverse}% % \advance\c@pgfplots@tiecounter by1 \ifnum\pgfplots@eachnth@tie=\c@pgfplots@tiecounter \t@pgfplots@toka=\expandafter{\pgfplots@loc@TMPa}% \t@pgfplots@tokb=\expandafter{\pgfplotsplothandlervis@streampoint@tieline@last}% \edef\pgfplots@loc@TMPa{\the\t@pgfplots@toka\the\t@pgfplots@tokb\noexpand\pgfplotsplothandlertieline@finishtie}% \expandafter\pgfplotsapplistXpushback\pgfplots@loc@TMPa\to\pgfp@ties \c@pgfplots@tiecounter=0 \fi % \def\b@pgfplotsplothandlersurveystart@tieline@even{1}% \fi }% \def\pgfplotsplothandlervis@streamend@tieline{% \begingroup \pgfplots@drawmodes@appendtrue \path[/pgfplots/tieline/every curve]% \pgfextra \ifx\tikz@plot@handler\pgfplotsplothandlertieline \let\tikz@plot@handler\pgfplothandlerlineto \fi \pgfplotsresetplothandler \tikz@plot@handler \pgf@plotstreamstart % \pgfplotsapplistXlet\pgfplots@loc@TMPa=\pgfp@binodal@A \pgfplots@loc@TMPa \pgfplotsapplistXnewempty\pgfp@binodal@A \pgfplotsprependlistXlet\pgfplots@loc@TMPa={pgfp@binodal@B@reverse}% \pgfplots@loc@TMPa \pgfplotsprependlistXnewempty{pgfp@binodal@B@reverse}% % \pgf@plotstreamend \endpgfextra; \endgroup % % \pgfplotsset{/pgfplots/tieline/every tieline}% \ifx\tikz@plot@handler\pgfplotsplothandlertieline \let\tikz@plot@handler\pgfplothandlerlineto \fi \pgfplotsresetplothandler \tikz@plot@handler \pgf@plotstreamstart % \def\pgfplotsplothandlertieline@finishtie{% \pgfplotsplothandlervisualizejump }% \pgfplotsapplistXlet\pgfplots@loc@TMPa=\pgfp@ties \pgfplots@loc@TMPa \pgfplotsapplistXnewempty\pgfp@ties % \pgf@plotstreamend }% \def\pgfplotsplothandlersurveystart@tieline{% \def\pgfplots@loc@TMPa{table}% \ifx\pgfplotssurveyphaseinputclass\pgfplots@loc@TMPa \else \pgfplots@error{Sorry, 'tieline' plots are currently only supported for \string\addplot\space table}% \fi \def\b@pgfplotsplothandlersurveystart@tieline@init{0}% }% \def\pgfplotsplothandlersurveyend@tieline{% }% \def\pgfplotsplothandlersurveypoint@tieline@init{% \pgfplotsplothandlersurveypoint@tieline@init@find@tieendcolfor x\pgfplotsplothandlertieline@Bx \pgfplotsplothandlersurveypoint@tieline@init@find@tieendcolfor y\pgfplotsplothandlertieline@By \ifpgfplots@curplot@threedim \pgfplotsplothandlersurveypoint@tieline@init@find@tieendcolfor z\pgfplotsplothandlertieline@Bz \fi % \def\b@pgfplotsplothandlersurveystart@tieline@init{1}% }% \def\pgfplotsplothandlersurveypoint@tieline@init@find@tieendcolfor#1#2{% \let#2=\relax \pgfkeysgetvalue{/pgfplots/table/tie end #1}{\pgfplots@loc@TMPa}% \ifx\pgfplots@loc@TMPa\pgfutil@empty \pgfkeysgetvalue{/pgfplots/table/tie end #1 index}{\pgfplots@loc@TMPa}% \ifx\pgfplots@loc@TMPa\pgfutil@empty \else \edef#2{\noexpand\getthisrowno{\pgfplots@loc@TMPa}\noexpand\pgfmathresult}% \fi \else \edef#2{\noexpand\getthisrow{\pgfplots@loc@TMPa}\noexpand\pgfmathresult}% \fi \ifx#2\relax \pgfplotsplothandlersurveypoint@tieline@init@find@colindex@for #1\pgfplots@loc@ind \c@pgf@countd=\pgfplots@loc@ind\relax \advance\c@pgf@countd by3 \ifnum\c@pgf@countd<\pgfplotstablecols\relax \else \c@pgf@countd=0 \pgfplots@error{Sorry, I can't find the 'tie end #1 index' automatically. Please provide 'table[tie end #1={}]' or 'table[tie end #1 index=]' manually and verify the all, x,y and z components are correct}% \fi \edef\pgfplots@loc@ind{\the\c@pgf@countd}% \pgfkeyslet{/pgfplots/table/tie end #1 index}\pgfplots@loc@ind \edef#2{\noexpand\getthisrowno{\pgfplots@loc@ind}\noexpand\pgfmathresult}% \fi }% \def\pgfplotsplothandlersurveypoint@tieline@init@find@colindex@for#1#2{% \pgfkeysgetvalue{/pgfplots/table/#1}{\pgfplots@loc@TMPa}% \pgfkeysgetvalue{/pgfplots/table/#1 index}{\pgfplots@loc@TMPb}% \ifx\pgfplots@loc@TMPa\pgfutil@empty \let#2=\pgfplots@loc@TMPb \else \def\pgfplots@loc@TMPb{\expandafter\pgfplotstablegetcolumnindexforname\expandafter{\pgfplots@loc@TMPa}\of}% \expandafter\pgfplots@loc@TMPb\pgfplotstablename\to#2% \fi }% \def\pgfplotsplothandlersurveypoint@tieline{% \if0\b@pgfplotsplothandlersurveystart@tieline@init \pgfplotsplothandlersurveypoint@tieline@init \fi \pgfplotsplothandlersurveypoint@default % \pgfplotsplothandlertieline@Bx\let\pgfplots@current@point@x=\pgfmathresult \pgfplotsplothandlertieline@By\let\pgfplots@current@point@y=\pgfmathresult \ifpgfplots@curplot@threedim \pgfplotsplothandlertieline@Bz\let\pgfplots@current@point@z=\pgfmathresult \fi \pgfplotsplothandlersurveypoint@default }% \endinput