summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/pgfplots/tex/pgfplotsstackedplots.code.tex
blob: 7f45bfb5befbae3c23ec20cc6b58b6b236b97fc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
%--------------------------------------------
%
% 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 2007-2013 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 <http://www.gnu.org/licenses/>.
%
%--------------------------------------------

%
% This file contains the implementation for stacked plots.
%
% Stacked plots always keep record of the last plotted coordinates.
% Any new plot will be ADDED on top of the last plotted coordinates.
% 
% Terminology: "last plotted coordinates" are called "zero levels"
% because they actually work like shifts.
%
% Programming Structure:
%
% 1. We keep TWO lists of coordinates: a list of CURRENT zero level
% coordinates and a list of NEXT zero level coordinates.
%
% The first one will be queried whenever a zero level coordinate is
% requested.
%
% The second one will be used to form zero levels for the next plot.
%
% 2. At the beginning and end of the survey phase of each plot, the lists in 1.) are
% initialised properly.
%
% 3.1 While plot coordinates are processed during the survey phase, the following methods
% interact with the stacked API:
% \pgfplots@stacked@preparepoint@inmacro
% 	-> compute the 'stacked' sum.
% 	This may need to be done with floating point arithmetics because
% 	the data scaling trafo is not yet initialised
% \pgfplots@stacked@rememberzerolevelpoint@for@next@plot
% \pgfplots@stacked@getnextzerolevelpoint
%
%
% 3.2 during the final visualization phase, we have
% \pgfplots@stacked@visphasepreparedatapoint
% 	-> takes coordinates as they will be given to Tikz. This method is
% 	used to 
% 		- communicate zero level coordinates to Tikz
% 		- implement the 'closed paths' option (allows filled stacked plots).
%
% 4. Zero levels are communicated to Tikz by
% \pgfplots@stacked@initzerolevelhandler. This routine initialises an
% input stream for Tikz plot handlers which produces a sequence of
% zero levels. It is used by [xy]comb and [xy]bar.
%
%

\let\pgfplots@stacked@zerolevelpoint@x=\pgfutil@empty
\let\pgfplots@stacked@zerolevelpoint@y=\pgfutil@empty

% this value is populated during the survey phase. It will be copied
% to the visualization phase, i.e. it will be serialized along with
% the survey'ed state:
\newif\ifpgfplots@stacked@isfirstplot
\newif\ifpgfplots@stacked@isinitialised

% Pre-initialisation.
% Needs to be called before the first call to
% \pgfplots@stacked@beginplot.
\def\pgfplots@stacked@initialise{%
	\gdef\pgfplots@stacked@coordcount{-1}%
	\pgfplots@stacked@isfirstplottrue
	\pgfplots@stacked@isinitialisedtrue
}%

% Cleanup method. Truncates any global variables to reduce string
% space.
\def\pgfplots@stacked@finalize{%
	\global\pgfplotslistnewempty\pgfplots@stacked@zerolevellist
	\global\pgfplotslistnewempty\pgfplots@stacked@zerolevellist@neg
	\global\pgfplotslistnewempty\pgfplots@stacked@nextzerolevellist@pos
	\global\pgfplotslistnewempty\pgfplots@stacked@nextzerolevellist@neg
	\pgfplots@stacked@isinitialisedfalse
}%

