%-------------------------------------------- % % 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 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 . % %-------------------------------------------- % 1. OVERVIEW % % Plot handlers are extended versions of the plot handlers of PGF with % backwards compatibility. % % To remind ourselfes: PGF plot handlers work like this % \pgfplotstreamstart % \pgfplotstreampoint{...} % \pgfplotstreampoint{...} % \pgfplotstreampoint{...} % \pgfplotstreampoint{...} % \pgfplotstreamend % % and that's it. % % PGFPlots plot handlers also contain these three macros. The tasks % are (of course) the same. In addition, they support a set of further % macros for every plot handler: % % \pgfplotsplothandlersurveystart % \pgfplotsplothandlersurveypoint % \pgfplotsplothandlersurveyend % % and serialization methods % \pgfplotsplothandlerserializepointto % \pgfplotsplothandlerdeserializepointfrom % \pgfplotsplothandlerserializestateto % \pgfplotsplothandlerdeserializepointfrom % % The idea is as follows: % During \addplot, PGFPLots performs a survey phase. Survey means: % nothing will be drawn, only stats will be collected. In this phase, % the \pgfplotsplothandlersurvey* methods will be invoked; followed by % a serialization. % % Then, when every plot has been surveyed, PGFPlots calls % \pgfplotsplothandlerdeserializestatefrom{} % \pgfplotstreamstart % foreach { % \pgfplotsplothandlerdeserializepointfrom{} % apply data transformations % handle plot marks % \pgfplotstreampoint{\pgfplotsqpointxy{}{ % Furthermore, it remembers the <\macro> such that it can be % deserialized later. % Then, the survey phase ends. The main point of interest is the % \pgfplotsplothandlersurveypoint routine, especially its % communication with the axis. It is described below. % % POSTCONDITION: % - the state of the axis is now aware of the new plot (limits, % stacking, ...). % - The plot's survey state is stored using its serialized % representation. % % THE VISUALIZATION PHASE: % FIXME % % 2.1 The API of an axis % % As described above, the coordinate input routine fires a lot of % \pgfplots@coord@stream@coord commands, which, in turn, invoke % \pgfplotsplothandlersurveypoint. Somehow this should update the % axis' state to reflect each point. But the 'data point' is a rather % abstract thing. Usually, it will contain at least (x,y) (or maybe z) % coordinates. But it may be more complex. % % So, the coordinate input routine provides whatever the user has % chosen. Let's assume, we are using \addplot table. Then, we can % access every cell in the current row (using \thisrow{} for % example). The plot handler knows how to extract its information from % this state. In general, the following steps are taken: % - the plot handler assembles coordinates. % - every assembled coordinate should be reported to the axis by % defining \pgfplots@current@point@[xyz] to its coordinates and % calling % \pgfplotsaxisparsecoordinate{} % This will apply coordinate filters, parse the single coordinates % and apply high level transformations and any logarithms. % It is some sort of advanced coordinate parser which works only for % (x,y) or for (x,y,z). % It yields (x,y,z). But the axis might need to change its % components! Thus, you also need to call % \pgfplotsaxispreparecoordinate{}. % This will, for example, apply the "stack plots" feature or the % 'data cs' feature. % % If necessary, the plot handler calls % \pgfplotsaxisparsecoordinate{} and % \pgfplotsaxispreparecoordinate{} multiple times, once for each % encountered coordinate. % % It might occasionally be too much to call % \pgfplotsaxispreparecoordinate. % % It might happen that a coordinate filter discards a coordinate. % This is returned in the \ifpgfplotsaxisparsecoordinateok boolean % and has to be checked by the plot handler. % % - the plot handler knows which of the coordinates contribute to the % final plot. It invokes % \ifpgfplotsaxisparsecoordinateok % \pgfplotsaxisupdatelimitsforcoordinate{}{}{} % \fi % for each of these coordinates. This has to be done for final % coordinates only, i.e. after \pgfplotsaxispreparecoordinate. % % - eventually, the plot handler is satisfied and considers a data % point as "readily surveyed". It is allowed if this does *not* % happen inside of \pgfplotsplothandlersurveypoint, but it must % happen before \pgfplotsplothandlersurveyend is finished. % % The plot handler invokes \pgfplotsaxisdatapointsurveyed. % This tells the axis that it can perform its own surveying tasks % (see below) and furthermore, that it can serialize the data point. % Consequently, it will invoke % \pgfplotsplothandlerserializepointto{<\macro>} % and it will remember that \macro internally. This serialization is % employed to place plot marks and to apply z buffering techniques % (that's why it is done by the axis and not by the plot handler on % its own). % % The axis does its own surveying task, initiated by % \pgfplotsaxisdatapointsurveyed (which is, turn, invoked by the % plot handler). This command handles the |point meta| feature, that % is: it queries the |point meta| input source and updates the meta % limits. Furthermore, the error bar feature is processed at this % point (using the final data point's (x,y,z) coordinates as basis). % The |xtick=data| feature is also prepared at this stage. % % - Later, the coordinate input routine invokes % \pgfplots@coord@stream@end indicating the end-of-input. This will % finalize the survey phase. % % A simple example looks like this: % \pgfplotsplothandlersurveystart: does nothing in the simple example. % \pgfplotsplothandlersurveypoint: % parses the input format somehow to get (x,y,z) in raw, symbolic format % calls \pgfplotsaxisparsecoordinate % calls \pgfplotsaxispreparecoordinate % calls \ifpgfplotsaxisparsecoordinateok \pgfplotsaxisupdatelimitsforcoordinate{}{}{} % which allows to change the current plot style from within API % functions. It sets and remembers them for the % visualization phase. % % \pgfplotsaxisupdatelimitsforpointmeta{}, % provided there is a point meta input handler (which is numeric). % Otherwise, the command is equal to \relax. % % % 3. Details about the VISUALIZATION phase % % The visualization phase consists of % % \pgfplotstreamstart % foreach serialized coordinate { % pgfplots calls \pgfplotsplothandlerdeserializestatefrom{} % if coordinate is empty ("unbounded") % pgfplots call \pgfplotsplothandlervisualizejump % else % pgfplots calls \pgfplotsaxisvisphasetransformcoordinate % pgfplots calls \pgfplotsaxisvisphasepreparedatapoint % fi % \pgfplotstreampoint % } % \pgfplotstreamend % % User defined plot handlers might need to invoke % \pgfplotsaxisvisphasetransformcoordinate on their own. % % During the visualization phase, the following macros can be used: % % - \pgfplotsaxisvisphasetransformpointmeta to set up point meta. % Use this only if there *is* point meta, see % \pgfplotsaxisifhaspointmeta{}{}. % % 4. API Functions of pgfplots to work with the visualization phases % % \pgfplotsifissurveyphase{}{} % \pgfplotsifisvisualizationphase{}{} % % \pgfplotsaxisfilteredcoordsaway % This macro expands to '1' if all points have been surveyed % successfully. It expands to '0' if at least one point has been % filtered away (for whatever reasons). This does not apply to % jumps. % \pgfplotsaxisplothasjumps % This macro expands to '1' if the current plot has jumps and '0' % if not.During the visualization phase, a jump is usually indicated % by an empty coordinate. % \def\pgfplotssurveyphaseinputclass{direct} % Resets the plot handler routines. % % This is necessary before installing a new plot handler! \def\pgfplotsresetplothandler{% \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@default \let\pgfplotsplothandlername=\pgfplotsplothandlername@default \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@default \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@default \let\pgfplotsplothandlerserializepointto=\pgfplotsplothandlerserializepointto@default \let\pgfplotsplothandlerdeserializepointfrom=\pgfplotsplothandlerdeserializepointfrom@default \let\pgfplotsplothandlerserializestateto=\pgfplotsplothandlerserializestateto@default \let\pgfplotsplothandlerdeserializestatefrom=\pgfplotsplothandlerdeserializestatefrom@default \let\pgfplotsplothandlervisualizejump=\pgfplotsplothandlervisualizejump@default \let\pgfplotsplothandlernotifyscanlinecomplete=\relax }% % \pgfplotsplothandlersurveystart \def\pgfplotsplothandlersurveystart@default{}% % \pgfplotsplothandlername \def\pgfplotsplothandlername@default{% [tikz@plot@handler: \meaning\pgf@plotstreamstart]% }% % \pgfplotsplothandlersurveyend % Called at the end of each survey phase. \def\pgfplotsplothandlersurveyend@default{} \let\pgfplotsplothandlernotifyscanlinecomplete=\relax% % \pgfplotsplothandlersurveypoint is called for each encountered data % point. % % The data point as such is available using the current state of any % macros which are assigned during the survey phase (during \addplot). % This includes any table macros etc. % PGFPlots stores the x,y and z coordinates into \pgfplots@current@point@[xyz]. % The point meta coordinate is in \pgfplots@current@point@meta. % % Note that since any currently assigned macro can be used here, the % new DV engine of PGF is also valid (and will be supported % eventually). This DV engine stores data point entries in keys, % namely those in the key path /data point. See the pgf manual. \def\pgfplotsplothandlersurveypoint@default{% \pgfplotsaxisparsecoordinate \pgfplotsaxispreparecoordinate \ifpgfplotsaxisparsecoordinateok \pgfplotsaxisupdatelimitsforcoordinate\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@z \fi \pgfplotsaxisdatapointsurveyed }% % \pgfplotsplothandlerserializepointto{<\macro>} % should save a complete data point to <\macro> such that it can be % de-serialized later. % % #1: a macro name. Will be filled with (expandable) data. % The format can be arbitrary, but you should be able to extra it. % % @PRECONDITION % this macro will be invoked in a context where the current data % point has been processed completely, including any preparations. % The required data which should be saved depends on the plot % handler. Usually, all plot handlers require % \pgfplots@current@point@[xyz] and \pgfplots@current@point@meta. % This macro should only assign keys which have been defined or % validated by any of the plot handler relevant methods (including % the de-serialization or survey methods). \def\pgfplotsplothandlerserializepointto@default#1{% % 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). \edef#1{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z}% }% % the counterpart for \pgfplotsplothandlerserializepointto. % It should restore the state as it was before the serialization. % % #1: the serialized information. \def\pgfplotsplothandlerdeserializepointfrom@default#1{% \expandafter\pgfplotsplothandlerdeserializepointfrom@default@#1\relax }% \def\pgfplotsplothandlerdeserializepointfrom@default@#1,#2,#3\relax{% \def\pgfplots@current@point@x{#1}% \def\pgfplots@current@point@y{#2}% \def\pgfplots@current@point@z{#3}% }% % \pgfplotsplothandlerserializestateto{<\macro>} % should save the state of the current plot handler such that it can % be de-serialized later. % % The state does usually NOT contain a coordinate stream, this is % accomplished by \pgfplotsplothandlerserializepointto. % % #1: a macro name. Can be filled with anything, including % non-expandable macro invocations. \def\pgfplotsplothandlerserializestateto@default#1{% \def#1{}% }% % \def\pgfplotsplothandlerdeserializestatefrom@default#1{% #1% }% \def\pgfplotsplothandlervisualizejump@default{% \pgfplotstreamend \pgfplotstreamstart }% \pgfplotsresetplothandler % ================================== % Defines % - a generic update limits routine, % \pgfplotsaxisupdatelimitsforcoordinate#1#2#3 % if #3 is empty, it will assume a 2d point, otherwise a 3d point % and the axis will be three dimensional as well. % During \addplot, this auto-detection will be disabled in favor of % the '\addplot3' versus' \addplot' syntax. % \def\pgfplots@prepare@axis@API{% \pgfplots@curplot@threedimtrue \pgfplots@prepare@axis@API@ \let\pgfplotsaxisupdatelimitsforcoordinatethreedim=\pgfplotsaxisupdatelimitsforcoordinate@ \let\pgfplotsaxisparsecoordinatethreedim=\pgfplotsaxisparsecoordinate@ % \pgfplots@curplot@threedimfalse \pgfplots@prepare@axis@API@ \let\pgfplotsaxisupdatelimitsforcoordinatetwodim=\pgfplotsaxisupdatelimitsforcoordinate@ \let\pgfplotsaxisparsecoordinatetwodim=\pgfplotsaxisparsecoordinate@ % \def\pgfplotsaxisupdatelimitsforcoordinate##1##2##3{% \pgfplots@ifempty{##3}{% \pgfplotsaxisupdatelimitsforcoordinatetwodim{##1}{##2}{}% }{% \global\pgfplots@threedimtrue \pgfplotsaxisupdatelimitsforcoordinatethreedim{##1}{##2}{##3}% }% }% \def\pgfplotsaxisparsecoordinate{% \ifx\pgfplots@current@point@z\pgfutil@empty \pgfplotsaxisparsecoordinatetwodim \else \global\pgfplots@threedimtrue \pgfplotsaxisparsecoordinatethreedim% \fi }% }% \def\pgfplots@prepare@axis@API@{% \begingroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \let\E=\noexpand % Setup Just-In-Time-Macro Compilation: % I compile a set of macros which is highly optimized for this % particular axis configuration. % % \pgfplotsaxisupdatelimitsforcoordinate % 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 are given in floating point format (FIXME) % % 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: % #1,#2,#3 the x,y and z coordinate. z is ignored for 2d plots. \xdef\pgfplotsaxisupdatelimitsforcoordinate@##1##2##3{% %\E\tracingmacros=2\E\tracingcommands=2 %\E\pgfplots@message{Updating limits for (##1,##2) ...}% % % 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@{##1}{\E\pgfplots@xmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{##1}{\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}{##1}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@xmax}{##1}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \fi \fi \ifpgfplots@autocompute@ymin \else \ifpgfplots@yislinear \E\pgfmathfloatlessthan@{##2}{\E\pgfplots@ymin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{##2}{\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}{##2}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@ymax}{##2}% \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@{##3}{\E\pgfplots@zmin}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{##3}{\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}{##3}% \E\ifpgfmathfloatcomparison \E\pgfplots@update@limits@for@one@point@ISCLIPPEDtrue \E\fi \else \E\pgfplotsmathlessthan{\E\pgfplots@zmax}{##3}% \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}{##1}% \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@xmin}{##1}% \E\global\E\let\E\pgfplots@xmin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@xmax \ifpgfplots@xislinear \E\pgfplotsmathfloatmax{\E\pgfplots@xmax}{##1}% \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@xmax}{##1}% \E\global\E\let\E\pgfplots@xmax=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@ymin \ifpgfplots@yislinear \E\pgfplotsmathfloatmin{\E\pgfplots@ymin}{##2}% \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@ymin}{##2}% \E\global\E\let\E\pgfplots@ymin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@ymax \ifpgfplots@yislinear \E\pgfplotsmathfloatmax{\E\pgfplots@ymax}{##2}% \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@ymax}{##2}% \E\global\E\let\E\pgfplots@ymax=\E\pgfmathresult \fi \fi \ifpgfplots@curplot@threedim \ifpgfplots@autocompute@zmin \ifpgfplots@zislinear \E\pgfplotsmathfloatmin{\E\pgfplots@zmin}{##3}% \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult \else \E\pgfplotsmathmin{\E\pgfplots@zmin}{##3}% \E\global\E\let\E\pgfplots@zmin=\E\pgfmathresult \fi \fi \ifpgfplots@autocompute@zmax \ifpgfplots@zislinear \E\pgfplotsmathfloatmax{\E\pgfplots@zmax}{##3}% \E\global\E\let\E\pgfplots@zmax=\E\pgfmathresult \else \E\pgfplotsmathmax{\E\pgfplots@zmax}{##3}% \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}{##1}% \E\global\E\let\E\pgfplots@data@xmin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@xmax}{##1}% \E\global\E\let\E\pgfplots@data@xmax=\E\pgfmathresult \fi \ifpgfplots@yislinear \E\pgfplotsmathfloatmin{\E\pgfplots@data@ymin}{##2}% \E\global\E\let\E\pgfplots@data@ymin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@ymax}{##2}% \E\global\E\let\E\pgfplots@data@ymax=\E\pgfmathresult \fi \ifpgfplots@curplot@threedim \ifpgfplots@zislinear \E\pgfplotsmathfloatmin{\E\pgfplots@data@zmin}{##3}% \E\global\E\let\E\pgfplots@data@zmin=\E\pgfmathresult \E\pgfplotsmathfloatmax{\E\pgfplots@data@zmax}{##3}% \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 }% % % A routine which parses a coordinate. % Here, 'coordinate' means (x,y) for a two dimensional plot and % '(x,y,z)' for a three dimensional one. % % The preparation consists of % - filtering. % - coordinate parsing and high level transformations. % - logs. % % It might happen that \pgfplotsaxisparsecoordinate is called % multiple times for a single data "point" (for example, a quiver % point might call it for the point where the vector starts and % where the vector ends). % % @PRECONDITION % - the plot's survey phase is running (has already been started) % - \pgfplots@current@point@[xyz] contains the coordinates of the % point. I assume they are unparsed. % % % @POSTCONDITION % - the axis' state will be updated. % - the \pgfplots@current@point@[xyz] macros will contain parsed data. % - \ifpgfplotsaxisparsecoordinateok will be true if and only % if the data point has not been filtered away. If it has been % filtered away, \pgfplots@current@point@[xyz] will be empty. % - \pgfplots@current@point@[xyz]@unfiltered contain unparsed % data. % % @see \pgfplotsaxispreparecoordinate % @see \pgfplotsaxisdatapointsurveyed \xdef\pgfplotsaxisparsecoordinate@{% % 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@invoke@prefilter % \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 % \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty \E\else \ifpgfplots@xislinear \E\pgfplotscoordmath{x}{parsenumber}{\E\pgfplots@current@point@x}% \E\let\E\pgfplots@current@point@x=\E\pgfmathresult \else % logs are already parsed (in prepare routine) \fi \E\pgfplotscoordmath{x}{if is bounded}{\E\pgfplots@current@point@x}% {}% {% 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\fi % \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty \E\else \ifpgfplots@yislinear \E\pgfplotscoordmath{y}{parsenumber}{\E\pgfplots@current@point@y}% \E\let\E\pgfplots@current@point@y=\E\pgfmathresult \else % logs are already parsed (in prepare routine) \fi \E\pgfplotscoordmath{y}{if is bounded}{\E\pgfplots@current@point@y}% {}% {% this clears nan, inf and -inf points. \E\let\E\pgfplots@current@point@y=\E\pgfutil@empty \E\def\E\pgfplots@unbounded@dir{y}% }% \E\fi % \ifpgfplots@curplot@threedim % \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty \E\else \ifpgfplots@zislinear \E\pgfplotscoordmath{z}{parsenumber}{\E\pgfplots@current@point@z}% \E\let\E\pgfplots@current@point@z=\E\pgfmathresult \else % logs are already parsed (in prepare routine) \fi \E\pgfplotscoordmath{z}{if is bounded}{\E\pgfplots@current@point@z}% {}% {% this clears nan, inf and -inf points. \E\let\E\pgfplots@current@point@z=\E\pgfutil@empty \E\def\E\pgfplots@unbounded@dir{z}% }% \E\fi \fi % % check if coordinates are bounded: \E\pgfplotsaxisparsecoordinateoktrue \E\ifx\E\pgfplots@current@point@x\E\pgfutil@empty \E\pgfplotsaxisparsecoordinateokfalse \E\else \E\ifx\E\pgfplots@current@point@y\E\pgfutil@empty \E\pgfplotsaxisparsecoordinateokfalse \E\else \ifpgfplots@curplot@threedim \E\ifx\E\pgfplots@current@point@z\E\pgfutil@empty \E\pgfplotsaxisparsecoordinateokfalse \E\fi \fi \E\fi \E\fi % }% % \endgroup }% % ================================== % The quiver plot handler. % It draws a lot of arrows. % Its input is (x_i,y_i); (u_i,v_i) for data point i and it draws a % vector in direction (u_i,v_i) starting from (x_i,y_i) . % It also supports 3D arrows (involving z_i and w_i). \newif\ifpgfplots@quiver@usetikz \newif\ifpgfplots@quiver@updatelimits \pgfplotsset{ % The 'quiver' plot handler for two- and three dimensional plots. % % User Interface: % use /pgfplots/quiver to enable the plot handler. % Then, provide `quiver/u value' or `quiver/u' to % tell where to find the 'x' coordinates of the vectors, and similarly % for 'v' and 'w' instead of 'u'. quiver/.code={% \let\tikz@plot@handler=\pgfplotsplothandlerquiver \pgfqkeys{/pgfplots/quiver}{#1}% },% quiver/u value*/.initial=0, quiver/v value*/.initial=0, quiver/w value*/.initial=0, quiver/u value is expr/.initial=0, quiver/v value is expr/.initial=0, quiver/w value is expr/.initial=0, quiver/u filter/.code=, quiver/v filter/.code=, quiver/w filter/.code=, quiver/u value/.code =\pgfplots@set@source@for{quiver/u}{#1}{0},% quiver/u/.code =\pgfplots@set@source@for{quiver/u}{#1}{1},% quiver/v value/.code =\pgfplots@set@source@for{quiver/v}{#1}{0},% quiver/v/.code =\pgfplots@set@source@for{quiver/v}{#1}{1},% quiver/w value/.code =\pgfplots@set@source@for{quiver/w}{#1}{0},% quiver/w/.code =\pgfplots@set@source@for{quiver/w}{#1}{1},% quiver/before arrow/.code=, quiver/after arrow/.code=, quiver/every arrow/.style={}, quiver/arrow color/.initial=, quiver/scale arrows/.initial=1, quiver/update limits/.is if=pgfplots@quiver@updatelimits, quiver/update limits=true, quiver/colored/.code={% \def\pgfplots@loc@TMPa{#1}% \ifx\pgfplots@loc@TMPa\pgfutil@empty \else \pgfkeyslet{/pgfplots/quiver/arrow color}\pgfplots@loc@TMPa \pgfkeysalso{/pgfplots/set point meta if empty=f(x)}% \fi },% quiver/colored/.default=mapped color, }% \def\pgfplots@set@source@for#1#2#3{% \pgfkeyssetvalue{/pgfplots/#1 value*}{#2}% \pgfkeyssetvalue{/pgfplots/#1 is expr}{#3}% }% % To be used to create a simple parser for keys initialised by % \pgfplots@set@source@for: % % #1: the key path (relative to /pgfplots/) of the data. % Can be empty in which case /pgfplots/#2 is used to access data. % #2: the key name of the data % #3: a macro name which be will defined to be a parser for the data. % % The parser will check whether the '#2 is expr' key is set. % Furthermore, it defines /data point/#2 to be the result. % % Example: % \pgfplots@set@source@for{hist/data}{...} % % -> % \pgfplots@prepare@source@parser@for{hist/}{data}\parser % % then, invoking \parser % will define \pgfmathresult to be the argument provided to % \pgfplots@set@source@for. \def\pgfplots@prepare@source@parser@for#1#2#3{% \pgfkeyslet{/data point/#1#2}\pgfutil@empty% % \pgfkeysgetvalue{/pgfplots/#1#2 value*}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfutil@empty % assume the '/data point/#1#2' is set by some input % routine. % Invoke math parser in this case. \pgfkeyssetvalue{/pgfplots/#1#2 is expr}{1}% \else \pgfkeyslet{/data point/#1#2}\pgfplots@loc@TMPa \fi \def#3{% \edef\pgfmathresult{\pgfkeysvalueof{/data point/#1#2}} %\message{parse coordinate #1#2 (\pgfmathresult) ...^^J}% }% % % \pgfkeysifdefined{/pgfplots/#1#2 coord trafo/.@cmd}{% \pgfkeysgetvalue{/pgfplots/#1#2 coord trafo/.@cmd}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key \else \t@pgfplots@toka=\expandafter{#3}% \t@pgfplots@tokb={% \def\pgfplots@loc@TMPa{\pgfkeysvalueof{/pgfplots/#1#2 coord trafo/.@cmd}}% \expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}\pgfeov% }% \t@pgfplots@tokc={% \ifx\pgfmathresult\pgfutil@empty \else \pgfmathfloatparsenumber{\pgfmathresult}% \fi }% \edef#3{% \the\t@pgfplots@toka \the\t@pgfplots@tokb \the\t@pgfplots@tokc }% \fi }{}% % \t@pgfplots@toka=\expandafter{#3}% \if1\pgfkeysvalueof{/pgfplots/#1#2 is expr}% \t@pgfplots@tokc={% \ifx\pgfmathresult\pgfutil@empty \else \pgfmathparse{\pgfmathresult}% \fi }% \else \t@pgfplots@tokc={% \ifx\pgfmathresult\pgfutil@empty \else \pgfmathfloatparsenumber{\pgfmathresult}% \fi }% \fi \edef#3{% \the\t@pgfplots@toka \the\t@pgfplots@tokc }% % \pgfkeysgetvalue{/pgfplots/#1#2 filter/.@cmd}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key \else \t@pgfplots@toka=\expandafter{#3}% \t@pgfplots@tokb={% \def\pgfplots@loc@TMPa{\pgfkeysvalueof{/pgfplots/#1#2 filter/.@cmd}}% \expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}\pgfeov% }% \t@pgfplots@tokc={% \ifx\pgfmathresult\pgfutil@empty \else \pgfmathfloatparsenumber{\pgfmathresult}% \fi }% \edef#3{% \the\t@pgfplots@toka \the\t@pgfplots@tokb \the\t@pgfplots@tokc }% \fi % \iftrue \t@pgfplots@toka=\expandafter{#3}% \t@pgfplots@tokc={% %\message{parse coordinate (#1#2) = \pgfmathresult.^^J}% }% \edef#3{% \the\t@pgfplots@toka \the\t@pgfplots@tokc }% \fi }% % Invokes /pgfplots/#1 coord inv trafo on \pgfmathresult if that key % exists. % #1 the argument is in float (will become the 'default' coordmath % eventually). % % On output, it should either '#1' if there was no coord inv trafo or % the result of the trafo. \def\pgfplots@coord@trafo@inv@for#1{% \def\pgfplots@loc@TMPb{/pgfplots/#1 coord inv trafo/.@cmd}% \pgfkeysifdefined{\pgfplots@loc@TMPb}{% \pgfkeysgetvalue{\pgfplots@loc@TMPb}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key \else \pgfmathfloattofixed{\pgfmathresult}% \expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}\pgfeov \fi }{}% } % Like \pgfplots@coord@trafo@inv@for, but for the normal trafo % direction \def\pgfplots@coord@trafo@for#1{% \def\pgfplots@loc@TMPb{/pgfplots/#1 coord trafo/.@cmd}% \pgfkeysifdefined{\pgfplots@loc@TMPb}{% \pgfkeysgetvalue{\pgfplots@loc@TMPb}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfplots@empty@command@key \else \expandafter\pgfplots@loc@TMPa\expandafter{\pgfmathresult}\pgfeov \fi }{}% } \def\pgfplotsplothandlerquiver{% \pgfplotsresetplothandler \let\pgf@plotstreamstart=\pgfplotsplothandlervisbegin@quiver \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@quiver \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@quiver \let\pgfplotsplothandlerserializepointto=\pgfplotsplothandlerserializepointto@quiver \let\pgfplotsplothandlerdeserializepointfrom=\pgfplotsplothandlerdeserializepointfrom@quiver \let\pgfplotsplothandlerquiver@vis@hook=\pgfutil@empty % \ifpgfplots@xislinear \else \pgfplotsplothandlerquivererror \fi \ifpgfplots@yislinear \else \pgfplotsplothandlerquivererror\fi \pgfplotsifcurplotthreedim{% \ifpgfplots@zislinear \else \pgfplotsplothandlerquivererror \fi }{}% }% \def\pgfplotsplothandlerquivererror{\pgfplots@error{Sorry, quiver plots for logarithmic axes are not yet implemented. In fact, the implementation does something -- but it will probably change in future releases. Contact the mailing list if you have questions}}% \def\pgfplotsplothandlersurveystart@quiver{% \pgfkeysgetvalue{/pgfplots/quiver/scale arrows}\pgfplots@quiver@scale \ifx\pgfplots@quiver@scale\pgfutil@empty \else \def\pgfplots@loc@TMPa{1}% \ifx\pgfplots@loc@TMPa\pgfplots@quiver@scale \let\pgfplots@quiver@scale=\pgfutil@empty \else \pgfmathparse{\pgfplots@quiver@scale}% \pgfmathfloatparsenumber\pgfplots@quiver@scale \let\pgfplots@quiver@scale=\pgfmathresult \fi \fi % \pgfplots@prepare@source@parser@for@quiver u\pgfplots@quiver@prepare@u% \pgfplots@prepare@source@parser@for@quiver v\pgfplots@quiver@prepare@v% \pgfplots@prepare@source@parser@for@quiver w\pgfplots@quiver@prepare@w% }% \def\pgfplots@prepare@source@parser@for@quiver#1#2{% \pgfplots@prepare@source@parser@for{quiver/}{#1}{#2}% \t@pgfplots@toka=\expandafter{#2}% \t@pgfplots@tokb=\expandafter{\csname pgfplots@quiver@#1\endcsname}% \edef#2{% \the\t@pgfplots@toka \noexpand\let\the\t@pgfplots@tokb=\noexpand\pgfmathresult \ifx\pgfplots@quiver@scale\pgfutil@empty \else \noexpand\pgfmathfloatmultiply@{\pgfplots@quiver@scale}{\the\t@pgfplots@tokb}% \noexpand\let\the\t@pgfplots@tokb=\noexpand\pgfmathresult \fi }% }% \def\pgfplotsplothandlersurveypoint@quiver{% \pgfplots@quiver@prepare@u \pgfplots@quiver@prepare@v \pgfplotsifcurplotthreedim{% \pgfplots@quiver@prepare@w }{% \let\pgfplots@quiver@w=\pgfutil@empty }% \pgfplotsaxisparsecoordinate \pgfplotsaxispreparecoordinate \ifpgfplotsaxisparsecoordinateok \pgfplotsaxisupdatelimitsforcoordinate\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@z % \pgfmathadd@{\pgfplots@quiver@u}{\pgfplots@current@point@x}% \let\pgfplots@quiver@u=\pgfmathresult \pgfmathadd@{\pgfplots@quiver@v}{\pgfplots@current@point@y}% \let\pgfplots@quiver@v=\pgfmathresult \pgfplotsifcurplotthreedim{% \pgfmathadd@{\pgfplots@quiver@w}{\pgfplots@current@point@z}% \let\pgfplots@quiver@w=\pgfmathresult }{}% \ifpgfplots@quiver@updatelimits \pgfplotsaxisupdatelimitsforcoordinate\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w \fi \fi \pgfplotsaxisdatapointsurveyed }% \def\pgfplotsplothandlerserializepointto@quiver#1{% \edef#1{\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z>\pgfplots@quiver@u,\pgfplots@quiver@v,\pgfplots@quiver@w}% }% \def\pgfplotsplothandlerdeserializepointfrom@quiver#1{% \expandafter\pgfplotsplothandlerdeserializepointfrom@quiver@#1\relax }% \def\pgfplotsplothandlerdeserializepointfrom@quiver@#1,#2,#3>#4,#5,#6\relax{% \def\pgfplots@current@point@x{#1}% \def\pgfplots@current@point@y{#2}% \def\pgfplots@current@point@z{#3}% \def\pgfplots@quiver@u{#4}% \def\pgfplots@quiver@v{#5}% \def\pgfplots@quiver@w{#6}% }% \def\pgfplotsplothandlervisbegin@quiver{% \def\pgfplots@quiver@has@handled@point@meta{0}% \pgfkeysgetvalue{/pgfplots/quiver/arrow color}\pgfplots@quiver@color \ifx\pgfplots@quiver@color\pgfutil@empty \else % prepare the color data and define 'mapped color': \def\pgfplots@quiver@has@handled@point@meta{1}% \expandafter\def\expandafter\pgfplotsplothandlerquiver@vis@hook\expandafter{% \pgfplotsplothandlerquiver@vis@hook \pgfplotsaxisvisphasetransformpointmeta \pgfplotscolormapdefinemappedcolor{\pgfplotspointmetatransformed}% }% % SEE BELOW AS WELL FOR HOW TO ENABLE THE COLOR. \fi % % \pgfkeysgetvalue{/pgfplots/quiver/every arrow/.@cmd}\pgfplots@quiver@everyarrow \ifx\pgfplots@quiver@everyarrow\pgfplots@empty@style@key % use PGF basic level methods to set the 'arrow color': \ifx\pgfplots@quiver@color\pgfutil@empty \else \expandafter\def\expandafter\pgfplotsplothandlerquiver@vis@hook\expandafter{% \pgfplotsplothandlerquiver@vis@hook \pgfsetstrokecolor{\pgfkeysvalueof{/pgfplots/quiver/arrow color}}% % for arrow heads: \pgfsetfillcolor{\pgfkeysvalueof{/pgfplots/quiver/arrow color}}% }% \fi \else % 'every arrow' should provide a high level user interface. % Use tikz instead of pgf. This is slower, but more powerfull. \pgfplots@quiver@usetikztrue \pgfplotsaxisifhaspointmeta{% % ASSERT(mapped color is available) \if0\pgfplots@quiver@has@handled@point@meta% % -> define mapped color \expandafter\def\expandafter\pgfplotsplothandlerquiver@vis@hook\expandafter{% \pgfplotsplothandlerquiver@vis@hook \pgfplotsaxisvisphasetransformpointmeta \pgfplotscolormapdefinemappedcolor{\pgfplotspointmetatransformed}% }% \def\pgfplots@quiver@has@handled@point@meta{1}% \fi }{}% % use tikz methods to set the 'arrow color': \ifx\pgfplots@quiver@color\pgfutil@empty \else \t@pgfplots@toka=\expandafter{\pgfplots@quiver@color}% \edef\pgfplots@loc@TMPa{\noexpand\pgfkeysalso{/pgfplots/quiver/every arrow/.prefix style={\the\t@pgfplots@toka}}}% \pgfplots@loc@TMPa \fi \fi % \global\let\pgf@plotstreampoint=\pgfplotsplothandlerquiver@vis% \global\let\pgf@plotstreamspecial=\pgfutil@gobble% \global\let\pgf@plotstreamend=\relax }% \def\pgfplotsplothandlerquiver@vis#1{% \pgfkeysvalueof{/pgfplots/quiver/before arrow/.@cmd}\pgfeov \pgfplotsplothandlerquiver@vis@hook \ifpgfplots@quiver@usetikz \draw[/pgfplots/quiver/every arrow] \pgfextra{\pgfplotsplothandlerquiver@vis@path{#1}}; \else \pgfplotsplothandlerquiver@vis@path{#1}% \pgfusepath{stroke}% \fi \pgfkeysvalueof{/pgfplots/quiver/after arrow/.@cmd}\pgfeov }% \def\pgfplotsplothandlerquiver@vis@path#1{% \pgfpathmoveto{#1}% \pgfplotsaxisvisphasetransformcoordinate\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w \pgfpathlineto{% \pgfplotsifcurplotthreedim{% \pgfplotsqpointxyz\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w }{% \pgfplotsqpointxy\pgfplots@quiver@u\pgfplots@quiver@v }% }% }% \newif\ifpgfplotsplothandlerhistogram@intervals \newif\ifpgfplotsplothandlerhistogram@cumulative \pgfplotsset{ hist/.code={% \let\tikz@plot@handler=\pgfplotsplothandlerhistogram \pgfqkeys{/pgfplots/hist}{#1}% }, hist/data value/.code =\pgfplots@set@source@for{hist/data}{#1}{0},% hist/data/.code =\pgfplots@set@source@for{hist/data}{#1}{1},% hist/data filter/.code=, hist/data value=\pgfkeysvalueof{/data point/y}, % hist/data=y, hist/data min/.initial=\pgfkeysvalueof{/pgfplots/xmin}, hist/data max/.initial=\pgfkeysvalueof{/pgfplots/xmax}, hist/bins/.initial=10, hist/intervals/.is if=pgfplotsplothandlerhistogram@intervals, hist/intervals/.default=true, hist/intervals=true, hist/cumulative/.is if=pgfplotsplothandlerhistogram@cumulative, hist/cumulative/.default=true, hist/handler/.style={/tikz/ybar interval}, hist/symbolic coords/.style={% /pgfplots/symbolic coords={hist/data}{A,B,C,D,E,F,G,H,I,J}, /pgfplots/symbolic coords={x}{A,B,C,D,E,F,G,H,I,J}, },% }% \def\pgfplotsplothandlerhistogram{% \pgfplotsresetplothandler \def\pgf@plotstreamstart{% \pgfplotsset{/pgfplots/hist/handler}% \pgfplotsresetplothandler \tikz@plot@handler \pgf@plotstreamstart }% \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@hist \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@hist \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@hist }% \def\pgfplotsplothandlersurveystart@hist{% \pgfplots@prepare@source@parser@for{hist/}{data}{\pgfplotsplothandlerhistogram@parse}% % \pgfkeysgetvalue{/pgfplots/hist/data min}\pgfmathresult \edef\pgfmathresult{\pgfmathresult}% \ifx\pgfmathresult\pgfutil@empty\else \pgfplots@coord@trafo@for{hist/data}% \fi \edef\pgfplotsplothandlerhistogram@datamin{\pgfmathresult}% % \pgfkeysgetvalue{/pgfplots/hist/data max}\pgfmathresult \edef\pgfmathresult{\pgfmathresult}% \ifx\pgfmathresult\pgfutil@empty\else \pgfplots@coord@trafo@for{hist/data}% \fi \edef\pgfplotsplothandlerhistogram@datamax{\pgfmathresult}% % \ifx\pgfplotsplothandlerhistogram@datamin\pgfutil@empty \pgfmathfloatcreate{1}{1.0}{2147483645}% \let\pgfplotsplothandlerhistogram@datamin=\pgfmathresult \def\pgfplotsplothandlerhistogram@datamin@autocompute{1}% \else \pgfmathfloatparsenumber{\pgfplotsplothandlerhistogram@datamin}% \let\pgfplotsplothandlerhistogram@datamin=\pgfmathresult \def\pgfplotsplothandlerhistogram@datamin@autocompute{0}% \fi \ifx\pgfplotsplothandlerhistogram@datamax\pgfutil@empty \pgfmathfloatcreate{2}{1.0}{2147483645}% \let\pgfplotsplothandlerhistogram@datamax=\pgfmathresult \def\pgfplotsplothandlerhistogram@datamax@autocompute{1}% \else \pgfmathfloatparsenumber{\pgfplotsplothandlerhistogram@datamax}% \let\pgfplotsplothandlerhistogram@datamax=\pgfmathresult \def\pgfplotsplothandlerhistogram@datamax@autocompute{0}% \fi % \edef\pgfplotsplothandlerhistogram@Nfixed{\pgfkeysvalueof{/pgfplots/hist/bins}}% \c@pgf@counta=\pgfplotsplothandlerhistogram@Nfixed\relax \advance\c@pgf@counta by-1 \edef\pgfplotsplothandlerhistogram@Nmax{\the\c@pgf@counta}% % \pgfmathfloatparsenumber{\pgfplotsplothandlerhistogram@Nfixed}% \let\pgfplotsplothandlerhistogram@N=\pgfmathresult % \pgfplotsapplistXnewempty\pgfp@hist@@ \def\c@pgfplotsplothandlerhistogram@num{0}% \c@pgfplots@coordindex=0 }% \def\pgfplotsplothandlersurveypoint@hist@limits{% \if1\pgfplotsplothandlerhistogram@datamin@autocompute \pgfplotsmathfloatmin{\pgfplots@current@point@data}{\pgfplotsplothandlerhistogram@datamin}% \let\pgfplotsplothandlerhistogram@datamin=\pgfmathresult \fi % \if1\pgfplotsplothandlerhistogram@datamax@autocompute \pgfplotsmathfloatmax{\pgfplots@current@point@data}{\pgfplotsplothandlerhistogram@datamax}% \let\pgfplotsplothandlerhistogram@datamax=\pgfmathresult \fi }% \def\pgfplotsplothandlersurveypoint@hist{% % Note that at this point, the coordinate filtering does NOT % apply. Perhaps it should... \pgfplotsplothandlerhistogram@parse \let\pgfplots@current@point@data=\pgfmathresult % \ifx\pgfplots@current@point@data\pgfutil@empty \else \pgfmathfloatiffinite\pgfplots@current@point@data{% \pgfplotsplothandlersurveypoint@hist@limits % \pgfplotsutil@advancestringcounter\c@pgfplotsplothandlerhistogram@num % % store parsed result. \edef\pgfmathresult{{\pgfplots@current@point@data}}% \expandafter\pgfplotsapplistXpushback\expandafter{\pgfmathresult}\to\pgfp@hist@@ }{% }% \fi \advance\c@pgfplots@coordindex by1 }% \def\pgfplotsplothandlersurveyend@hist{% \ifnum\c@pgfplotsplothandlerhistogram@num>0 \expandafter\pgfplotsplothandlersurveyend@hist@ \fi }% \def\pgfplotsplothandlersurveyend@hist@{% \pgfmathfloatsubtract@{\pgfplotsplothandlerhistogram@datamax}{\pgfplotsplothandlerhistogram@datamin}% \let\pgfplotsplothandlerhistogram@range=\pgfmathresult \pgfmathfloatdivide@{\pgfplotsplothandlerhistogram@range}{\pgfplotsplothandlerhistogram@N}% \let\pgfplotsplothandlerhistogram@h=\pgfmathresult \pgfmathfloatreciprocal@{\pgfplotsplothandlerhistogram@h}% \let\pgfplotsplothandlerhistogram@invh=\pgfmathresult % \pgfplotsarraynewempty{pgfp@hist}% \pgfplotsarrayresize{pgfp@hist}{\pgfplotsplothandlerhistogram@Nfixed}% \pgfplotsarrayforeachungrouped{pgfp@hist}\as\pgfplots@hist@count{% \pgfplotsarrayset{\pgfplotsarrayforeachindex}\of{pgfp@hist}\to{0}% }% % \pgfplotsapplistXlet\pgfplots@hist@data=\pgfp@hist@@ \pgfplotsapplistXnewempty\pgfp@hist@@ \expandafter\pgfplotsplothandlersurveyend@hist@loop\pgfplots@hist@data\pgfplots@EOI \let\pgfplots@hist@data=\relax % \ifpgfplotsplothandlerhistogram@cumulative \c@pgf@counta=0 \pgfplotsarrayforeachungrouped{pgfp@hist}\as\pgfplots@hist@count{% \advance\c@pgf@counta by\pgfplots@hist@count\relax \def\pgfplots@loc@TMPa{\pgfplotsarrayset{\pgfplotsarrayforeachindex}\of{pgfp@hist}\to}% \expandafter\pgfplots@loc@TMPa\expandafter{\the\c@pgf@counta}% }% \fi % \pgfplots@curplot@threedimfalse % \pgfplotsset{/pgfplots/hist/handler}% \pgfplotsresetplothandler \tikz@plot@handler % \pgfplotsplothandlersurveystart % \let\pgfplots@current@point@z=\pgfutil@empty \pgfplotsarrayforeachungrouped{pgfp@hist}\as\pgfplots@hist@count{% \pgfplotsplothandlerhistgetintervalstartfor\pgfplotsarrayforeachindex \pgfplotsplothandlerhist@invtrafo \let\pgfplots@current@point@x\pgfmathresult% \let\pgfplots@current@point@y\pgfplots@hist@count% %\message{Survey point (\pgfplots@current@point@x,\pgfplots@current@point@y)^^J}% \pgfplotsplothandlersurveypoint }% \ifpgfplotsplothandlerhistogram@intervals % replicate last count. \let\pgfmathresult\pgfplotsplothandlerhistogram@datamax% \pgfplotsplothandlerhist@invtrafo \let\pgfplots@current@point@x\pgfmathresult% \let\pgfplots@current@point@y\pgfplots@hist@count% %\message{Survey point (\pgfplots@current@point@x,\pgfplots@current@point@y)^^J}% \pgfplotsplothandlersurveypoint \fi % \pgfplotsplothandlersurveyend } \def\pgfplotsplothandlerhist@invtrafo{% % This here might be inefficient, because % there needs to be a compatible "x coord trafo" as well -- and % that transformation will (most likely) do the very same thing as % the hist/data coord trafo. % % But I did not find a way to combine the transformations % automatically without resorting to hackery. % % And: the performance impact might (hopefully) be small... \pgfplots@coord@trafo@inv@for{hist/data}% }% \def\pgfplotsplothandlersurveyend@hist@loop#1{% \def\pgfplots@loc@TMPa{#1}% \ifx\pgfplots@loc@TMPa\pgfplots@EOI \else \pgfplotsplothandlerhistgetbinfor@{#1}% \expandafter\pgfplotsplothandlerhistadvancebin\expandafter{\pgfmathresult}% % \expandafter\pgfplotsplothandlersurveyend@hist@loop \fi }% \def\pgfplotsplothandlerhistadvancebin#1{% \pgfplotsarrayselect{#1}\of{pgfp@hist}\to\pgfplots@loc@TMPa% \pgfplotsutil@advancestringcounter\pgfplots@loc@TMPa \pgfplotsarrayletentry{#1}\of{pgfp@hist}=\pgfplots@loc@TMPa }% \def\pgfplotsplothandlerhistgetintervalstartfor#1{% \pgfmathfloatparsenumber{#1}% \expandafter\pgfplotsplothandlerhistgetintervalstartfor@\expandafter{\pgfmathresult}% }% \def\pgfplotsplothandlerhistgetintervalstartfor@#1{% \pgfmathfloatmultiply@{\pgfplotsplothandlerhistogram@h}{#1}% \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfplotsplothandlerhistogram@datamin}% }% \def\pgfplotsplothandlerhistgetbinfor#1{% \pgfmathfloatparsenumber{#1}% \expandafter\pgfplotsplothandlerhistgetbinfor@\expandafter{\pgfmathresult}% }% \def\pgfplotsplothandlerhistsettol#1{% \begingroup \pgfmathfloatparsenumber{#1}% \global\let\pgfplotsplothandlerhisttol@parsed=\pgfmathresult \endgroup }% \pgfplotsplothandlerhistsettol{1e-4}% \def\pgfplotsplothandlerhistgetbinfor@#1{% \pgfmathfloatsubtract@{#1}{\pgfplotsplothandlerhistogram@datamin}% \expandafter\pgfmathfloatmultiply@\expandafter{\pgfmathresult}{\pgfplotsplothandlerhistogram@invh}% \expandafter\pgfmathfloatadd@\expandafter{\pgfmathresult}{\pgfplotsplothandlerhisttol@parsed}% \pgfmathfloattofixed{\pgfmathresult}% \afterassignment\pgfplots@gobble@until@relax \c@pgf@counta=\pgfmathresult\relax \ifnum\pgfplotsplothandlerhistogram@Nfixed>\c@pgf@counta \ifnum\c@pgf@counta<0 \def\pgfmathresult{0}% \else \def\pgfmathresult{\the\c@pgf@counta}% \fi \else \let\pgfmathresult=\pgfplotsplothandlerhistogram@Nmax \fi }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % % Contour plots % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 \newif\ifpgfplotsplothandlercontour@labels \newif\ifpgfplotsplothandlercontour@filled \pgfplotsset{ contour prepared/.code={% \let\tikz@plot@handler=\pgfplotsplothandlercontourprepared \pgfqkeys{/pgfplots/contour}{% #1,% }% }, contour prepared filled/.style={% /pgfplots/contour prepared={draw color=mapped color!80!black,labels=false,filled=true}, }, % FIXME : should use \tikz@plot@handler instead of just the % visualization thing! contour/handler/.style={/tikz/sharp plot}, contour prepared format/.is choice, contour prepared format/standard/.code= {\def\pgfplotsplothandlercontourprepared@format{s}}, contour prepared format/matlab/.code= {\def\pgfplotsplothandlercontourprepared@format{m}}, contour prepared format/standard, contour/draw color/.initial=mapped color, contour/fill color/.initial=mapped color, contour/label distance/.initial=70pt, contour/label node code/.code={% \node {\pgfmathprintnumber{#1}}; },% contour/labels/.is if=pgfplotsplothandlercontour@labels, contour/labels=true, contour/filled/.is if=pgfplotsplothandlercontour@filled, contour/filled/.default=true, contour/data limits/.initial=,% FIXME EXPERIMENTAL contour/every contour label/.style={% sloped,% transform shape,% inner sep=2pt, font=\scriptsize, every node/.style={mapped color!50!black,fill=white},% /pgf/number format/relative={\pgfplotspointmetarangeexponent},% %every node/.style={yshift=10pt},% }, contour/labels over line/.style={ /pgfplots/contour/every contour label/.append style={% every node/.append style={% fill=none, anchor=base, yshift=1pt, }, }, }, contour/contour label style/.style={ /pgfplots/contour/every contour label/.append style={#1}}, % % % Styles to actually *compute* the contour. % These are mostly placeholders here: As long as the % algorithm is not ready, we have to resort to external tools. % % Shared parameters: contour/number/.initial=5, % % % Interface to external tools: contour external/.code={% \edef\tikz@plot@handler{\noexpand\pgfplotsplothandlercontourexternal}% \pgfqkeys{/pgfplots/contour external}{#1}% }, contour external/scanline marks/.is choice, contour external/scanline marks/false/.code={\def\pgfplotsplothandlercontourexternal@scanlinemode{0}}, contour external/scanline marks/if in input/.code={\def\pgfplotsplothandlercontourexternal@scanlinemode{1}}, contour external/scanline marks/required/.code={\def\pgfplotsplothandlercontourexternal@scanlinemode{2}}, contour external/scanline marks/true/.code={\def\pgfplotsplothandlercontourexternal@scanlinemode{2}}, contour external/scanline marks/if in input, contour external/file/.initial=,% auto-generate contour external/script extension/.initial=script, contour external/script/.initial=,% not yet initialised contour external/cmd/.initial=,% not yet initialised contour external/.search also=/pgfplots/contour, contour gnuplot/.style={ contour external={% scanline marks=required, script={unset surface; set cntrparam levels \pgfkeysvalueof{/pgfplots/contour/number}; set contour; set table \"\outfile\"; splot \"\infile\";}, cmd={gnuplot \"\script\"}, #1,% }, }, }% \def\pgfplotsplothandlercontourprepared{% \pgfplotsresetplothandler \pgfplotsset{empty line=jump}% \let\pgf@plotstreamstart=\pgfplotsplothandlervisstart@contour \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@contour \if m\pgfplotsplothandlercontourprepared@format \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@contourmatlabformat \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@contourmatlabformat \pgfplotsaxisifhaspointmeta{}{% \pgfplotsset{/pgfplots/point meta=explicit}% }% \fi \pgfplotsplothandlercontour@prepare@point@meta }% \def\pgfplotsplothandlercontour@prepare@point@meta{% \ifpgfplots@curplot@threedim \pgfplotsset{/pgfplots/set point meta if empty=z}% \else \pgfplotsaxisifhaspointmeta{}{% \pgfkeysgetvalue{/pgfplots/table/meta index}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfutil@empty % FIXME : this here is reasonable, but it should be sanity checked! \pgfkeyssetvalue{/pgfplots/table/meta index}{2}% \fi \pgfplotsset{/pgfplots/set point meta if empty=explicit}% }% %\pgfplots@error{Sorry, 'contour external' requires \string\addplot3 (or a non-empty `point meta' used as label data)}% \fi \def\pgfplotsplothandlercontour@empty@pointmeta@error@@{0}% }% \def\pgfplotsplothandlercontour@empty@pointmeta@error{% \if0\pgfplotsplothandlercontour@empty@pointmeta@error@@ \def\pgfplotsplothandlercontour@empty@pointmeta@error@@{1}% \def\pgfplots@current@point@meta{0}% \pgfplotsthrow{invalid argument}{\pgfplots@current@point@meta}{Sorry, contour plots require non--empty `point meta'. Please use '\string\addplot3[contour ...] together with 'view={0}{90}' or provide a valid 'point meta=' (for example `=z'?)}\pgfeov% \fi }% \def\pgfplotsplothandlersurveystart@contourmatlabformat{% \def\c@pgfplotsplothandlercontourprepared@matlabformat@cur{0}% \def\c@pgfplotsplothandlercontourprepared@matlabformat@count{0}% } \def\pgfplotsplothandlersurveypoint@contourmatlabformat{% \ifnum\c@pgfplotsplothandlercontourprepared@matlabformat@cur=\c@pgfplotsplothandlercontourprepared@matlabformat@count\relax \pgfmathfloatparsenumber{\pgfplots@current@point@y}% \pgfmathfloattoint\pgfmathresult \let\c@pgfplotsplothandlercontourprepared@matlabformat@count=\pgfmathresult \def\c@pgfplotsplothandlercontourprepared@matlabformat@cur{0}% % \pgfmathfloatparsenumber{\pgfplots@current@point@x}% \let\pgfplotsplothandlercontourprepared@matlabformat@meta=\pgfmathresult % \else \let\pgfplots@current@point@z=\pgfplotsplothandlercontourprepared@matlabformat@meta \let\pgfplots@current@point@meta=\pgfplotsplothandlercontourprepared@matlabformat@meta \pgfplotsplothandlersurveypoint@default \pgfplotsutil@advancestringcounter\c@pgfplotsplothandlercontourprepared@matlabformat@cur \fi }% \def\pgfplotsplothandlersurveyend@contour{% \pgfplotsplothandlercontour@init@limits \ifx\pgfplotsplothandlercontour@limits@low@meta\pgfutil@empty \else \pgfplotsaxisupdatelimitsforpointmeta\pgfplotsplothandlercontour@limits@low@meta \fi }% \def\pgfplotsplothandlervisstart@contour{% % \ifpgfplotsplothandlercontour@labels \pgfkeysgetvalue{/pgfplots/contour/label distance}\pgfplotsplothandlercontour@labeldist \pgfmathparse{\pgfplotsplothandlercontour@labeldist}% \edef\pgfplotsplothandlercontour@labeldist{\pgfmathresult pt}% % \pgfplotsapplistXnewempty\pgfplotsplothandlercontour@storedlabels \let\pgfplotsplothandlercontour@handlesplinesegment=\pgfplotsplothandlercontour@handlesplinesegment@forlabels \else \def\pgfplotsplothandlercontour@handlesplinesegment##1##2##3{}% \fi % \ifpgfplotsplothandlercontour@filled \pgfseteorule \pgfplotsapplistXnewempty\pgfplotsplothandlercontour@stored@lastcontourpath \pgfplotsplothandlercontour@init@limits \fi % \pgfplotsresetplothandler \pgfplotsset{/pgfplots/contour/handler}% \tikz@plot@handler % \def\pgfplotsplothandlercontour@haspendingjump{0}% \let\pgfplotsplothandlervisualizejump=\pgfplotsplothandlercontour@jump % \let\pgfplotsplothandlercontour@handler@start=\pgf@plotstreamstart \let\pgfplotsplothandlercontour@lastcontour=\pgfutil@empty \global\let\pgf@plotstreampoint=\pgfplotsplothandlercontour@streampoint \global\let\pgf@plotstreamend=\pgfplotsplothandlercontour@streamend }% \def\pgfplotsplothandlercontour@jump{% \def\pgfplotsplothandlercontour@haspendingjump{1}% }% \def\pgfplotsplothandlercontour@streamend{% \ifx\pgfplotsplothandlercontour@lastcontour\pgfutil@empty \else % \def\pgfplotsplothandlercontour@haspendingjump{0}% important! (this is a different case than a jump) \pgfplotsplothandlercontour@finishcontourline % \ifpgfplotsplothandlercontour@filled \if0\pgfplotsplothandlercontour@processed@outer \pgfplotsplothandlercontour@stream@bbcontour \pgfplotsplothandlercontour@finishcontourline \fi \fi % \ifpgfplotsplothandlercontour@labels \scope[/pgfplots/contour/every contour label] \let\pgfplots@restore@drawmodes=\relax% FIXME : necessary? \pgfplotsapplistXlet\pgfplotsplothandlercontour@storedlabels@=\pgfplotsplothandlercontour@storedlabels \pgfplotsapplistXnewempty\pgfplotsplothandlercontour@storedlabels \expandafter\pgfplotsplothandlercontourplacelabels\pgfplotsplothandlercontour@storedlabels@\pgfplots@EOI \endscope \fi \fi }% \def\pgfplotsplothandlercontour@check@bbcontour{% \ifpgfplotsplothandlercontour@filled \if0\pgfplotsplothandlercontour@processed@outer \pgfplotscoordmath{meta}{if less than} {\pgfplotsplothandlercontour@act@contour} {\pgfplotsplothandlercontour@limits@low@meta} {% % TRUE! \pgfplotsplothandlercontour@stream@bbcontour@inbetween }{}% \fi \fi }% \def\pgfplotsplothandlercontour@stream@bbcontour@inbetween{% \def\pgfplotsplothandlercontour@processed@outer{1}% }% \def\pgfplotsplothandlercontour@stream@bbcontour{% %\message{contour: processing OUTER data limit contour...}% \def\pgfplotsplothandlercontour@haspendingjump{0}% important % % forbid labels: \let\pgfplotsplothandlercontour@stream@bbcontour@oldlabelsetting=\pgfplotsplothandlercontour@handlesplinesegment \def\pgfplotsplothandlercontour@handlesplinesegment##1##2##3{}% % \let\pgfplots@current@point@meta=\pgfplotsplothandlercontour@limits@low@meta \pgfplotsplothandlercontour@streampoint{% \pgfplotsplothandlerpointxyz \pgfplotsplothandlercontour@limits@low@x \pgfplotsplothandlercontour@limits@low@y \pgfplotsplothandlercontour@limits@low@z }% \pgfplotsplothandlercontour@streampoint{% \pgfplotsplothandlerpointxyz \pgfplotsplothandlercontour@limits@high@x \pgfplotsplothandlercontour@limits@low@y \pgfplotsplothandlercontour@limits@low@z }% \pgfplotsplothandlercontour@streampoint{% \pgfplotsplothandlerpointxyz \pgfplotsplothandlercontour@limits@high@x \pgfplotsplothandlercontour@limits@high@y \pgfplotsplothandlercontour@limits@low@z }% \pgfplotsplothandlercontour@streampoint{% \pgfplotsplothandlerpointxyz \pgfplotsplothandlercontour@limits@low@x \pgfplotsplothandlercontour@limits@high@y \pgfplotsplothandlercontour@limits@low@z }% \pgfplotsplothandlercontour@streampoint{% \pgfplotsplothandlerpointxyz \pgfplotsplothandlercontour@limits@low@x \pgfplotsplothandlercontour@limits@low@y \pgfplotsplothandlercontour@limits@low@z }% \def\pgfplotsplothandlercontour@processed@outer{1}% % % restore labels: \let\pgfplotsplothandlercontour@handlesplinesegment=\pgfplotsplothandlercontour@stream@bbcontour@oldlabelsetting }% \def\pgfplotsplothandlercontourplacelabels#1{% \def\pgfplots@loc@TMPa{#1}% \ifx\pgfplots@loc@TMPa\pgfplots@EOI \else % \pgfplotsplothandlercontourplacelabels@act#1\relax % \expandafter\pgfplotsplothandlercontourplacelabels \fi }% \def\pgfplotsplothandlercontourplacelabels@act#1,#2;#3,#4;#5\relax{% \begingroup \def\pgfplots@current@point@meta{#5}% \pgfplotsaxisvisphasetransformpointmeta \pgfplotscolormapdefinemappedcolor{\pgfplotspointmetatransformed}% % \pgftransformlineattime{0.5}{\pgfqpoint{#1}{#2}}{\pgfqpoint{#3}{#4}}% \pgfkeysvalueof{/pgfplots/contour/label node code/.@cmd}#5\pgfeov \endgroup }% \def\pgfplotsplothandlercontour@streampoint#1{% \pgf@process{#1}% % remember point: \edef\pgfplotsplothandlercontour@act@canvas{\pgf@x=\the\pgf@x\space\pgf@y=\the\pgf@y\space}% % \let\pgfplotsplothandlercontour@act@contour=\pgfplots@current@point@meta \ifx\pgfplotsplothandlercontour@act@contour\pgfutil@empty % oh. No Z data!? That should not happen! \pgfplotsplothandlercontour@empty@pointmeta@error \fi \ifx\pgfplotsplothandlercontour@lastcontour\pgfutil@empty % oh. its the very first point. \def\pgfplotsplothandlercontour@haspendingjump{0}% important! (this is a different case than a jump) \pgfplotsplothandlercontour@preparenewcontourline \else \ifx\pgfplotsplothandlercontour@lastcontour\pgfplotsplothandlercontour@act@contour % belongs to the same contour. \if1\pgfplotsplothandlercontour@haspendingjump \pgfplotsplothandlercontour@finishcontourline \pgfplotsplothandlercontour@preparenewcontourline \fi \else % oh, a new contour line. \def\pgfplotsplothandlercontour@haspendingjump{0}% important! (this is a different case than a jump) \pgfplotsplothandlercontour@finishcontourline \pgfplotsplothandlercontour@check@bbcontour \pgfplotsplothandlercontour@preparenewcontourline \fi \fi % % % handle difference vector for label placement: \ifx\pgfplotsplothandlercontour@lastcanvas\pgfutil@empty \else \pgfplotsplothandlercontour@handlesplinesegment {\pgfplotsplothandlercontour@lastcanvas} {\pgfplotsplothandlercontour@act@canvas}% {\pgfplotsplothandlercontour@act@contour}% \fi % \pgfplotsplothandlercontour@handler@streampoint{\pgfplotsplothandlercontour@act@canvas}% \let\pgfplotsplothandlercontour@lastlastcanvas=\pgfplotsplothandlercontour@lastcanvas \let\pgfplotsplothandlercontour@lastcanvas=\pgfplotsplothandlercontour@act@canvas \let\pgfplotsplothandlercontour@lastcontour=\pgfplotsplothandlercontour@act@contour % \ifpgfplotsplothandlercontour@filled \t@pgfplots@toka=\expandafter{\expandafter{\pgfplotsplothandlercontour@act@canvas}}% \expandafter\pgfplotsapplistXpushback\expandafter\pgf@plotstreampoint\the\t@pgfplots@toka \to\pgfplotsplothandlercontour@stored@lastcontourpath \fi % \ifx\pgf@plotstreampoint\pgfplotsplothandlercontour@streampoint \else \let\pgfplotsplothandlercontour@handler@streampoint=\pgf@plotstreampoint \fi \global\let\pgf@plotstreampoint=\pgfplotsplothandlercontour@streampoint \global\let\pgf@plotstreamend=\pgfplotsplothandlercontour@streamend % ATTENTION : if the low level plot handler introduces extra % levels of scopes, this *will* fail! }% % % #1 : source % #2 : target % #3 : contour value \def\pgfplotsplothandlercontour@handlesplinesegment@forlabels#1#2#3{% #2% \pgf@xb=\pgf@x \pgf@yb=\pgf@y #1% \pgf@xc=\pgf@x \pgf@yc=\pgf@y \pgfpointdiff {\pgf@x=\pgf@xc \pgf@y=\pgf@yc} {\pgf@x=\pgf@xb \pgf@y=\pgf@yb}% \edef\pgfplots@loc@TMPa{{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}}% \expandafter\pgfmath@basic@veclen@\pgfplots@loc@TMPa \pgf@xa=\pgfmathresult pt % \advance\pgf@xa by\pgfplotsplothandlercontour@len\relax \edef\pgfplotsplothandlercontour@len{\the\pgf@xa}% %\message{contour(\pgfplotsplothandlercontour@act@contour): cur len=\pgfplotsplothandlercontour@len > \pgfplotsplothandlercontour@labeldist ? [segment from #1--#2];}% \ifdim\pgf@xa>\pgfplotsplothandlercontour@labeldist\relax \def\pgfplotsplothandlercontour@haslabel{1}% \edef\pgfplots@loc@TMPa{{\the\pgf@xc,\the\pgf@yc;\the\pgf@xb,\the\pgf@yb;{#3}}}% \expandafter\pgfplotsapplistXpushback\expandafter{\pgfplots@loc@TMPa}\to\pgfplotsplothandlercontour@storedlabels \advance\pgf@xa by-\pgfplotsplothandlercontour@labeldist\relax \edef\pgfplotsplothandlercontour@len{\the\pgf@xa\relax}% \fi }% \def\pgfplotsplothandlercontour@preparenewcontourline{% \if0\pgfplotsplothandlercontour@haspendingjump %\message{PREPARE NEW CONTOUR LEVEL (\pgfplots@current@point@meta).}% % a completely new level has been % started, not due to jumps inside of one level. % % thus, we need to compute 'mapped color': \pgfplotsaxisvisphasetransformpointmeta \pgfplotscolormapdefinemappedcolor{\pgfplotspointmetatransformed}% \pgfsetstrokecolor{\pgfkeysvalueof{/pgfplots/contour/draw color}}% \ifpgfplotsplothandlercontour@filled \pgfsetfillcolor{\pgfkeysvalueof{/pgfplots/contour/fill color}}% \fi % % furthermore, we need to handle the 'filled' style: \ifpgfplotsplothandlercontour@filled \pgfplotsapplistXlet\pgfplotsplothandlercontour@stored@lastcontourpath@=\pgfplotsplothandlercontour@stored@lastcontourpath % flush: \pgfplotsapplistXnewempty\pgfplotsplothandlercontour@stored@lastcontourpath % % process it: \ifx\pgfplotsplothandlercontour@stored@lastcontourpath@\pgfutil@empty % oh. This here is the very first contour. Nothing to do! \else % ok. This here is the i'th contour level, i>0. % Thus, we have the 'i-1'th contour stored. % REPLICATE its path to fill the space between the (i-1)'th contour and the i'th one! \let\pgf@plotstreamstart=\pgfplotsplothandlercontour@handler@start \pgf@plotstreamstart \pgfplotsplothandlercontour@stored@lastcontourpath@ \pgf@plotstreamend \fi \fi \else %\message{PREPARE NEW CONTOUR for the already begun level \pgfplots@current@point@meta.}% \ifpgfplotsplothandlercontour@filled \pgfplotsapplistXpushback\pgf@plotstreamstart\to\pgfplotsplothandlercontour@stored@lastcontourpath \fi \fi % \let\pgfplotsplothandlercontour@lastcanvas=\pgfutil@empty \let\pgfplotsplothandlercontour@lastlastcanvas=\pgfutil@empty \ifpgfplotsplothandlercontour@labels \def\pgfplotsplothandlercontour@haslabel{0}% % % this here means that 20% of labeldist are already there. % it moves the first label nearer to its start. \pgf@xa=\pgfplotsplothandlercontour@labeldist\relax \pgf@xa=0.2\pgf@xa \edef\pgfplotsplothandlercontour@len{\the\pgf@xa}% \fi \def\pgfplotsplothandlercontour@haspendingjump{0}% % \pgfplotsplothandlercontour@handler@start \let\pgfplotsplothandlercontour@handler@end=\pgf@plotstreamend \let\pgfplotsplothandlercontour@handler@streampoint=\pgf@plotstreampoint }% \def\pgfplotsplothandlercontour@finishcontourline{% \ifpgfplotsplothandlercontour@labels \if0\pgfplotsplothandlercontour@haslabel \ifx\pgfplotsplothandlercontour@lastlastcanvas\pgfutil@empty \else % force a label: %\message{FORCING A LABEL for contour \pgfplotsplothandlercontour@lastcontour\space from (\pgfplotsplothandlercontour@lastlastcanvas --\pgfplotsplothandlercontour@lastcanvas)}% \edef\pgfplotsplothandlercontour@len{\pgfplotsplothandlercontour@labeldist}% \pgfplotsplothandlercontour@handlesplinesegment {\pgfplotsplothandlercontour@lastlastcanvas} {\pgfplotsplothandlercontour@lastcanvas}% {\pgfplotsplothandlercontour@lastcontour}% \fi \fi \fi \pgfplotsplothandlercontour@handler@end % % \ifpgfplotsplothandlercontour@filled % \pgfpathclose % FIXME this is, in general, not good enough. % \fi \if0\pgfplotsplothandlercontour@haspendingjump %\message{usepath{} to finalize level \pgfplotsplothandlercontour@lastcontour.}% % flush paths if the complete contour level is ready. % do *not* flush paths if we have just a new part of the % existing contour level. % % This makes a difference for the filled contour. \ifpgfplotsplothandlercontour@filled \pgfusepath{fill,stroke}% \else \pgfusepath{stroke}% \fi \else %\message{usepath{} for level \pgfplotsplothandlercontour@lastcontour.}% \ifpgfplotsplothandlercontour@filled \pgfplotsapplistXpushback\pgf@plotstreamend\to\pgfplotsplothandlercontour@stored@lastcontourpath \fi \fi }% \def\pgfplotsplothandlercontour@init@limits{% \def\pgfplotsplothandlercontour@processed@outer{0}% \let\pgfplotsplothandlercontour@limits@low@meta=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@low@x=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@low@y=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@low@z=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@high@meta=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@high@x=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@high@y=\pgfutil@empty \let\pgfplotsplothandlercontour@limits@high@z=\pgfutil@empty % \pgfkeysgetvalue{/pgfplots/contour/data limits}\pgfplots@loc@TMPa \ifx\pgfplots@loc@TMPa\pgfutil@empty \def\pgfplotsplothandlercontour@processed@outer{1}% \else \expandafter\pgfplotsplothandlercontour@init@limits@getboundingboxlow\pgfplots@loc@TMPa\pgfplots@EOI \fi %\message{contour: I processed data limits to MIN = (\pgfplotsplothandlercontour@limits@low@x,\pgfplotsplothandlercontour@limits@low@y,\pgfplotsplothandlercontour@limits@low@z;\pgfplotsplothandlercontour@limits@low@meta) and MAX = (\pgfplotsplothandlercontour@limits@high@x,\pgfplotsplothandlercontour@limits@high@y,\pgfplotsplothandlercontour@limits@high@z;\pgfplotsplothandlercontour@limits@high@meta).}% }% \def\pgfplotsplothandlercontour@init@limits@getboundingboxlow(#1,#2,#3,#4){% \def\pgfplotsplothandlercontour@init@limits@cur{low}% \pgfplotsplothandlercontour@init@limits@read(#1,#2,#3,#4)% \pgfutil@ifnextchar(% \pgfplotsplothandlercontour@init@limits@getboundingboxhigh {\pgfplots@error{Sorry, 'data limits=(xmin,ymin,zmin,contourmin) (xmax,ymax,zmax,contourmax)' has been expected, not \pgfkeysvalueof{/pgfplots/contour/data limits}}\pgfplots@gobble@until@EOI}% }% \def\pgfplotsplothandlercontour@init@limits@getboundingboxhigh(#1,#2,#3,#4){% \def\pgfplotsplothandlercontour@init@limits@cur{high}% \pgfplotsplothandlercontour@init@limits@read(#1,#2,#3,#4)% \pgfutil@gobble }% \def\pgfplotsplothandlercontour@init@limits@read(#1,#2,#3,#4){% % FIXME : logs and trafos and user interface! \pgfplotscoordmath{x}{parsenumber}{#1}% \pgfplotscoordmath{x}{datascaletrafo}\pgfmathresult \expandafter\let\csname pgfplotsplothandlercontour@limits@\pgfplotsplothandlercontour@init@limits@cur @x\endcsname=\pgfmathresult % \pgfplotscoordmath{y}{parsenumber}{#2}% \pgfplotscoordmath{y}{datascaletrafo}\pgfmathresult \expandafter\let\csname pgfplotsplothandlercontour@limits@\pgfplotsplothandlercontour@init@limits@cur @y\endcsname=\pgfmathresult % \ifpgfplots@curplot@threedim \pgfplotscoordmath{z}{parsenumber}{#3}% \pgfplotscoordmath{z}{datascaletrafo}\pgfmathresult \expandafter\let\csname pgfplotsplothandlercontour@limits@\pgfplotsplothandlercontour@init@limits@cur @z\endcsname=\pgfmathresult \fi % \pgfplotscoordmath{meta}{parsenumber}{#4}% \expandafter\let\csname pgfplotsplothandlercontour@limits@\pgfplotsplothandlercontour@init@limits@cur @meta\endcsname=\pgfmathresult }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % contour external implementation % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\pgfplotsplothandlercontourexternal{% \pgfplotsresetplothandler \def\pgfplotsplothandlername{contour external}% % \pgfplotsplothandlercontour@prepare@point@meta % \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@contourexternal \def\pgf@plotstreamstart{% \pgfplotsplothandlercontourprepared \pgf@plotstreamstart }% }% \gdef\c@pgfplotsplothandlersurveystart@contourexternal@fileno{0}% \def\pgfplotsplothandlersurveystart@contourexternal{% % \pgfkeysgetvalue{/pgfplots/contour external/file}\pgfplotsplothandlercontourexternal@file % \ifx\pgfplotsplothandlercontourexternal@file\pgfutil@empty \pgfutil@ifundefined{pgfactualjobname}{% \let\pgfplots@loc@TMPa=\jobname }{% % be compatible with external lib: \let\pgfplots@loc@TMPa=\pgfactualjobname }% \edef\pgfplotsplothandlercontourexternal@file{\pgfplots@loc@TMPa_contourtmp\c@pgfplotsplothandlersurveystart@contourexternal@fileno}% \pgfplotsutil@advancestringcounter@global\c@pgfplotsplothandlersurveystart@contourexternal@fileno \fi % \if0\pgfplotsplothandlercontourexternal@scanlinemode \pgfplotsset{plot to file/scanline marks/false}% \else \pgfplotsset{plot to file/scanline marks/if in input}% the choice 'always' is unaware of existing end-of-scanline marks \fi \pgfplotsplothandlertofile{\pgfplotsplothandlercontourexternal@file.dat}% \pgfplotsplothandlersurveystart \let\pgfplotsplothandlersurveypoint@tofile=\pgfplotsplothandlersurveypoint \let\pgfplotsplothandlersurveyend@tofile=\pgfplotsplothandlersurveyend \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@contourexternal \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@contourexternal }% \def\pgfplotsplothandlersurveypoint@contourexternal{% % temporarily disable updates to point meta limits. They should be % updated during the contour prepared processing. \let\pgfplotsplothandlercontourexternal@orig@perpointlimits@limits=\pgfplots@set@perpointmeta@limits \let\pgfplots@set@perpointmeta@limits=\relax % \pgfplotsaxissurveysetpointmeta \let\pgfplots@current@point@z=\pgfplots@current@point@meta % \let\pgfplots@set@perpointmeta@limits=\pgfplotsplothandlercontourexternal@orig@perpointlimits@limits % %\message{contour gnuplot: collecting point (\pgfplots@current@point@x,\pgfplots@current@point@y,\pgfplots@current@point@z) [\pgfplots@current@point@meta]...}% \pgfplotsplothandlersurveypoint@tofile }% { \catcode`\`=12 \catcode`\'=12 \catcode`\"=12 \catcode`\|=12 \catcode`\;=12 \catcode`\:=12 \catcode`\#=12 \gdef\pgfplotsplothandlersurveyend@contourexternal{% \pgfplotsplothandlersurveyend@tofile \if2\pgfplotsplothandlercontourexternal@scanlinemode \if0\pgfplotsplothandlertofilegeneratedscanlinemarks \pgfplots@error{Sorry, processing the input stream did not lead to end-of-scanline markers; the generated temporary file for 'contour external' does not contain any of them (indicating that matrix structure is lost). To fix this, you have the following options:^^J - Insert end-of-scanline markers into your input data (i.e. empty lines),^^J - provide two of the three options 'mesh/rows=, mesh/cols=, mesh/num points='}% \fi \fi % \begingroup \let\numcoords=\pgfplots@current@point@coordindex% \pgfplotsautocompletemeshkeys \def\"{"}% \def\|{|}% \def\;{;}% \def\:{:}% \def\#{#}% \def\'{'}% \def\`{`}% \edef\ordering{\pgfplots@plot@mesh@ordering}% \edef\infile{\pgfplotsplothandlercontourexternal@file.dat}% \edef\outfile{\pgfplotsplothandlercontourexternal@file.table}% \edef\script{\pgfplotsplothandlercontourexternal@file.\pgfkeysvalueof{/pgfplots/contour external/script extension}}% \immediate\openout\w@pgf@writea=\script \immediate\write\w@pgf@writea{\pgfkeysvalueof{/pgfplots/contour external/script}}% \immediate\closeout\w@pgf@writea % \immediate\write18{\pgfkeysvalueof{/pgfplots/contour external/cmd}}% \endgroup % % \pgfplotsplothandlercontourprepared \let\pgfplots@coord@stream@start=\relax% has already been done. \def\pgfplots@coord@stream@end{\pgfplotsplothandlersurveyend}% \ifpgfplots@curplot@threedim \pgfplotssetpointmetainput{z}{}% \else \pgfplotssetpointmetainput{explicit}{}% \fi \pgfplots@addplotimpl@file@streamit{\pgfplotsplothandlercontourexternal@file.table}% \closein\r@pgfplots@reada }% } % the `plot unprocessed to file' plot handler simply copies the input data % UNPROCESSED to an output file. % % I use it as helper tool for `contour gnuplot'. % % this cannot be combined with other plot handlers unless the other % plot handlers controls that explicitly % % Immediately after the survey ends, this plot handler will set % \pgfplotsplothandlertofilegeneratedscanlinemarks to '1' or '0'. \pgfplotsset{ plot unprocessed to file/.code={ \edef\tikz@plot@handler{\noexpand\pgfplotsplothandlertofile{#1}}% }, plot to file/scanline marks/.is choice, plot to file/scanline marks/false/.code={\def\pgfplotsplothandlertofile@scanlinemarks{0}}, plot to file/scanline marks/if in input/.code={\def\pgfplotsplothandlertofile@scanlinemarks{1}}, plot to file/scanline marks/always/.code={\def\pgfplotsplothandlertofile@scanlinemarks{2}}, plot to file/scanline marks/true/.code={\def\pgfplotsplothandlertofile@scanlinemarks{2}}, plot to file/scanline marks/if in input, plot to file/col sep/.initial=\pgfplots@TAB, plot to file/end-of-scanline content/.initial=, } \def\pgfplotsplothandlertofile#1{% \edef\pgfplotsplothandlertofile@name{#1}% \pgfplotsresetplothandler \pgfplotsset{empty line=scanline}% \let\pgfplotsplothandlersurveystart=\pgfplotsplothandlersurveystart@tofile \def\pgfplotsplothandlername{plot to file}% \let\pgfplotsplothandlersurveyend=\pgfplotsplothandlersurveyend@tofile \let\pgfplotsplothandlersurveypoint=\pgfplotsplothandlersurveypoint@tofile \let\pgfplotsplothandlernotifyscanlinecomplete=\pgfplotsplothandlernotifyscanlinecomplete@tofile % \if1\pgfplotsplothandlertofile@scanlinemarks % plot to file/scanline marks=if in input % check if we have mesh input: \def\pgfplots@loc@TMP@has@mesh@information{0}% \pgfkeysgetvalue{/pgfplots/mesh/rows}\pgfplots@loc@TMPa \pgfkeysgetvalue{/pgfplots/mesh/cols}\pgfplots@loc@TMPb \pgfkeysgetvalue{/pgfplots/mesh/num points}\pgfplots@loc@TMPc \ifx\pgfplots@loc@TMPa\pgfutil@empty \ifx\pgfplots@loc@TMPc\pgfutil@empty \else % has rows and num points: \def\pgfplots@loc@TMP@has@mesh@information{1}% \fi \else \ifx\pgfplots@loc@TMPb\pgfutil@empty \ifx\pgfplots@loc@TMPc\pgfutil@empty \else % has cols and num points: \def\pgfplots@loc@TMP@has@mesh@information{1}% \fi \else % has rows,cols: \def\pgfplots@loc@TMP@has@mesh@information{1}% \fi \fi \if1\pgfplots@loc@TMP@has@mesh@information % activate 'plot to file/scanline marks=always % --> we have the required information! \def\pgfplotsplothandlertofile@scanlinemarks{2}% \fi \fi % NO \else here! \if2\pgfplotsplothandlertofile@scanlinemarks % plot to file/scanline marks=always \pgfplotsautocompletemeshkeys% \def\c@pgfplotsplothandlertofile@scanlinelength{0}% \if\pgfplots@plot@mesh@ordering0% % ordering = x varies= rowwise -> scanline is cols! \pgfkeysgetvalue{/pgfplots/mesh/cols}\c@pgfplotsplothandlertofile@expectedscanline \else % ordering = y varies = colwise: scanline is rows! \pgfkeysgetvalue{/pgfplots/mesh/rows}\c@pgfplotsplothandlertofile@expectedscanline \fi \fi \pgfplotsplothandlertofile@scanlinependingfalse \pgfkeysgetvalue{/pgfplots/plot to file/col sep}\pgfplotsplothandlertofile@colsep \pgfkeysgetvalue{/pgfplots/plot to file/end-of-scanline content}\pgfplotsplothandlertofile@scanlinemark % % \def\pgfplotsplothandlertofilegeneratedscanlinemarks{0}% }% \def\pgfplotsplothandlertofile@scanlinemarks@check{% \if2\pgfplotsplothandlertofile@scanlinemarks % plot to file/scanline marks=always \pgfplotsutil@advancestringcounter\c@pgfplotsplothandlertofile@scanlinelength \ifnum\c@pgfplotsplothandlertofile@scanlinelength=\c@pgfplotsplothandlertofile@expectedscanline \def\c@pgfplotsplothandlertofile@scanlinelength{0}% \pgfplotsplothandlernotifyscanlinecomplete@tofile \fi \fi }% \newif\ifpgfplotsplothandlertofile@scanlinepending \def\pgfplotsplothandlernotifyscanlinecomplete@tofile{% \if0\pgfplotsplothandlertofile@scanlinemarks \else \pgfplotsplothandlertofile@scanlinependingtrue \fi }% \def\pgfplotsplothandlersurveypoint@tofile{% \ifpgfplotsplothandlertofile@scanlinepending \def\pgfplotsplothandlertofilegeneratedscanlinemarks{1}% \immediate\write\w@pgf@writea{\pgfplotsplothandlertofile@scanlinemark}% end-of-scanline \pgfplotsplothandlertofile@scanlinependingfalse \fi \pgfplotscoordmath{x}{parsenumber}{\pgfplots@current@point@x}% \pgfplotscoordmath{x}{tostring}{\pgfmathresult}% \let\pgfplots@current@point@x=\pgfmathresult % \pgfplotscoordmath{y}{parsenumber}{\pgfplots@current@point@y}% \pgfplotscoordmath{y}{tostring}{\pgfmathresult}% \let\pgfplots@current@point@y=\pgfmathresult % \ifpgfplots@curplot@threedim \pgfplotscoordmath{z}{parsenumber}{\pgfplots@current@point@z}% \pgfplotscoordmath{z}{tostring}{\pgfmathresult}% \let\pgfplots@current@point@z=\pgfmathresult \fi % \pgfplotsaxissurveysetpointmeta \pgfplotsaxisifhaspointmeta{% \pgfplotscoordmath{meta}{tostring}{\pgfplots@current@point@meta}% \let\pgfplots@current@point@meta=\pgfmathresult }{}% % \immediate\write\w@pgf@writea{% \pgfplots@current@point@x\pgfplotsplothandlertofile@colsep \pgfplots@current@point@y\pgfplotsplothandlertofile@colsep \ifpgfplots@curplot@threedim\pgfplots@current@point@z\pgfplotsplothandlertofile@colsep\fi \pgfplots@current@point@meta }% \advance\c@pgfplots@coordindex by1 \pgfplotsplothandlertofile@scanlinemarks@check }% \def\pgfplotsplothandlersurveyend@tofile{% \immediate\closeout\w@pgf@writea }% \def\pgfplotsplothandlersurveystart@tofile{% \immediate\openout\w@pgf@writea=\pgfplotsplothandlertofile@name\relax }% \input pgfplotsmeshplothandler.code.tex