%-------------------------------------------- % % Package pgfplots % % Provides a user-friendly interface to create function plots (normal % plots, semi-logplots and double-logplots). % % It is based on Till Tantau's PGF package. % % Copyright 2013 by Christian Feuersaenger % % 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 library adds support for high-level instructions for "fill area % between two arbitrary plots of functions". % % It activates the syntax % % \addplot fill between[of=A and B]; % % where A and B are two plots named by 'name path='. % % In fact, this here is not much more than a low-level invocation of % \pgfpathfillbetween % and a couple of styles. It could become a TikZ library because it % actually works on any two named paths, but it has its restrictions % regarding the supported input paths: both need to be plots of % functions (non-intersecting, should have at most one function value % for each canvas X coord) \pgfutil@IfUndefined{pgfplotsset}{% \pgferror{Please load pgfplots before pgfplots.fillbetween.}% \endinput }{}% \usetikzlibrary{fillbetween} \usepgfplotslibrary{decorations.softclip} % Takes a domain #1:#2 and returns a new domain \pgfplotsretval:\pgfplotsretvalb which is larger. \def\pgfplots@softclip@enlarge#1#2{% \begingroup \pgfplotscoordmath{default}{parse}{0.1*(#2-#1)}\let\pgfplots@diff=\pgfmathresult \pgfplotscoordmath{default}{if is}{\pgfplots@diff}{+}{% % ok, max > min. Should always be the case. \pgfplotscoordmath{default}{parse}{#1-\pgfplots@diff}\let\pgfplots@min=\pgfmathresult \pgfplotscoordmath{default}{parse}{#2+\pgfplots@diff}\let\pgfplots@max=\pgfmathresult }{% \pgfplotscoordmath{default}{if is}{\pgfplots@diff}{0}{% % ok, max == min. Very Strange. \pgfplotscoordmath{default}{parse}{#1-1}\let\pgfplots@min=\pgfmathresult \pgfplotscoordmath{default}{parse}{#2+1}\let\pgfplots@max=\pgfmathresult }{% % ok, max < min. Strange. \pgfplotscoordmath{default}{parse}{#1+\pgfplots@diff}\let\pgfplots@min=\pgfmathresult \pgfplotscoordmath{default}{parse}{#2-\pgfplots@diff}\let\pgfplots@max=\pgfmathresult }% }% \global\let\pgfplots@glob@TMPa=\pgfplots@min \global\let\pgfplots@glob@TMPb=\pgfplots@max \endgroup \let\pgfplotsretval=\pgfplots@glob@TMPa \let\pgfplotsretvalb=\pgfplots@glob@TMPb }% \pgfkeys{ /pgfplots/every fill between plot/.style={/pgfplots/area legend,/tikz/fill,/pgfplots/on layer=pre main}, /tikz/soft clip assign/domain/.code args={#1:#2}{% \pgfplotsifisvisualizationphase{% \ifpgfplots@yislinear \pgfplots@softclip@enlarge {min(\pgfkeysvalueof{/pgfplots/ymin},\pgfplots@data@ymin)}% {max(\pgfkeysvalueof{/pgfplots/ymax},\pgfplots@data@ymax)}% \else \pgfplots@softclip@enlarge{\pgfkeysvalueof{/pgfplots/ymin}}{\pgfkeysvalueof{/pgfplots/ymax}}% \fi \edef\pgfplots@loc@TMPa{% (axis cs:#1,\pgfplotsretval) rectangle (axis cs:#2,\pgfplotsretvalb)}% \pgfkeysalso{/tikz/soft clip assign/path/.expand once=\pgfplots@loc@TMPa}% }{}% },% /tikz/soft clip assign/y domain y/.style={/tikz/soft clip assign/domain y={#1}}, /tikz/soft clip assign/domain y/.code args={#1:#2}{% \pgfplotsifisvisualizationphase{% \ifpgfplots@yislinear \pgfplots@softclip@enlarge {min(\pgfkeysvalueof{/pgfplots/xmin},\pgfplots@data@xmin)}% {max(\pgfkeysvalueof{/pgfplots/xmax},\pgfplots@data@xmax)}% \else \pgfplots@softclip@enlarge{\pgfkeysvalueof{/pgfplots/xmin}}{\pgfkeysvalueof{/pgfplots/xmax}}% \fi \edef\pgfplots@loc@TMPa{% (axis cs:\pgfplotsretval,#1) rectangle (axis cs:\pgfplotsretvalb,#2)}% \pgfkeysalso{/tikz/soft clip assign/path/.expand once=\pgfplots@loc@TMPa}% }{}% },% % /pgfplots/execute at begin axis@@/.add={}{% \gdef\b@pgfplotsfillbetween@list@has@set@layers{0}% }, } % The options are from % \addplot[#1] fill between[#2] #3; % % This method is invoked from the global \addplot dispatching. \def\pgfplotslibraryfillbetween@addplot#1#2#3{% % \pgfplots@start@plot@with@behavioroptions{/pgfplots/every fill between plot,#1}% % % '/tikz/fill between/on layer' is not really integrated into the option processing of pgfplots. % improve it here (to some extend): \pgfkeysgetvalue{/pgfplots/on layer}\pgfplots@loc@TMPa \pgfkeyslet{/tikz/fill between/on layer}{\pgfplots@loc@TMPa}% % % FIXME: is this here an accident!? \pgfkeysvalueof{/pgfplots/execute at end survey}% \pgfplots@remember@survey@option@list % % \pgfplotslibraryfillbetweenpreparecurrentlayer % \pgfplots@addplot@enqueue@coords{% % precmd }{% % empty - this here is a TikZ instruction, not a "real" \addplot command }{% \def\b@pgfplots@fillbetween@clip@on@layer{0}% \pgfkeysgetvalue{/tikz/fill between/on layer}\pgfplots@loc@TMPa \edef\pgfplots@fillbetween@layer{\pgfplots@loc@TMPa}% \ifx\pgfplots@fillbetween@layer\pgfutil@empty \else \ifpgfplots@clip \def\b@pgfplots@fillbetween@clip@on@layer{1}% % This here is messy: we have to clip on the other % layer. I gave up to install this clip path once % per axis, that's why I do it for each individual % fillbetween - let us hope this is not too % inefficient. % % I had to give up because the result appears to % require a pattern of sorts % \onlayer{L} % \scope % \clip ... ; % \endonlayer % ... % % \onlayer{L} % \endscope % \endonlayer % % which is forbidden in TeX -- and using % \pgfsys@beginscope resulted in invalid PDF. % \pgfplotsonlayer{\pgfplots@loc@TMPa}% \scope \pgfplotspathaxisoutline \pgfusepath{clip}% \fi \fi % % the path instruction: \tikzfillbetween[#2]{% /pgfplots/.search also=/tikz,% /pgfplots/.cd,% /tikz/fill between/every last segment/.append style={/tikz/fill between/path after segment={#3}},% #1% }% % \if1\b@pgfplots@fillbetween@clip@on@layer \endscope \endpgfplotsonlayer% \fi }{% % post command. }% } % ONLY TO BE USED AS LATER OPTION! \pgfkeysdef{/pgfplots/fill between/@ensure layers}{% \ifpgfplots@layered@graphics \else \pgfplots@log3{fill between: activating layered graphics}% \pgfplotsset{set layers}% \pgfplots@set@options@of@layered@graphics \fi }% % SIDE-EFFECT: modifies \b@pgfplotsfillbetween@list@has@set@layers and \def\pgfplotslibraryfillbetweenpreparecurrentlayer{% \pgfkeysgetvalue{/tikz/fill between/on layer}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfutil@empty \else \if0\b@pgfplotsfillbetween@list@has@set@layers % \pgfplotssetlateoptions{fill between/@ensure layers}% \gdef\b@pgfplotsfillbetween@list@has@set@layers{1}% \fi \fi } \def\pgfplots@tikzfillbetween{\pgfutil@ifnextchar[{\pgfplots@tikzfillbetween@opt}{\pgfplots@tikzfillbetween@opt[]}} \def\pgfplots@tikzfillbetween@opt[#1]#2{% \pgfplots@addplot@enqueue@coords{% % precmd }{% % empty - this here is a TikZ instruction, not a "real" \addplot command }{% % the path instruction: \tikzfillbetween[#1]{#2}% }{% % post command. }% }% \expandafter\def\expandafter\pgfplots@replace@path@commands\expandafter{\pgfplots@replace@path@commands \let\pgfplots@orig@tikzfillbetween=\tikzfillbetween \let\tikzfillbetween=\pgfplots@tikzfillbetween }% \expandafter\def\expandafter\pgfplots@restore@path@commands\expandafter{\pgfplots@restore@path@commands \let\tikzfillbetween=\pgfplots@orig@tikzfillbetween } \endinput