% (Re)defines the macro \pgfplots@stacked@getnextzerolevelpoint
% at the beginning of each plot.
%
% The macro \pgfplots@stacked@getnextzerolevelpoint fills
% \pgfplots@stacked@zerolevelpoint@[xy].
%
% ATTENTION: call \pgfplots@stacked@initialise before the first call
% of beginplot!
%
% ATTENTION: install this before 'visualization depends on' - it
% modifies \pgfplotsaxisserializedatapoint@private
\def\pgfplots@stacked@beginplot{%
%\message{pgfplots@stacked@beginplot: PLOT STARTED.}%
	\ifpgfplots@stacked@isinitialised
	\else
		\pgfplots@error{LOGIC ERROR: please call \string\pgfplots@stacked@initialise.}%
	\fi
	\def\pgfplots@stacked@zerolevel@current{}%
	\def\pgfplots@stacked@zerolevel@current@pos{}%
	\def\pgfplots@stacked@zerolevel@current@neg{}%
	\pgfplots@stacked@prepare@value@serialization
	% accumulate this command here for \closedcycle:
	\ifpgfplots@stacked@isfirstplot
		\global\pgfplotslistnewempty\pgfplots@stacked@zerolevellist
		\global\pgfplotslistnewempty\pgfplots@stacked@zerolevellist@neg
		% only work with float if its really necessary - for
		% example if the scaling trafo which maps to pgfmath is
		% not yet initialised.
		\pgfplots@stacked@zerolevel@fallback x%
		\pgfplots@stacked@zerolevel@fallback y%
		\pgfplots@stacked@zerolevel@fallback z%
		%
		\def\pgfplots@stacked@getnextzerolevelpoint{%
			% keep \pgfplots@stacked@zerolevel@current = {}
			% there is special handling in place which will use the
			% '0' level in this case
			%
			% omit this:
			%\pgfplots@stacked@ensure{}%
			%\let\pgfplots@stacked@zerolevel@current=\pgfplotsretval
		}%
	\else
		{\globaldefs=1
		\pgfplotslistcopy\pgfplots@stacked@nextzerolevellist@pos\to\pgfplots@stacked@zerolevellist
		\pgfplotslistcopy\pgfplots@stacked@nextzerolevellist@neg\to\pgfplots@stacked@zerolevellist@neg
		}%
		\def\pgfplots@stacked@getnextzerolevelpoint{%
			%
			\pgfplots@stacked@getnextzerolevelpoint@pos
			%
			\if P\pgfplots@stacked@negative@mode
				% stack negative=on previous:
				% just use one list in order to remember the
				% zerolevel:
				\expandafter\pgfplots@stacked@parsezerolevelpoint\expandafter{\pgfplots@stacked@zerolevel@current@pos}%
			\else
				% stack negative=separate:
				% use two levels, one for '+' and one for '-':
				\pgfplots@stacked@getnextzerolevelpoint@neg
				%
				\if+\pgfplots@stacked@sign
					\expandafter\pgfplots@stacked@parsezerolevelpoint\expandafter{\pgfplots@stacked@zerolevel@current@pos}%
				\else
					\expandafter\pgfplots@stacked@parsezerolevelpoint\expandafter{\pgfplots@stacked@zerolevel@current@neg}%
				\fi
			\fi
		}%
	\fi
	\global\pgfplotslistnewempty\pgfplots@stacked@nextzerolevellist@pos
	\global\pgfplotslistnewempty\pgfplots@stacked@nextzerolevellist@neg
}%

\def\pgfplots@stacked@getnextzerolevelpoint@pos{%
	\pgfplotslistcheckempty\pgfplots@stacked@zerolevellist
	\ifpgfplotslistempty
		\pgfplots@stacked@wrong@count@error
	\else
		{\globaldefs=1
		\pgfplotslistpopfront\pgfplots@stacked@zerolevellist\to\pgfplots@stacked@zerolevel@current@pos
		}%
	\fi
}%
\def\pgfplots@stacked@getnextzerolevelpoint@neg{%
	\pgfplotslistcheckempty\pgfplots@stacked@zerolevellist@neg
	\ifpgfplotslistempty
		\pgfplots@stacked@wrong@count@error
	\else
		{\globaldefs=1
		\pgfplotslistpopfront\pgfplots@stacked@zerolevellist@neg\to\pgfplots@stacked@zerolevel@current@neg
		}%
	\fi
}

\def\pgfplots@stacked@zerolevel@fallback#1{%
	\pgfplots@stacked@zerolevel@fallback@{#1}%
	\expandafter\let\csname pgfplots@stacked@zerolevelpoint@#1\endcsname=\pgfmathresult%
}%
\def\pgfplots@stacked@zerolevel@fallback@#1{%
	\ifpgfplots@datascaletrafo@initialised % FIXME : should be '!ifsurvey'
		\def\pgfmathresult{0}%
	\else
		% note that log plots are special: their "stacked zero" is
		% computed with \pgfplotscoordmath{default}
		%
		\pgfplots@if{pgfplots@#1islinear}{\pgfplotscoordmath{#1}{zero}}{\pgfplotscoordmath{default}{zero}}%
	\fi
}%

