Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCandle.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Georg Troska 19/05/16
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <cstdlib>
13
14#include "TBuffer.h"
15#include "TCandle.h"
16#include "TVirtualPad.h"
17#include "TH2D.h"
18#include "TRandom2.h"
19#include "strlcpy.h"
20
25
27
28/** \class TCandle
29\ingroup BasicGraphics
30
31The candle plot painter class.
32
33Instances of this class are generated by the histograms painting
34classes (THistPainter and THStack) when an candle plot (box plot) is drawn.
35TCandle is the "painter class" of the box plots. Therefore it is never used
36directly to draw a candle.
37*/
38
39////////////////////////////////////////////////////////////////////////////////
40/// TCandle default constructor.
41
43{
44 fIsCalculated = 0;
45 fIsRaw = 0;
46 fPosCandleAxis = 0.;
47 fCandleWidth = 1.0;
48 fHistoWidth = 1.0;
49 fMean = 0.;
50 fMedian = 0.;
51 fMedianErr = 0;
52 fBoxUp = 0.;
53 fBoxDown = 0.;
54 fWhiskerUp = 0.;
55 fWhiskerDown = 0.;
56 fNDatapoints = 0;
57 fDismiss = 0;
58 fLogX = 0;
59 fLogY = 0;
60 fLogZ = 0;
61 fNDrawPoints = 0;
62 fNHistoPoints = 0;
63 fAxisMin = 0.;
64 fAxisMax = 0.;
66 fProj = NULL;
67 fDatapoints = 0;
68
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// TCandle constructor passing a draw-option.
73
74TCandle::TCandle(const char *opt)
75{
76 fIsCalculated = 0;
77 fIsRaw = 0;
78 fPosCandleAxis = 0.;
79 fCandleWidth = 1.0;
80 fHistoWidth = 1.0;
81 fMean = 0.;
82 fMedian = 0.;
83 fMedianErr = 0;
84 fBoxUp = 0.;
85 fBoxDown = 0.;
86 fWhiskerUp = 0.;
87 fWhiskerDown = 0.;
88 fNDatapoints = 0;
89 fDismiss = 0;
90 fLogX = 0;
91 fLogY = 0;
92 fLogZ = 0;
93 fNDrawPoints = 0;
94 fNHistoPoints = 0;
95 fAxisMin = 0.;
96 fAxisMax = 0.;
98 fProj = NULL;
99 fDatapoints = 0;
100
101
102 // Conversion necessary in order to cast from const char* to char*
103 char myopt[128];
104 strlcpy(myopt,opt,128);
105
106
107 ParseOption(myopt);
108}
109
110
111////////////////////////////////////////////////////////////////////////////////
112/// TCandle constructor for raw-data candles.
113
114TCandle::TCandle(const Double_t candlePos, const Double_t candleWidth, Long64_t n, Double_t * points)
116{
117 //Preliminary values only, need to be calculated before paint
118 fMean = 0;
119 fMedian = 0;
120 fMedianErr = 0;
121 fBoxUp = 0;
122 fBoxDown = 0;
123 fWhiskerUp = 0;
124 fWhiskerDown = 0;
125 fNDatapoints = n;
126 fIsCalculated = 0;
127 fIsRaw = true;
128 fPosCandleAxis = candlePos;
129 fCandleWidth = candleWidth;
130 fHistoWidth = candleWidth;
132 fProj = NULL;
133 fDismiss = 0;
135 fLogX = 0;
136 fLogY = 0;
137 fLogZ = 0;
138 fNDrawPoints = 0;
139 fNHistoPoints = 0;
140 fAxisMin = 0.;
141 fAxisMax = 0.;
142 sprintf(fOptionStr," ");
143}
144
145////////////////////////////////////////////////////////////////////////////////
146/// TCandle TH1 data constructor.
147
148TCandle::TCandle(const Double_t candlePos, const Double_t candleWidth, TH1D *proj)
150{
151 //Preliminary values only, need to be calculated before paint
152 fMean = 0;
153 fMedian = 0;
154 fMedianErr = 0;
155 fBoxUp = 0;
156 fBoxDown = 0;
157 fWhiskerUp = 0;
158 fWhiskerDown = 0;
159 fNDatapoints = 0;
160 fIsCalculated = 0;
161 fIsRaw = 0;
162 fPosCandleAxis = candlePos;
163 fCandleWidth = candleWidth;
164 fHistoWidth = candleWidth;
165 fDatapoints = 0;
166 fProj = proj;
167 fDismiss = 0;
169 fLogX = 0;
170 fLogY = 0;
171 fLogZ = 0;
172 fNDrawPoints = 0;
173 fNHistoPoints = 0;
174 fAxisMin = 0.;
175 fAxisMax = 0.;
176 sprintf(fOptionStr," ");
177}
178
179////////////////////////////////////////////////////////////////////////////////
180/// TCandle default destructor.
181
183 if (fIsRaw && fProj) delete fProj;
184}
185
187{
188 return fScaledCandle;
189}
190
192{
193 return fScaledViolin;
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// Static function to set fWhiskerRange, by setting whisker-range, one can force
198/// the whiskers to cover the fraction of the distribution.
199/// Set wRange between 0 and 1. Default is 1
200/// TCandle::SetWhiskerRange(0.95) will set all candle-charts to cover 95% of
201/// the distribution with the whiskers.
202/// Can only be used with the standard-whisker definition
203
205 if (wRange < 0) fWhiskerRange = 0;
206 else if (wRange > 1) fWhiskerRange = 1;
207 else fWhiskerRange = wRange;
208
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Static function to set fBoxRange, by setting whisker-range, one can force the
213/// box of the candle-chart to cover that given fraction of the distribution.
214/// Set bRange between 0 and 1. Default is 0.5
215/// TCandle::SetBoxRange(0.68) will set all candle-charts to cover 68% of the
216/// distribution by the box
217
218void TCandle::SetBoxRange(const Double_t bRange) {
219 if (bRange < 0) fBoxRange = 0;
220 else if (bRange > 1) fBoxRange = 1;
221 else fBoxRange = bRange;
222}
223
224////////////////////////////////////////////////////////////////////////////////
225/// Static function to set scaling between candles-withs. A candle containing
226/// 100 entries with be two times wider than a candle containing 50 entries
227
229 fScaledCandle = cScale;
230}
231
232////////////////////////////////////////////////////////////////////////////////
233/// Static function to set scaling between violin-withs. A violin or histo chart
234/// with a maximum bin content to 100 will be two times as high as a violin with
235/// a maximum bin content of 50
236
238 fScaledViolin = vScale;
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// Parsing of the option-string.
243/// The option-string will be empty at the end (by-reference).
244
245int TCandle::ParseOption(char * opt) {
247 char *l;
248
249 l = strstr(opt,"CANDLE");
250 if (l) {
251 const CandleOption fallbackCandle = (CandleOption)(kBox + kMedianLine + kMeanCircle + kWhiskerAll + kAnchor);
252
253 char direction = ' ';
254 char preset = ' ';
255
256
257
258 if (l[6] >= 'A' && l[6] <= 'Z') direction = l[6];
259 if (l[6] >= '1' && l[6] <= '9') preset = l[6];
260 if (l[7] >= 'A' && l[7] <= 'Z' && preset != ' ') direction = l[7];
261 if (l[7] >= '1' && l[7] <= '9' && direction != ' ') preset = l[7];
262
263 if (direction == 'X' || direction == 'V') { /* nothing */ }
264 if (direction == 'Y' || direction == 'H') { fOption = (CandleOption)(fOption + kHorizontal); }
265 if (preset == '1') //Standard candle using old candle-definition
266 fOption = (CandleOption)(fOption + fallbackCandle);
267 else if (preset == '2') //New standard candle with better whisker definition + outlier
269 else if (preset == '3') //Like candle2 but with a fMean as a circle
271 else if (preset == '4') //Like candle3 but showing the uncertainty of the fMedian as well
273 else if (preset == '5') //Like candle2 but showing all datapoints
275 else if (preset == '6') //Like candle2 but showing all datapoints scattered
277 else if (preset != ' ') //For all other presets not implemented yet used fallback candle
278 fOption = (CandleOption)(fOption + fallbackCandle);
279
280 if (preset != ' ' && direction != ' ')
281 memcpy(l," ",8);
282 else if (preset != ' ' || direction != ' ')
283 memcpy(l," ",7);
284 else
285 memcpy(l," ",6);
286
287 Bool_t useIndivOption = false;
288
289 if (direction == ' ') direction = 'X';
290 if (preset == ' ') { // Check if the user wants to set the properties individually
291 char *brOpen = strstr(opt,"(");
292 char *brClose = strstr(opt,")");
293 char indivOption[32];
294 if (brOpen && brClose) {
295 useIndivOption = true;
296 bool isHorizontal = IsHorizontal();
297 strlcpy(indivOption, brOpen, brClose-brOpen+2); //Now the string "(....)" including brackets is in this array
298 sscanf(indivOption,"(%d)", (int*) &fOption);
299 if (isHorizontal) {fOption = (CandleOption)(fOption + kHorizontal);}
300 memcpy(brOpen," ",brClose-brOpen+1); //Cleanup
301
302 sprintf(fOptionStr,"CANDLE%c(%ld)",direction,(long)fOption);
303 } else {
304 preset = 1;
305 fOption = (CandleOption)(fOption + fallbackCandle);
306 }
307 } else {
308 sprintf(fOptionStr,"CANDLE%c%c",direction,preset);
309 }
310 //Handle option "CANDLE" ,"CANDLEX" or "CANDLEY" to behave like "CANDLEX1" or "CANDLEY1"
311 if (!useIndivOption && !fOption ) {
312 fOption = fallbackCandle;
313 sprintf(fOptionStr,"CANDLE%c2",direction);
314 }
315 }
316
317 l = strstr(opt,"VIOLIN");
318 if (l) {
320
321 char direction = ' ';
322 char preset = ' ';
323
324 if (l[6] >= 'A' && l[6] <= 'Z') direction = l[6];
325 if (l[6] >= '1' && l[6] <= '9') preset = l[6];
326 if (l[7] >= 'A' && l[7] <= 'Z' && preset != ' ') direction = l[7];
327 if (l[7] >= '1' && l[7] <= '9' && direction != ' ') preset = l[7];
328
329 if (direction == 'X' || direction == 'V') { /* nothing */ }
330 if (direction == 'Y' || direction == 'H') { fOption = (CandleOption)(fOption + kHorizontal); }
331 if (preset == '1') //Standard candle using old candle-definition
332 fOption = (CandleOption)(fOption + fallbackCandle);
333 else if (preset == '2') //New standard candle with better whisker definition + outlier
335 else if (preset != ' ') //For all other presets not implemented yet used fallback candle
336 fOption = (CandleOption)(fOption + fallbackCandle);
337
338 if (preset != ' ' && direction != ' ')
339 memcpy(l," ",8);
340 else if (preset != ' ' || direction != ' ')
341 memcpy(l," ",7);
342 else
343 memcpy(l," ",6);
344
345 Bool_t useIndivOption = false;
346
347 if (direction == ' ') direction = 'X';
348 if (preset == ' ') { // Check if the user wants to set the properties individually
349 char *brOpen = strstr(opt,"(");
350 char *brClose = strstr(opt,")");
351 char indivOption[32];
352 if (brOpen && brClose) {
353 useIndivOption = true;
354 bool isHorizontal = IsHorizontal();
355 strlcpy(indivOption, brOpen, brClose-brOpen +2); //Now the string "(....)" including brackets is in this array
356 sscanf(indivOption,"(%d)", (int*) &fOption);
357 if (isHorizontal) {fOption = (CandleOption)(fOption + kHorizontal);}
358 memcpy(brOpen," ",brClose-brOpen+1); //Cleanup
359
360 sprintf(fOptionStr,"VIOLIN%c(%ld)",direction,(long)fOption);
361
362 } else {
363 preset = 1;
364 fOption = (CandleOption)(fOption + fallbackCandle);
365 }
366 } else {
367 sprintf(fOptionStr,"VIOLIN%c%c",direction,preset);
368 }
369 //Handle option "VIOLIN" ,"VIOLINX" or "VIOLINY" to behave like "VIOLINX1" or "VIOLINY1"
370 if (!useIndivOption && !fOption ) {
371 fOption = fallbackCandle;
372 sprintf(fOptionStr,"VIOLIN%c1",direction);
373 }
374 }
375
376 fIsCalculated = false;
377
378 return fOption;
379
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Calculates all values needed by the candle definition depending on the
384/// candle options.
385
387 //Reset everything
388 fNDrawPoints = 0;
389 fNHistoPoints = 0;
390
391 Bool_t swapXY = IsOption(kHorizontal);
392 Bool_t doLogY = (!(swapXY) && fLogY) || (swapXY && fLogX);
393 Bool_t doLogX = (!(swapXY) && fLogX) || (swapXY && fLogY);
394 Bool_t doLogZ = fLogZ;
395
396 //Will be min and max values of raw-data
397 Double_t min = 1e15;
398 Double_t max = -1e15;
399
400 // Determining the quantiles
401 Double_t *prob = new Double_t[5];
402
403 if (fWhiskerRange >= 1) {
404 prob[0] = 1e-15;
405 prob[4] = 1-1e-15;
406 } else {
407 prob[0] = 0.5 - fWhiskerRange/2.;
408 prob[4] = 0.5 + fWhiskerRange/2.;
409 }
410
411
412 if (fBoxRange >= 1) {
413 prob[1] = 1E-14;
414 prob[3] = 1-1E-14;
415 } else {
416 prob[1] = 0.5 - fBoxRange/2.;
417 prob[3] = 0.5 + fBoxRange/2.;
418 }
419
420 prob[2]=0.5;
421 Double_t *quantiles = new Double_t[5];
422 quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
423 if (!fIsRaw && fProj) { //Need a calculation for a projected histo
424 if (((IsOption(kHistoLeft)) || (IsOption(kHistoRight)) || (IsOption(kHistoViolin))) && fProj->GetNbinsX() > 500) {
425 // When using the histooption the number of bins of the projection is
426 // limited because of the array space defined by kNMAXPOINTS.
427 // So the histo is rebinned, that it can be displayed at any time.
428 // Finer granularity is not useful anyhow
429 int divideBy = ((fProj->GetNbinsX() - 1)/((kNMAXPOINTS-10)/4))+1;
430 fProj->RebinX(divideBy);
431 }
432 fProj->GetQuantiles(5, quantiles, prob);
433 } else { //Need a calculation for a raw-data candle
435 }
436
437 // Check if the quantiles are valid, seems the under- and overflow is taken
438 // into account as well, we need to ignore this!
439 if (quantiles[0] >= quantiles[4] ||
440 quantiles[1] >= quantiles[3]) {
441 delete [] prob;
442 delete [] quantiles;
443 return;
444 }
445
446 // Definition of the candle in the standard case
447 fBoxUp = quantiles[3];
448 fBoxDown = quantiles[1];
449 fWhiskerUp = quantiles[4]; //Standard case
450 fWhiskerDown = quantiles[0]; //Standard case
451 fMedian = quantiles[2];
453 Int_t nOutliers = 0;
454
455 if (IsOption(kWhisker15)) { // Improved whisker definition, with 1.5*iqr
456 if (!fIsRaw && fProj) { //Need a calculation for a projected histo
457 int bin = fProj->FindBin(fBoxDown-1.5*iqr);
458 // extending only to the lowest data value within this range
459 while (fProj->GetBinContent(bin) == 0 && bin <= fProj->GetNbinsX()) bin++;
461
462 bin = fProj->FindBin(fBoxUp+1.5*iqr);
463 while (fProj->GetBinContent(bin) == 0 && bin >= 1) bin--;
465 } else { //Need a calculation for a raw-data candle
468
469 //Need to find highest value up to 1.5*iqr from the BoxUp-pos, and the lowest value up to -1.5*iqr from the boxLow-pos
470 for (Long64_t i = 0; i < fNDatapoints; ++i) {
471 Double_t myData = fDatapoints[i];
472 if (myData > fWhiskerUp && myData <= fBoxUp + 1.5*iqr) fWhiskerUp = myData;
473 if (myData < fWhiskerDown && myData >= fBoxDown - 1.5*iqr) fWhiskerDown = myData;
474 }
475 }
476 }
477
478 if (!fIsRaw && fProj) { //Need a calculation for a projected histo
479 fMean = fProj->GetMean();
480 fMedianErr = 1.57*iqr/sqrt(fProj->GetEntries());
483 } else { //Need a calculation for a raw-data candle
484 //Calculate the Mean
485 fMean = 0;
486 for (Long64_t i = 0; i < fNDatapoints; ++i) {
487 fMean += fDatapoints[i];
488 if (fDatapoints[i] < min) min = fDatapoints[i];
489 if (fDatapoints[i] > max) max = fDatapoints[i];
490 if (fDatapoints[i] < fWhiskerDown || fDatapoints[i] > fWhiskerUp) nOutliers++;
491 }
493 fMedianErr = 1.57*iqr/sqrt(fNDatapoints);
494 }
495
496 delete [] prob;
497 delete [] quantiles;
498
499 //Doing the outliers and other single points to show
500 if (GetCandleOption(5) > 0) { //Draw outliers
501 TRandom2 random;
502 const int maxOutliers = kNMAXPOINTS;
503 Double_t myScale = 1.;
504 if (!fIsRaw && fProj) { //Need a calculation for a projected histo
505 if (fProj->GetEntries() > maxOutliers/2) myScale = fProj->GetEntries()/(maxOutliers/2.);
506 fNDrawPoints = 0;
507 for (int bin = 0; bin < fProj->GetNbinsX(); bin++) {
508 // Either show them only outside the whiskers, or all of them
509 if (fProj->GetBinContent(bin) > 0 && (fProj->GetBinCenter(bin) < fWhiskerDown || fProj->GetBinCenter(bin) > fWhiskerUp || (GetCandleOption(5) > 1)) ) {
510 Double_t scaledBinContent = fProj->GetBinContent(bin)/myScale;
511 if (scaledBinContent >0 && scaledBinContent < 1) scaledBinContent = 1; //Outliers have a typical bin content between 0 and 1, when scaling they would disappear
512 for (int j=0; j < (int)scaledBinContent; j++) {
513 if (fNDrawPoints > maxOutliers) break;
514 if (IsOption(kPointsAllScat)) { //Draw outliers and "all" values scattered
517 } else { //Draw them in the "candle line"
519 if ((int)scaledBinContent == 1) //If there is only one datapoint available put it in the middle of the bin
521 else //If there is more than one datapoint scatter it along the bin, otherwise all marker would be (invisibly) stacked on top of each other
523 }
524 if (swapXY) {
525 //Swap X and Y
526 Double_t keepCurrently;
527 keepCurrently = fDrawPointsX[fNDrawPoints];
529 fDrawPointsY[fNDrawPoints] = keepCurrently;
530 }
531 // Continue fMeans, that fNDrawPoints is not increased, so that value will not be shown
532 if (doLogX) {
534 }
535 if (doLogY) {
537 }
538 fNDrawPoints++;
539 }
540 }
541 if (fNDrawPoints > maxOutliers) { //Should never happen, due to myScale!!!
542 Error ("PaintCandlePlot","Not possible to draw all outliers.");
543 break;
544 }
545 }
546 } else { //Raw data candle
547 //If only outliers are shown, calculate myScale only based on nOutliers, use fNDatapoints (all) instead
548 if (IsOption(kPointsOutliers) && nOutliers > maxOutliers/2) {
549 myScale = nOutliers/(maxOutliers/2.);
550 } else {
551 if (fNDatapoints > maxOutliers/2) myScale = fNDatapoints/(maxOutliers/2.);
552 }
553 fNDrawPoints = 0;
554 for (int i = 0; i < fNDatapoints; i++ ) {
555 Double_t myData = fDatapoints[i];
556 Double_t maxScatter = (fWhiskerUp-fWhiskerDown)/100;
557 if (!(i % (int) myScale == 0 )) continue; //If the amount of data is too large take only every 2nd or 3rd to reduce the amount
558 // Either show them only outside the whiskers, or all of them
559 if (myData < fWhiskerDown || myData > fWhiskerUp || (GetCandleOption(5) > 1)) {
560 if (IsOption(kPointsAllScat)) { //Draw outliers and "all" values scattered
562 fDrawPointsY[fNDrawPoints] = myData + (random.Rndm() - 0.5)*maxScatter; //random +- 0.5 of candle-height
563 } else { //Draw them in the "candle line"
565 fDrawPointsY[fNDrawPoints] = myData + (random.Rndm() - 0.5)*maxScatter; //random +- 0.5 of candle-height
566 }
567 if (swapXY) {
568 //Swap X and Y
569 Double_t keepCurrently;
570 keepCurrently = fDrawPointsX[fNDrawPoints];
572 fDrawPointsY[fNDrawPoints] = keepCurrently;
573 }
574 // Continue fMeans, that fNDrawPoints is not increased, so that value will not be shown
575 if (doLogX) {
577 else continue;
578 }
579 if (doLogY) {
581 else continue;
582 }
583 fNDrawPoints++;
584 if (fNDrawPoints > maxOutliers) { //Should never happen, due to myScale!!!
585 Error ("PaintCandlePlotRaw","Not possible to draw all outliers.");
586 break;
587 }
588 }
589 }
590 }
591 }
593 //We are starting with kHistoRight, left will be modified from right later
594 if (fIsRaw) { //This is a raw-data candle
595 if (!fProj) {
596 fProj = new TH1D("hpa","hpa",100,min,max+0.0001*(max-min));
597 for (Long64_t i = 0; i < fNDatapoints; ++i) {
599 }
600 }
601 }
602
603 fNHistoPoints = 0;
604 Double_t maxContent = fProj->GetMaximum();
605 Double_t maxHistoHeight = fHistoWidth;
606 if (IsOption(kHistoViolin)) maxHistoHeight *= 0.5;
607
608 bool isFirst = true;
609 int lastNonZero = 0;
610 for (int bin = 1; bin <= fProj->GetNbinsX(); bin++) {
611 if (isFirst) {
612 if (fProj->GetBinContent(bin) > 0) {
615 if (doLogX) {
617 }
618 if (doLogY) {
620 }
622 isFirst = false;
623 } else {
624 continue;
625 }
626 }
627
628 Double_t myBinValue = fProj->GetBinContent(bin);
629 if (doLogZ) {
630 if (myBinValue > 0) myBinValue = TMath::Log10(myBinValue); else myBinValue = 0;
631 }
632 fHistoPointsX[fNHistoPoints] = fPosCandleAxis + myBinValue/maxContent*maxHistoHeight;
635 fHistoPointsX[fNHistoPoints] = fPosCandleAxis + myBinValue/maxContent*maxHistoHeight;
637 if (doLogX) {
640 }
641 if (doLogY) {
644 }
645
647 if (fProj->GetBinContent(bin) > 0) lastNonZero = fNHistoPoints;
648 }
649
652 fNHistoPoints = lastNonZero+1; //+1 so that the line down to 0 is added as well
653
654 if (IsOption(kHistoLeft)) {
655 for (int i = 0; i < fNHistoPoints; i++) {
657 }
658 }
659 if (IsOption(kHistoViolin)) {
660 for (int i = 0; i < fNHistoPoints; i++) {
663 }
664 fNHistoPoints *= 2;
665 }
666 }
667
668
669 fIsCalculated = true;
670}
671
672////////////////////////////////////////////////////////////////////////////////
673/// Paint one candle with its current attributes.
674
676{
677 //If something was changed before, we need to recalculate some values
678 if (!fIsCalculated) Calculate();
679
680 // Save the attributes as they were set originally
681 Style_t saveLine = GetLineStyle();
682 Style_t saveMarker = GetMarkerStyle();
683 Style_t saveFillStyle = GetFillStyle();
684 Style_t saveFillColor = GetFillColor();
685 Style_t saveLineColor = GetLineColor();
686
688 Double_t dimRight = fPosCandleAxis+0.5*fCandleWidth;
689
693
694 Bool_t swapXY = IsOption(kHorizontal);
695 Bool_t doLogY = (!(swapXY) && fLogY) || (swapXY && fLogX);
696 Bool_t doLogX = (!(swapXY) && fLogX) || (swapXY && fLogY);
697
698 // From now on this is real painting only, no calculations anymore
699
701 SetLineColor(saveFillColor);
704 SetLineColor(saveLineColor);
706 }
707
708
710 if (IsOption(kHistoZeroIndicator) && (saveFillStyle != 0)) {
711 SetLineColor(saveFillColor);
713 }
714 if (!swapXY) {
717 } else {
720 }
721 if (IsOption(kHistoZeroIndicator) && (saveFillStyle != 0)) {
722 SetLineColor(saveLineColor);
724 }
725 }
726
727 if (IsOption(kBox)) { // Draw a simple box
728 if (IsOption(kMedianNotched)) { // Check if we have to draw a box with notches
729 Double_t x[] = {dimLeft, dimLeft, dimLeft+fCandleWidth/3., dimLeft, dimLeft, dimRight,
730 dimRight, dimRight-fCandleWidth/3., dimRight, dimRight, dimLeft};
733 PaintBox(11, x, y, swapXY);
734 } else { // draw a simple box
735 Double_t x[] = {dimLeft, dimLeft, dimRight, dimRight, dimLeft};
737 PaintBox(5, x, y, swapXY);
738 }
739 }
740
741 if (IsOption(kAnchor)) { // Draw the anchor line
742 PaintLine(dimLeft, fWhiskerUp, dimRight, fWhiskerUp, swapXY);
743 PaintLine(dimLeft, fWhiskerDown, dimRight, fWhiskerDown, swapXY);
744 }
745
746 if (IsOption(kWhiskerAll) && !IsOption(kHistoZeroIndicator)) { // Whiskers are dashed
747 SetLineStyle(2);
751 SetLineStyle(saveLine);
753 } else if ((IsOption(kWhiskerAll) && IsOption(kHistoZeroIndicator)) || IsOption(kWhisker15) ) { // Whiskers without dashing, better whisker definition, or forced when using zero line
756 }
757
758 if (IsOption(kMedianLine)) { // Paint fMedian as a line
759 PaintLine(dimLeft, fMedian, dimRight, fMedian, swapXY);
760 } else if (IsOption(kMedianNotched)) { // Paint fMedian as a line (using notches, fMedian line is shorter)
761 PaintLine(dimLeft+fCandleWidth/3, fMedian, dimRight-fCandleWidth/3., fMedian, swapXY);
762 } else if (IsOption(kMedianCircle)) { // Paint fMedian circle
763 Double_t myMedianX[1], myMedianY[1];
764 if (!swapXY) {
765 myMedianX[0] = fPosCandleAxis;
766 myMedianY[0] = fMedian;
767 } else {
768 myMedianX[0] = fMedian;
769 myMedianY[0] = fPosCandleAxis;
770 }
771
772 Bool_t isValid = true;
773 if (doLogX) {
774 if (myMedianX[0] > 0) myMedianX[0] = TMath::Log10(myMedianX[0]); else isValid = false;
775 }
776 if (doLogY) {
777 if (myMedianY[0] > 0) myMedianY[0] = TMath::Log10(myMedianY[0]); else isValid = false;
778 }
779
780 SetMarkerStyle(24);
782
783 if (isValid) gPad->PaintPolyMarker(1,myMedianX,myMedianY); // A circle for the fMedian
784
785 SetMarkerStyle(saveMarker);
787
788 }
789
790 if (IsOption(kMeanCircle)) { // Paint fMean as a circle
791 Double_t myMeanX[1], myMeanY[1];
792 if (!swapXY) {
793 myMeanX[0] = fPosCandleAxis;
794 myMeanY[0] = fMean;
795 } else {
796 myMeanX[0] = fMean;
797 myMeanY[0] = fPosCandleAxis;
798 }
799
800 Bool_t isValid = true;
801 if (doLogX) {
802 if (myMeanX[0] > 0) myMeanX[0] = TMath::Log10(myMeanX[0]); else isValid = false;
803 }
804 if (doLogY) {
805 if (myMeanY[0] > 0) myMeanY[0] = TMath::Log10(myMeanY[0]); else isValid = false;
806 }
807
808 SetMarkerStyle(24);
810
811 if (isValid) gPad->PaintPolyMarker(1,myMeanX,myMeanY); // A circle for the fMean
812
813 SetMarkerStyle(saveMarker);
815
816 } else if (IsOption(kMeanLine)) { // Paint fMean as a dashed line
817 SetLineStyle(2);
819
820 PaintLine(dimLeft, fMean, dimRight, fMean, swapXY);
821 SetLineStyle(saveLine);
823
824 }
825
826 if (IsOption(kAnchor)) { //Draw standard anchor
827 PaintLine(dimLeft, fWhiskerDown, dimRight, fWhiskerDown, swapXY); // the lower anchor line
828 PaintLine(dimLeft, fWhiskerUp, dimRight, fWhiskerUp, swapXY); // the upper anchor line
829 }
830
831 // This is a bit complex. All values here are handled as outliers. Usually
832 // only the datapoints outside the whiskers are shown.
833 // One can show them in one row as crosses, or scattered randomly. If activated
834 // all datapoint are shown in the same way
835
836 if (GetCandleOption(5) > 0) { //Draw outliers
837 if (IsOption(kPointsAllScat)) { //Draw outliers and "all" values scattered
839 } else {
841 }
843 gPad->PaintPolyMarker(fNDrawPoints,fDrawPointsX, fDrawPointsY);
844 }
845}
846
847////////////////////////////////////////////////////////////////////////////////
848/// Return true is this option is activated in fOption
849
851 long myOpt = 9;
852 int pos = 0;
853 for (pos = 0; pos < 16; pos++) {
854 if (myOpt > opt) break;
855 else myOpt *=10;
856 }
857 myOpt /= 9;
858 int thisOpt = GetCandleOption(pos);
859
860 return ((thisOpt * myOpt) == opt);
861}
862
863////////////////////////////////////////////////////////////////////////////////
864/// Paint a box for candle.
865
867{
868 Bool_t doLogY = (!(swapXY) && fLogY) || (swapXY && fLogX);
869 Bool_t doLogX = (!(swapXY) && fLogX) || (swapXY && fLogY);
870 if (doLogY) {
871 for (int i=0; i<nPoints; i++) {
872 if (y[i] > 0) y[i] = TMath::Log10(y[i]);
873 else return;
874 }
875 }
876 if (doLogX) {
877 for (int i=0; i<nPoints; i++) {
878 if (x[i] > 0) x[i] = TMath::Log10(x[i]);
879 else return;
880 }
881 }
882 if (!swapXY) {
883 gPad->PaintFillArea(nPoints, x, y);
884 gPad->PaintPolyLine(nPoints, x, y);
885 } else {
886 gPad->PaintFillArea(nPoints, y, x);
887 gPad->PaintPolyLine(nPoints, y, x);
888 }
889}
890
891////////////////////////////////////////////////////////////////////////////////
892/// Paint a line for candle.
893
895{
896 Bool_t doLogY = (!(swapXY) && fLogY) || (swapXY && fLogX);
897 Bool_t doLogX = (!(swapXY) && fLogX) || (swapXY && fLogY);
898 if (doLogY) {
899 if (y1 > 0) y1 = TMath::Log10(y1); else return;
900 if (y2 > 0) y2 = TMath::Log10(y2); else return;
901 }
902 if (doLogX) {
903 if (x1 > 0) x1 = TMath::Log10(x1); else return;
904 if (x2 > 0) x2 = TMath::Log10(x2); else return;
905 }
906 if (!swapXY) {
907 gPad->PaintLine(x1, y1, x2, y2);
908 } else {
909 gPad->PaintLine(y1, x1, y2, x2);
910 }
911}
912
913////////////////////////////////////////////////////////////////////////////////
914/// Stream an object of class TCandle.
915
916void TCandle::Streamer(TBuffer &R__b)
917{
918 if (R__b.IsReading()) {
919 UInt_t R__s, R__c;
920 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
921 if (R__v > 3) {
922 R__b.ReadClassBuffer(TCandle::Class(), this, R__v, R__s, R__c);
923 return;
924 }
925 } else {
926 R__b.WriteClassBuffer(TCandle::Class(),this);
927 }
928}
929
930////////////////////////////////////////////////////////////////////////////////
931/// The coordinates in the TParallelCoordVar-class are in Pad-Coordinates, so we need to convert them
932
933void TCandle::ConvertToPadCoords(Double_t minAxis, Double_t maxAxis, Double_t axisMinCoord, Double_t axisMaxCoord)
934{
935 if (!fIsCalculated) Calculate();
936 Double_t a,b;
937 if (fLogY) {
938 a = TMath::Log10(minAxis);
939 b = TMath::Log10(maxAxis/minAxis);
940 } else {
941 a = minAxis;
942 b = maxAxis-minAxis;
943 }
944
945 fMean = axisMinCoord + ((fMean-a)/b)*(axisMaxCoord-axisMinCoord);
946 fMedian = axisMinCoord + ((fMedian-a)/b)*(axisMaxCoord-axisMinCoord);
947 fMedianErr = axisMinCoord + ((fMedianErr-a)/b)*(axisMaxCoord-axisMinCoord);
948 fBoxUp = axisMinCoord + ((fBoxUp-a)/b)*(axisMaxCoord-axisMinCoord);
949 fBoxDown = axisMinCoord + ((fBoxDown-a)/b)*(axisMaxCoord-axisMinCoord);
950 fWhiskerUp = axisMinCoord + ((fWhiskerUp-a)/b)*(axisMaxCoord-axisMinCoord);
951 fWhiskerDown = axisMinCoord + ((fWhiskerDown-a)/b)*(axisMaxCoord-axisMinCoord);
952
953 for (int i = 0; i < fNDrawPoints; i++) {
954 fDrawPointsY[i] = axisMinCoord + ((fDrawPointsY[i]-a)/b)*(axisMaxCoord-axisMinCoord);
955 }
956 for (int i = 0; i < fNHistoPoints; i++) {
957 fHistoPointsY[i] = axisMinCoord + ((fHistoPointsY[i]-a)/b)*(axisMaxCoord-axisMinCoord);
958 }
959}
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
static const double x2[5]
static const double x1[5]
short Version_t
Definition RtypesCore.h:65
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:92
bool Bool_t
Definition RtypesCore.h:63
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:73
short Style_t
Definition RtypesCore.h:80
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
const Int_t kNMAXPOINTS
Definition TCandle.h:24
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
double sqrt(double)
#define gPad
point * points
Definition X3DBuffer.c:22
Fill Area Attributes class.
Definition TAttFill.h:19
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void Modify()
Change current fill area attributes if necessary.
Definition TAttFill.cxx:211
Line Attributes class.
Definition TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:34
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:242
Marker Attributes class.
Definition TAttMarker.h:19
virtual void Modify()
Change current marker attributes if necessary.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
Double_t GetXmax() const
Definition TAxis.h:134
Double_t GetXmin() const
Definition TAxis.h:133
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
The candle plot painter class.
Definition TCandle.h:26
Double_t fMedian
Position of the median.
Definition TCandle.h:63
static Double_t fBoxRange
The fraction which is covered by the box (0 < x < 1), default 0.5.
Definition TCandle.h:91
CandleOption
Definition TCandle.h:29
@ kHorizontal
If this bit is not set it is vertical.
Definition TCandle.h:47
@ kAnchor
Definition TCandle.h:39
@ kWhiskerAll
Definition TCandle.h:37
@ kMeanCircle
Definition TCandle.h:36
@ kHistoZeroIndicator
Definition TCandle.h:46
@ kPointsAllScat
Definition TCandle.h:42
@ kNoOption
Definition TCandle.h:30
@ kHistoRight
Definition TCandle.h:44
@ kMeanLine
Definition TCandle.h:35
@ kBox
Definition TCandle.h:31
@ kWhisker15
Definition TCandle.h:38
@ kMedianLine
Definition TCandle.h:32
@ kPointsAll
Definition TCandle.h:41
@ kPointsOutliers
Definition TCandle.h:40
@ kMedianNotched
Definition TCandle.h:33
@ kHistoLeft
Definition TCandle.h:43
@ kMedianCircle
Definition TCandle.h:34
@ kHistoViolin
Definition TCandle.h:45
TH1D * fProj
Definition TCandle.h:55
static void SetScaledViolin(const Bool_t vScale=true)
Static function to set scaling between violin-withs.
Definition TCandle.cxx:237
bool fIsRaw
0: for TH1 projection, 1: using raw data
Definition TCandle.h:53
static Double_t fWhiskerRange
The fraction which is covered by the whiskers (0 < x < 1), default 1.
Definition TCandle.h:90
CandleOption fOption
Setting the style of the candle.
Definition TCandle.h:81
Double_t fAxisMax
The Maximum which is visible by the axis (used by zero indicator)
Definition TCandle.h:88
int fLogZ
make the candle appear logz-like
Definition TCandle.h:85
bool IsOption(CandleOption opt)
Return true is this option is activated in fOption.
Definition TCandle.cxx:850
Double_t fPosCandleAxis
x-pos for a vertical candle
Definition TCandle.h:58
int fNHistoPoints
Definition TCandle.h:79
Double_t fMean
Position of the mean.
Definition TCandle.h:62
Double_t fWhiskerDown
Position of the lower whisker end.
Definition TCandle.h:68
Long64_t fNDrawPoints
max number of outliers or other point to be shown
Definition TCandle.h:75
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition TCandle.cxx:675
Double_t fAxisMin
The Minimum which is visible by the axis (used by zero indicator)
Definition TCandle.h:87
void ConvertToPadCoords(Double_t minAxis, Double_t maxAxis, Double_t axisMinCoord, Double_t axisMaxCoord)
The coordinates in the TParallelCoordVar-class are in Pad-Coordinates, so we need to convert them.
Definition TCandle.cxx:933
Double_t fDrawPointsY[kNMAXPOINTS]
y-coord for every outlier, ..
Definition TCandle.h:74
Bool_t IsViolinScaled()
Definition TCandle.cxx:191
Long64_t fNDatapoints
Number of Datapoints within this candle.
Definition TCandle.h:71
Double_t fHistoPointsY[kNMAXPOINTS]
y-coord for the polyline of the histo
Definition TCandle.h:78
Bool_t IsHorizontal()
Definition TCandle.h:117
Double_t fHistoPointsX[kNMAXPOINTS]
x-coord for the polyline of the histo
Definition TCandle.h:77
static void SetScaledCandle(const Bool_t cScale=true)
Static function to set scaling between candles-withs.
Definition TCandle.cxx:228
Double_t * fDatapoints
position of all Datapoints within this candle
Definition TCandle.h:70
int ParseOption(char *optin)
Parsing of the option-string.
Definition TCandle.cxx:245
bool fDismiss
True if the candle cannot be painted.
Definition TCandle.h:56
Double_t fWhiskerUp
Position of the upper whisker end.
Definition TCandle.h:67
static void SetBoxRange(const Double_t bRange)
Static function to set fBoxRange, by setting whisker-range, one can force the box of the candle-chart...
Definition TCandle.cxx:218
static Bool_t fScaledViolin
shall the violin or histos be scaled to each other by the maximum height?
Definition TCandle.h:94
int fLogY
make the candle appear logy-like
Definition TCandle.h:84
Double_t fMedianErr
The size of the notch.
Definition TCandle.h:64
void PaintBox(Int_t nPoints, Double_t *x, Double_t *y, Bool_t swapXY)
Paint a box for candle.
Definition TCandle.cxx:866
Double_t fBoxUp
Position of the upper box end.
Definition TCandle.h:65
virtual ~TCandle()
TCandle default destructor.
Definition TCandle.cxx:182
int fLogX
make the candle appear logx-like
Definition TCandle.h:83
Double_t fDrawPointsX[kNMAXPOINTS]
x-coord for every outlier, ..
Definition TCandle.h:73
TCandle()
TCandle default constructor.
Definition TCandle.cxx:42
Double_t fBoxDown
Position of the lower box end.
Definition TCandle.h:66
void Calculate()
Calculates all values needed by the candle definition depending on the candle options.
Definition TCandle.cxx:386
void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Bool_t swapXY)
Paint a line for candle.
Definition TCandle.cxx:894
Bool_t IsCandleScaled()
Definition TCandle.cxx:186
Double_t fHistoWidth
The histo width (the height of the max bin)
Definition TCandle.h:60
int GetCandleOption(const int pos)
Definition TCandle.h:98
bool fIsCalculated
Definition TCandle.h:54
static void SetWhiskerRange(const Double_t wRange)
Static function to set fWhiskerRange, by setting whisker-range, one can force the whiskers to cover t...
Definition TCandle.cxx:204
static Bool_t fScaledCandle
shall the box-width be scaled to each other by the integral of a box?
Definition TCandle.h:93
char fOptionStr[128]
String to draw the candle.
Definition TCandle.h:82
Double_t fCandleWidth
The candle width.
Definition TCandle.h:59
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:618
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:8981
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=0)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition TH1.cxx:4543
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition TH1.cxx:7428
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition TH1.h:320
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition TH1.cxx:8390
virtual Int_t GetNbinsX() const
Definition TH1.h:296
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3350
virtual TH1 * RebinX(Int_t ngroup=2, const char *newname="")
Definition TH1.h:350
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:8992
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4386
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:4993
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9003
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3680
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition TRandom2.h:27
virtual Double_t Rndm()
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition TRandom2.cxx:56
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, Bool_t isSorted=kTRUE, Int_t *index=0, Int_t type=7)
Computes sample quantiles, corresponding to the given probabilities.
Definition TMath.cxx:1183
Double_t Log10(Double_t x)
Definition TMath.h:764
auto * l
Definition textangle.C:4