% ATTENTION: install this before 'visualization depends on' - it
% modifies \pgfplotsaxisserializedatapoint@private
\def\pgfplots@stacked@visphase@beginplot{%
%\message{pgfplots@stacked@beginplot: VISUALIZATION OF PLOT STARTED (phase = \pgfplots@visphase@name).^^J}%
	\let\pgfplots@stacked@closedcycle@impl=\pgfutil@empty
	\pgfplots@stacked@prepare@value@serialization
}%

\def\pgfplots@stacked@prepare@value@serialization{%
	% This here is SIMILAR to 'visualization depends on'.
	%
	% The only difference is that 'visualization depends on' expands
	% its arguments whereas this one here does not.
	%
	\pgfplotsset{%
		visualization depends on=value \pgfplots@stacked@diff\as\pgfplots@stacked@diff
	}%
	%
	%
	% Modify the axis private parts such that a data point is
	% serialized to the form
	% {Z{<stacked zerolevel value>}{<point meta>};<x coordinate>,<y coordinate>,<z coordinate>}
	%
	% for example, a 2d data pont (0,1) without point meta is serialized to 
	% {Z{}{};0Y0.0e0],1Y1.0e0],}
	%
	% The deserialization looks for the magic token 'Z'. The next
	% parameter is the zero level of the data point, the following one
	% the "old" private serialization stuff (typically just point
	% meta).
	%
	% Note that the zero level of a data point might have its own zero
	% level (grand father) ... this would be part here as well, even
	% if it is useless (?). This causes recursive references to all
	% zero levels... and more memory for stacked plots.
	%
	% The zero'th level has an empty zero level point.
	\expandafter\def\expandafter\pgfplotsaxisserializedatapoint@private\expandafter{%
		\pgfplotsaxisserializedatapoint@private
		% at deserialization time, this will become \pgfplots@stacked@zerolevel :
		\t@pgfplots@toka=\expandafter{\pgfplots@stacked@zerolevel@current}%
		\t@pgfplots@tokb=\expandafter{\pgfplotsretval}%
		\edef\pgfplotsretval{%
			Z{\the\t@pgfplots@toka}%
			{\the\t@pgfplots@tokb}%
		}%
	}%
	%
	\pgfutil@ifundefined{pgfplotsaxisdeserializedatapointfrom@private@backup@}{}{%
		\pgfplots@error{Illegal internal state encountered: the stacked plots serialization preparation has been invoked twice}%
	}%
	\let\pgfplotsaxisdeserializedatapointfrom@private@backup@=\pgfplotsaxisdeserializedatapointfrom@private
	\def\pgfplotsaxisdeserializedatapointfrom@private##1{%
		\pgfplotsaxisdeserializedatapointfrom@private@stacked@##1%
	}%
}%

\def\pgfplotsaxisdeserializedatapointfrom@private@stacked@ Z#1#2{%
	\def\pgfplots@stacked@zerolevel{#1}%
	\pgfplotsaxisdeserializedatapointfrom@private@backup@{#2}%
}%

% #1: the result of \pgfplotsaxisserializedatapointtostring
\def\pgfplots@stacked@parsezerolevelpoint#1{%
	\begingroup
	\pgfplotsaxisdeserializedatapointfrom#1% no braces here!
%	\pgfplotsplothandlerdeserializepointfrom{#1}%
	\pgfplots@stacked@smuggle
	\endgroup
	% the value of \pgfplots@stacked@zerolevel@current will be configured as
	% "visualization depends on".
	% In other words: it is available later-on.
	\def\pgfplots@stacked@zerolevel@current{#1}%
}

\def\pgfplots@stacked@smuggle\endgroup{%
	\xdef\pgfplots@glob@TMPb{%
		\noexpand\def\noexpand\pgfplots@stacked@zerolevelpoint@x{\pgfplots@current@point@x}%
		\noexpand\def\noexpand\pgfplots@stacked@zerolevelpoint@y{\pgfplots@current@point@y}%
		\noexpand\def\noexpand\pgfplots@stacked@zerolevelpoint@z{\pgfplots@current@point@z}%
	}%
	\endgroup
	\pgfplots@glob@TMPb
}%

\def\pgfplots@stacked@wrong@count@error{%
	\pgfplots@error{Sorry, pgfplots expects stacked plots to have exactly the same number of coordinates. Unfortunately, I encountered at plot with DIFFERENT NUMBERS OF COORDINATES. Please verify that 1. no point has been dropped by coordinate filters (for example log(0) or so) and 2. all plots have the same number of coordinates.}%
}%

\def\pgfplots@stacked@survey@endplot{%
%\message{Stacked plot survey phase end: isfirst = \ifpgfplots@stacked@isfirstplot true \else false\fi^^J}%
	\ifpgfplots@stacked@isfirstplot
		\pgfplotslistcheckempty\pgfplots@stacked@zerolevellist
		\ifpgfplotslistempty
		\else
			\pgfplots@stacked@wrong@count@error
		\fi
		\if P\pgfplots@stacked@negative@mode
			% stack negative=on previous:
		\else
			% stack negative=separate:
			\pgfplotslistcheckempty\pgfplots@stacked@zerolevellist@neg
			\ifpgfplotslistempty
			\else
				\pgfplots@stacked@wrong@count@error
			\fi
		\fi
	\fi
	\ifpgfplots@stacked@isfirstplot
		\def\pgfplots@stacked@serialized@commands{\noexpand\pgfplots@stacked@isfirstplottrue}%
	\else
		\def\pgfplots@stacked@serialized@commands{\noexpand\pgfplots@stacked@isfirstplotfalse}%
	\fi
	\global\pgfplots@stacked@isfirstplotfalse
}%

\def\pgfplots@stacked@visphase@endplot{%
%\message{Stacked plot vis phase end: isfirst = \ifpgfplots@stacked@isfirstplot true \else false\fi^^J}%
	\ifpgfplots@stacked@isfirstplot
		\let\pgfplots@stacked@closedcycle@impl=\pgfplots@path@closed@cycle@std
	\else
		\t@pgfplots@tokc=\expandafter{\pgfplots@stacked@closedcycle@impl}%
		\edef\pgfplots@stacked@closedcycle@impl{%
			[mark=none,/utils/exec=\noexpand\pgfplots@try@mirror@plot@handler]
			--plot coordinates{\the\t@pgfplots@tokc}
			--cycle
		}%
	\fi
	\global\pgfplots@stacked@isfirstplotfalse
}%

% WARNING: when this method is called, NEITHER
% \ifpgfplots@stacked@isfirstplot NOR the zero level lists are
% initialised!
\def\pgfplots@stacked@initzerolevelhandler{%
	\if\pgfplots@stacked@dir x
		\pgfplotxzerolevelstream@@list
		\pgfplotyzerolevelstreamconstant{\pgfplots@ZERO@y}%
	\else
		\pgfplotxzerolevelstreamconstant{\pgfplots@ZERO@x}%
		\pgfplotyzerolevelstream@@list
	\fi
}%

% Provides public access to zero levels into some key-value pairs.
% Returns the values into a set of keys in the /data point/ prefix.
%
% The values can be used in 'axis cs'.
\def\pgfplotspointgetzerolevelcoordinates{%
	\pgfplotspointgetnormalizedzerolevelcoordinates
	\pgfplotspointgetcoordinatesfromnormalized[path=/data point/zero]%
	\pgfplotspointgetcoordinatesfromnormalized[path=/data point/diff]%
}

% Same as \pgfplotsgetzerolevelcoordinates, but the resulting values
% are for use in 'normalized axis cs'.
%
% This works for both stacked plots and normal plots.
\def\pgfplotspointgetnormalizedzerolevelcoordinates{%
	\begingroup
	\ifpgfplots@stackedmode
		% STATE: 
		%  * \pgfplots@stacked@diff is the diff of the CURRENT point.
		%  * \pgfplots@stacked@zerolevel is the ENTIRE point of the
		%     zerolevel (consisting of its recursive zerolevel, its own diff, and its x,y coords) 
		%  -> we need both
		\let\pgfplots@stacked@diff@cur=\pgfplots@stacked@diff
		\ifx\pgfplots@stacked@zerolevel\pgfutil@empty
			\pgfplotspointgetnormalizedcoordinates%
			\pgfplotsutilforeachcommasep{x,y,z}\as\pgfplots@loc@TMPa{%
				\pgfkeysgetvalue{/data point/\pgfplots@loc@TMPa}\pgfplots@loc@TMPb
				\expandafter\let\csname pgfplots@current@point@\pgfplots@loc@TMPa\endcsname=\pgfplots@loc@TMPb
			}%
			\pgfplotscoordmath{\pgfplots@stacked@dir}{zero}%
			\expandafter\let\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname\pgfmathresult%
			%
			\let\pgfplots@current@point@meta=\pgfutil@empty
			\pgfkeyssetvalue{/data point/zero/auto}{1}%
		\else
			%
			\expandafter\pgfplotsaxisdeserializedatapointfrom\pgfplots@stacked@zerolevel%
			\pgfkeyssetvalue{/data point/zero/auto}{0}%
		\fi
		%
		\pgfplotscoordmath{x}{zero}\let\pgfplots@stacked@diff@x=\pgfmathresult%
		\pgfplotscoordmath{y}{zero}\let\pgfplots@stacked@diff@y=\pgfmathresult%
		\pgfplotscoordmath{z}{zero}\let\pgfplots@stacked@diff@z=\pgfmathresult%
		\pgfutil@namelet{pgfplots@stacked@diff@\pgfplots@stacked@dir}{pgfplots@stacked@diff@cur}%
	\else
		% Ah - no stacked plot!? Well, than do "something useful":
		% ... note that we have to use 'pgfbasic' here as that is the
		% "transformed" format.
		\pgfplotscoordmath{pgfbasic}{zero}\let\pgfplots@current@point@x=\pgfmathresult%
		\pgfplotscoordmath{pgfbasic}{zero}\let\pgfplots@current@point@y=\pgfmathresult%
		\pgfplotscoordmath{pgfbasic}{zero}\let\pgfplots@current@point@z=\pgfmathresult%
		%
		\pgfplotspointgetnormalizedcoordinates%
		\pgfplotsutilforeachcommasep{x,y,z}\as\pgfplots@loc@TMPa{%
			\pgfkeysgetvalue{/data point/\pgfplots@loc@TMPa}\pgfplots@loc@TMPb
			\expandafter\let\csname pgfplots@stacked@diff@\pgfplots@loc@TMPa\endcsname=\pgfplots@loc@TMPb
		}%
		\pgfkeyssetvalue{/data point/zero/auto}{1}%
	\fi
	%
	\xdef\pgfplots@glob@TMPd{%
		\noexpand\pgfkeyssetvalue{/data point/zero/x}{\pgfplots@current@point@x}%
		\noexpand\pgfkeyssetvalue{/data point/zero/y}{\pgfplots@current@point@y}%
		\noexpand\pgfkeyssetvalue{/data point/zero/z}{\pgfplots@current@point@z}%
		\noexpand\pgfkeyssetvalue{/data point/zero/meta}{\pgfplots@current@point@meta}%
		\noexpand\pgfkeyssetvalue{/data point/zero/auto}{\pgfkeysvalueof{/data point/zero/auto}}%
		\noexpand\pgfkeyssetvalue{/data point/diff/x}{\pgfplots@stacked@diff@x}%
		\noexpand\pgfkeyssetvalue{/data point/diff/y}{\pgfplots@stacked@diff@y}%
		\noexpand\pgfkeyssetvalue{/data point/diff/z}{\pgfplots@stacked@diff@z}%
	}%
	\endgroup
	\pgfplots@glob@TMPd
%
%\message{pgfplotsgetzerolevelcoordinates returned x=\pgfkeysvalueof{/data point/zero/x}, y=\pgfkeysvalueof{/data point/zero/y}, diffx=\pgfkeysvalueof{/data point/diff/x}; diffy=\pgfkeysvalueof{/data point/diff/y}, diff=\pgfkeysvalueof{/data point/diff}^^J}%
}%

% PRECONDITION:
% 	Is in invoked inside of a coord preparation routine, that means
% 	- \pgfplots@current@point@[xyz] 
% 	- \ifpgfplots@curplot@threedim
% 	are all set properly.
% 
% POSTCONDITION:
%   - the zero level macro is set (for use in the visualizer)
%   - the closed cycle impl is updated
%   - the points as such are NOT touched
\def\pgfplots@stacked@visphasepreparedatapoint{%
	\ifx\pgfplots@stacked@zerolevel\pgfutil@empty
		% this here is the case if we have the first encountered plot,
		% i.e. the one on which others are stacked.
		%
		% Note that it is not necessarily the first one which is
		% processed (compare reverse stacked plots).
		\begingroup
		% FIXME : eliminate this special handling by recording the
		% correct '0' values during the survey phase!
		\pgfutil@namelet{pgfplots@current@point@\pgfplots@stacked@dir}{pgfplots@logical@ZERO@\pgfplots@stacked@dir}%
		\pgfplotsaxis@toPGF@coords
		\if\pgfplots@stacked@dir x
			\edef\pgfplots@stacked@PGF@zerolevel{\the\pgf@x}%
		\else
			\edef\pgfplots@stacked@PGF@zerolevel{\the\pgf@y}%
		\fi
		\pgfmath@smuggleone\pgfplots@stacked@PGF@zerolevel
		\endgroup
		%
	\else
		\begingroup
		%\expandafter\pgfplotsplothandlerdeserializepointfrom\expandafter{\pgfplots@stacked@zerolevel}%
		\expandafter\pgfplotsaxisdeserializedatapointfrom\pgfplots@stacked@zerolevel%
		%
		\pgfplots@stacked@logarithm@if@needed
		%
		% avoid endless recursion:
		\let\pgfplots@stacked@visphasepreparedatapoint=\relax
		\pgfplotsaxisvisphasegetpoint
		\edef\pgfplots@current@point@x{\the\pgf@x}%
		\edef\pgfplots@current@point@y{\the\pgf@y}%
		% this here merely communicates
		% \pgfplots@stacked@zerolevelpoint@x and @y outside of the
		% group:
		\pgfplots@stacked@smuggle
		\endgroup
		%
		\if\pgfplots@stacked@dir x
			\let\pgfplots@stacked@PGF@zerolevel=\pgfplots@stacked@zerolevelpoint@x%
		\else
			\let\pgfplots@stacked@PGF@zerolevel=\pgfplots@stacked@zerolevelpoint@y%
		\fi
		\t@pgfplots@toka=\expandafter{\pgfplots@stacked@closedcycle@impl}%
		\edef\pgfplots@stacked@closedcycle@impl{%
			(\pgfplots@stacked@zerolevelpoint@x,\pgfplots@stacked@zerolevelpoint@y)%
			\the\t@pgfplots@toka}%
	\fi
}%

% A special hook which is executed early in the visualization phase. 
% It will be invoked *before*
% \pgfplots@stacked@visphasepreparedatapoint!
%
% Its purpose is to clear the data if necessary, i.e. it implements 
% /pgfplots/stacked ignores zero
\def\pgfplots@stacked@visphase@stream@coord@{%
	\ifpgfplots@stacked@ignores@zero
		\edef\pgfplots@loc@TMPa{\pgfkeysvalueof{/pgfplots/stacked ignores zero/\pgfplots@visphase@name}}%
		\def\pgfplots@loc@TMPb{true}%
		% apply this feature only if it is active for the current
		% visualization phase:
		\ifx\pgfplots@loc@TMPb\pgfplots@loc@TMPa
			\ifx\pgfplots@current@point@x\pgfutil@empty% this implements `unbounded coords=jump', for example
			\else
				\pgfplotscoordmath{\pgfplots@stacked@dir}{if is}{\pgfplots@stacked@diff}{0}{%
					\let\pgfplots@current@point@x=\pgfutil@empty
					\let\pgfplots@current@point@y=\pgfutil@empty
					\let\pgfplots@current@point@z=\pgfutil@empty
				}{%
				}%
			\fi
		\fi
	\fi
}%

% PRECONDITION:
% 	Is in invoked inside of a coord preparation routine, that means
% 	- \pgfplots@current@point@[xyz] 
% 	- \ifpgfplots@curplot@threedim
% 	are all set properly.
%
% POSTCONDITION:
% 	- \pgfplots@current@point@[xyz] are adjusted.
\def\pgfplots@stacked@preparepoint@inmacro{%
	\ifpgfplots@stacked@plus
		\def\pgfplots@stacked@op{add}%
	\else
		\def\pgfplots@stacked@op{subtract}%
	\fi
	%
	\pgfutil@namelet{pgfplots@stacked@diff}{pgfplots@current@point@\pgfplots@stacked@dir}%
	%
	\pgfmathfloatparsenumber{\pgfplots@stacked@diff}%
	\expandafter\pgfmathfloatifflags\expandafter{\pgfmathresult}{2}{%
		\def\pgfplots@stacked@sign{-}%
	}{%
		\def\pgfplots@stacked@sign{+}%
	}%
	\pgfplots@stacked@getnextzerolevelpoint
	%
	%
	\pgfplots@if{pgfplots@\pgfplots@stacked@dir islinear}{%
		\pgfplotscoordmath{\pgfplots@stacked@dir}{op}{\pgfplots@stacked@op}{%
			{\csname pgfplots@stacked@zerolevelpoint@\pgfplots@stacked@dir\endcsname}%
			{\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname}}%
	}{%
		% LOG. we need to compute log(zerolevel + current):
		% FIXME : this might work, but is is hackery - because the
		% coordmath framework handles log bases in a very stupid way.
		% improve it somehow!
		\edef\pgfmathresult{\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname}%
		\pgfplotscoordmath{\pgfplots@stacked@dir}{exp}{\pgfmathresult}%
		\pgfplotscoordmath{default}{parsenumber}{\pgfmathresult}%
		\expandafter\let\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname=\pgfmathresult
		\pgfplotscoordmath{default}{op}{\pgfplots@stacked@op}{%
			{\csname pgfplots@stacked@zerolevelpoint@\pgfplots@stacked@dir\endcsname}%
			{\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname}%
		}%
	}%
	%
	% for logs, I remember just zerolevel+current; not its log.
	\expandafter\let\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname=\pgfmathresult
	%
	% this here would also be ok, but it would only store the coords
	% of the zero level...
	%\pgfplotsplothandlerserializepointto\pgfplotsretval
	%
	\begingroup
	%
	% without this line, the "zerolevel" would also know all its zero
	% levels recursively:
	\pgfplots@stacked@strip@parents@zerolevel
	%
	\pgfplotsaxisserializedatapointtostring
	%
%\message{Current value is '\pgfplots@stacked@sign'. Serializing: \meaning\pgfplotsretval^^J}%
	\if P\pgfplots@stacked@negative@mode
		% stack negative=on previous:
		% just track one list
		\expandafter\pgfplotslistpushbackglobal\expandafter{\pgfplotsretval}\to\pgfplots@stacked@nextzerolevellist@pos
	\else
		% stack negative=separate:
		% keep track of both separate zerolevel lists:
		\if+\pgfplots@stacked@sign
			\expandafter\pgfplotslistpushbackglobal\expandafter{\pgfplotsretval}\to\pgfplots@stacked@nextzerolevellist@pos
			%
			\pgfplots@stacked@ensure\pgfplots@stacked@zerolevel@current@neg
			\expandafter\pgfplotslistpushbackglobal\expandafter{\pgfplotsretval}\to\pgfplots@stacked@nextzerolevellist@neg
		\else
			\expandafter\pgfplotslistpushbackglobal\expandafter{\pgfplotsretval}\to\pgfplots@stacked@nextzerolevellist@neg
			%
			\pgfplots@stacked@ensure\pgfplots@stacked@zerolevel@current@pos
			\expandafter\pgfplotslistpushbackglobal\expandafter{\pgfplotsretval}\to\pgfplots@stacked@nextzerolevellist@pos
		\fi
	\fi
	%
	\endgroup
	%
	% 
	%
	\pgfplots@stacked@logarithm@if@needed
}

\def\pgfplots@stacked@ensure#1{%
	\ifx#1\pgfutil@empty
		\pgfplots@stacked@zerolevel@fallback@{\pgfplots@stacked@dir}%
		\expandafter\let\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname=\pgfmathresult
	\else
		\expandafter\pgfplotsaxisdeserializedatapointfrom#1% no braces
	\fi
	\pgfplotsaxisserializedatapointtostring
%\message{UNUSED value serialized as \meaning\pgfplotsretval^^J}%
}%

% 
% We store the normal values for zero levels. Consequently, we may
% need to (re)apply the log if we have a log axis. 
%
% I am unsure of whether log+stacked is useful at all.
\def\pgfplots@stacked@logarithm@if@needed{%
	\pgfplots@if{pgfplots@\pgfplots@stacked@dir islinear}{%
	}{%
		\pgfplotscoordmath{\pgfplots@stacked@dir}{log}{\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname}%
		\expandafter\let\csname pgfplots@current@point@\pgfplots@stacked@dir\endcsname=\pgfmathresult
	}%
}%

% you can \let this here to \relax if you want to gain access to all
% zero levels recursively:
\def\pgfplots@stacked@strip@parents@zerolevel{%
	\def\pgfplots@stacked@zerolevel@current{}%
}

% This here is a re-implementation of the stored plot processing.
%
% The idea is simple, although it requires quite some work:
%
% If we stack plots on top of each other, early drawing commands
% (early plots) will be OVERDRAWN by later drawing commands (later
% plots). This is especially unfortunate if we use filled bar plots
% or comb plots.
%
% IDEA: draw plots in REVERSE order. The positioning, styles and
% whatever must not be affected, only the sequence of drawing commands
% shall change.
%
% So, this command here reverses the list.
\def\pgfplots@stacked@finalize@stored@plots{%
	\pgfplotslistnewempty\pgfplots@stored@plotlist@reversed
	\begingroup
	\pgfplotslistforeachungrouped\pgfplots@stored@plotlist\as\pgfplots@loc@TMPa{%
		% Reverse sequence:
		\expandafter\pgfplotslistpushfront\pgfplots@loc@TMPa\to\pgfplots@stored@plotlist@reversed
	}%
	% Now, overwrite the original list:
	\global\let\pgfplots@stored@plotlist=\pgfplots@stored@plotlist@reversed
	\global\let\pgfplots@stored@plotlist@reversed=\relax
	\endgroup
}%

\def\pgfplots@stacked@path@closed@cycle{%
	\pgfplots@stacked@closedcycle@impl
}

% PGF interfaces:
%
% these are relatively simple right now: assuming that the zero-level
% streams are advanced if and only if the coordinate streams are
% advanced, we can simply inject the *currect* zero level rather than
% providing all at once.
\def\pgfplotxzerolevelstream@@list{%
	\def\pgf@plotxzerolevelstreamstart{%
		\gdef\pgf@plotxzerolevelstreamnext{%
			\global\pgf@x=\pgfplots@stacked@PGF@zerolevel\relax
		}%
	}%
	\def\pgf@plotxzerolevelstreamend{%
	}%
}%

\def\pgfplotyzerolevelstream@@list{%
	\def\pgf@plotyzerolevelstreamstart{%
		\gdef\pgf@plotyzerolevelstreamnext{%
			\global\pgf@x=\pgfplots@stacked@PGF@zerolevel\relax
		}%
	}%
	\def\pgf@plotyzerolevelstreamend{%
	}%
}%