Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TParallelCoordVar.cxx
Go to the documentation of this file.
1// @(#)root/treeviewer:$Id$
2// Author: Bastien Dalla Piazza 02/08/2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, 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 "TParallelCoordVar.h"
13#include "TParallelCoord.h"
14#include "TParallelCoordRange.h"
15
16#include "TLatex.h"
17#include "TLine.h"
18#include "TVirtualPad.h"
19#include "TMath.h"
20#include "TH1.h"
21#include "TStyle.h"
22#include "TBox.h"
23#include "TCollection.h"
24#include "TList.h"
25#include "TFrame.h"
26#include "TCanvas.h"
27#include "TMarker.h"
28
29#include <cstdio>
30#include <iostream>
31
32/** \class TParallelCoordVar
33
34TParallelCoord axes. Class containing a variable for the TParallelCoord.
35
36Options can be defined each axis separately using the right mouse click. These
37options can be applied to every axes using the editor.
38
39 - Axis width: If set to 0, the axis is simply a line. If higher, a color
40 histogram is drawn on the axis.
41 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
42
43The order in which the variables are drawn is essential to see the clusters. The
44axes can be dragged to change their position. A zoom is also available. The
45logarithm scale is also available by right clicking on the axis.
46*/
47
48////////////////////////////////////////////////////////////////////////////////
49/// Default constructor.
50
56
57////////////////////////////////////////////////////////////////////////////////
58///Destructor.
59
61{
62 if (fHistogram) delete fHistogram;
63 if (fRanges){
64 TIter next(fRanges);
66 while((range = (TParallelCoordRange*)next())) fParallel->CleanUpSelections(range);
67 fRanges->Delete();
68 delete fRanges;
69 }
70 if (fVal) delete [] fVal;
71}
72
73////////////////////////////////////////////////////////////////////////////////
74/// Normal constructor. By default, the title and the name are the expression
75/// given to TTree::Draw. The name can be changed by the user (the label on the
76/// plot) but not the title.
77
79 :TNamed(title,title), TAttLine(1,1,1), TAttFill(kOrange+9,3001)
80{
81 Init();
82 fId = id;
83 fParallel = parallel;
84 fRanges = new TList();
86
88
89 for(Long64_t ui = 0;ui<fParallel->GetNentries();++ui) fVal[ui]=val[ui];
90
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Add a range to the current selection on the axis.
98
100{
101 if (!range) {
103 if (select) {
104 range = new TParallelCoordRange(this,0,0,select);
105 fRanges->Add(range);
106 range->GetSelection()->Add(range);
107 } else {
108 Error("AddRange","You must create a selection before adding ranges.");
109 }
110 } else {
111 fRanges->Add(range);
112 range->GetSelection()->Add(range);
113 }
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Delete variables.
118
120{
122 delete this;
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Computes the distance from the axis.
127
129{
130 if(!gPad) return 9999;
131 Double_t xx = gPad->AbsPixeltoX(px);
132 Double_t yy = gPad->AbsPixeltoY(py);
133 Double_t dist = 9999;
134
135 if (fX1==fX2) {
136 if (yy>fY1+0.01 && yy<fY2-0.01) dist = TMath::Abs(xx - fX1);
137 } else {
138 if (xx>fX1+0.01 && xx<fX2-0.01) dist = TMath::Abs(yy - fY1);
139 }
140 if (dist<=0.005) return 0;
141 else return 9999;
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Draw the axis.
146
151
152////////////////////////////////////////////////////////////////////////////////
153/// Check if the entry is within the range(s) of "select". Two ranges on a
154/// single axis are conjugated as a "or": to be selected, the entry must be in
155/// one of the ranges.
156
158{
159 if (fRanges->GetSize() > 0){
160 TIter next(fRanges);
161 bool inarange = false;
162 bool noOwnedRange = true;
163 TParallelCoordRange *range;
164 while ((range = (TParallelCoordRange*)next())){
165 if(select->Contains(range)) {
166 noOwnedRange = false;
167 if(range->IsIn(fVal[evtidx])) inarange = true;
168 }
169 }
170 if (noOwnedRange) return true;
171 else return inarange;
172 }
173 else return true;
174}
175
177 public:
180
182 {
183 Double_t valx = parent.AbsPixeltoX(px);
184 Double_t valy = parent.AbsPixeltoY(py);
185 if (first)
186 zooming = vertical ? (valx > x1) : (valy > y1);
187
188 if (zooming) {
189 pzoom2 = vertical ? valy : valx;
190 if (first)
191 pzoom1 = pzoom2;
192 } else {
193 pmove = vertical ? valx : valy;
194 }
195 }
196
198 {
199 Double_t xx[4], yy[4];
200
201 if (!zooming && vertical) {
202 xx[0] = xx[1] = pmove;
203 yy[0] = y1; yy[1] = y2;
204 } else if (!zooming && !vertical) {
205 xx[0] = x1; xx[1] = x2;
206 yy[0] = yy[1] = pmove;
207 } else if (zooming && vertical) {
208 xx[0] = xx[2] = x1 - 0.05;
209 xx[1] = xx[3] = x1 + 0.05;
210 yy[0] = yy[1] = pzoom1;
211 yy[2] = yy[3] = pzoom2;
212 } else {
213 xx[0] = xx[1] = pzoom1;
214 xx[2] = xx[3] = pzoom2;
215 yy[0] = yy[2] = y1 - 0.05;
216 yy[1] = yy[3] = y1 + 0.05;
217
218 }
219 parent.PaintPolyLine(2, xx, yy, "iparallelvar1");
220 if (zooming)
221 parent.PaintPolyLine(2, xx+2, yy+2, "iparallelvar2");
222 parent.UpdateAsync();
223 }
224
225};
226
227////////////////////////////////////////////////////////////////////////////////
228/// Execute the corresponding entry.
229
231{
232 if (!gPad)
233 return;
234
235 auto &parent = *gPad;
236
237 if (!parent.IsEditable() && entry != kMouseEnter)
238 return;
239
240 if (GetVert()) {
241 if (parent.AbsPixeltoX(px) - fX1 > 0)
242 parent.SetCursor(kArrowVer);
243 else
244 parent.SetCursor(kArrowHor);
245 } else {
246 if (parent.AbsPixeltoY(py) - fY1 > 0)
247 parent.SetCursor(kArrowHor);
248 else
249 parent.SetCursor(kArrowVer);
250 }
251
252 auto inter = dynamic_cast<TParallelCoordVarInteractive *> (parent.Interactive(this));
253
254 switch (entry) {
255 case kButton1Down:
256 inter = new TParallelCoordVarInteractive();
257 parent.Interactive(this, inter);
258 inter->vertical = GetVert();
259 parent.GetCanvas()->Selected(&parent, fParallel, 1);
260 // no break
261 case kButton1Motion:
262 if (inter) {
263 inter->HandleMouse(parent, fX1, fY1, px, py, entry == kButton1Down);
264 inter->Paint(parent, fX1, fY1, fX2, fY2);
265 }
266 break;
267 case kButton1Up: {
268 if (inter && inter->zooming) {
269 Double_t min, max;
270 if (GetVert()) {
271 min = GetValuefromXY(fX1, inter->pzoom1);
272 max = GetValuefromXY(fX1, inter->pzoom2);
273 } else {
274 min = GetValuefromXY(inter->pzoom1, fY1);
275 max = GetValuefromXY(inter->pzoom2, fY1);
276 }
277
278 if (min > max)
279 std::swap(min, max);
280
284 } else {
285 SetCurrentLimits(min,max);
286 }
287 } else if (inter && !inter->zooming) {
288 TFrame *frame = parent.GetFrame();
289 Double_t pos = 0;
290 if (GetVert()) {
291 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
292 pos = (inter->pmove - frame->GetX1()) / axisSpace;
293 } else {
294 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
295 pos = (inter->pmove - frame->GetY1()) / axisSpace;
296 }
297 Int_t n = pos < 0 ? -1 : (Int_t) pos;
298 if (n >= 0 && (UInt_t)n >= fParallel->GetNvar())
299 --n;
300 else if (n < fParallel->GetVarList()->IndexOf(this))
301 ++n;
302 fParallel->GetVarList()->Remove(this);
303 fParallel->GetVarList()->AddAt(this, n);
304 }
305
306 parent.Modified();
307 parent.Interactive();
308 break;
309 }
310 }
311}
312
313////////////////////////////////////////////////////////////////////////////////
314/// Get the position of the variable on the graph for the n'th entry.
315
317{
318 if(fX1==fX2){
319 x = fX1;
320 if (fMinCurrent != fMaxCurrent) {
321 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
323 else y = fY1 + (fY2 - fY1) *
325 } else {
326 y = fY1 + 0.5*(fY2-fY1);
327 }
328 } else {
329 y = fY1;
330 if (fMinCurrent != fMaxCurrent) {
331 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
333 else x = fX1 + (fX2 - fX1) *
335 } else {
336 x = fX1 + 0.5*(fX2-fX1);
337 }
338 }
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// Get the entry weight: The weight of an entry for a given variable
343/// is the bin content of the histogram bin the entry is going through.
344
350
351////////////////////////////////////////////////////////////////////////////////
352/// Create or recreate the histogram.
353
355{
356 if (fHistogram) delete fHistogram;
357 fHistogram = nullptr;
358 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
359 fHistogram->SetDirectory(nullptr);
362 for(Long64_t li=first; li<first+nentries;++li) {
363 if(fVal[li] >= fMinCurrent && fVal[li] <= fMaxCurrent) fHistogram->Fill(fVal[li]);
364 }
365 return fHistogram;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Get mean, min and max of those variable.
370
372{
373 Double_t min,max,ave = 0;
374 min = DBL_MAX;
375 max = -DBL_MAX;
376 Long64_t first,nentries;
377 first = fParallel->GetCurrentFirst();
379 for(Long64_t li=first; li<first+nentries;++li){
380 if(fVal[li]<min) min = fVal[li];
381 if(fVal[li]>max) max = fVal[li];
382 ave+=fVal[li];
383 }
384
385 fMean = ave/((Double_t)nentries);
386 fMinCurrent = fMinInit = min;
387 fMaxCurrent = fMaxInit = max;
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Returns info about this axis.
392
394{
395 static char info[128];
396 info[0] = 0;
397
398 if (!gPad) return info;
399 Double_t xx = gPad->AbsPixeltoX(px);
400 Double_t yy = gPad->AbsPixeltoY(py);
401 if (fX1 == fX2) {
402 if (yy<fY1) {
403 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
404 } else if (yy>fY2) {
405 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
406 } else {
407 Double_t axislength = fY2-fY1;
408 Double_t pos = (yy-fY1)/axislength;
409 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent + pos*(fMaxCurrent-fMinCurrent));
410 }
411 } else {
412 if (xx<fX1) {
413 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
414 } else if(xx>fX2) {
415 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
416 } else {
417 Double_t axislength = fX2-fX1;
418 Double_t pos = (xx-fX1)/axislength;
419 snprintf(info,128,"%s = %f", GetTitle(), pos*(fMaxCurrent-fMinCurrent));
420 }
421 }
422 return info;
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Get the box plot values (quantiles).
427
429{
430 Double_t *quantiles = new Double_t[3];
431 quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.;
432 Double_t *prob = new Double_t[3];
433 prob[0]=0.25; prob[1]=0.5; prob[2] = 0.75;
436 if (!TestBit(kLogScale) && first==0 && nentries==fNentries) TMath::Quantiles(fNentries,3,fVal,quantiles,prob,false);
437 else {
438 Double_t* val = new Double_t[nentries];
439 Int_t selected = 0;
440 if(fMinInit<=0) {
441 for (Long64_t n=first;n<first+nentries;++n) {
442 if (fVal[n] >= fMinCurrent) {
443 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
444 else val[selected] = fVal[n];
445 ++selected;
446 }
447 }
448 } else {
449 for (Long64_t n=first;n<first+nentries;++n) {
450 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
451 else val[selected] = fVal[n];
452 ++selected;
453 }
454 }
455 TMath::Quantiles(selected,3,val,quantiles,prob,false);
456 delete [] val;
457 }
458 fQua1 = quantiles[0];
459 fMed = quantiles[1];
460 fQua3 = quantiles[2];
461 delete [] quantiles;
462 delete [] prob;
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// Get the value corresponding to the position.
467
469{
470 Double_t pos;
471 if (fMinCurrent == fMaxCurrent) return fMinCurrent;
472 if (fX1 == fX2) {
473 if (y<=fY1) pos = fMinCurrent;
474 else if (y>=fY2) pos = fMaxCurrent;
475 else pos = fMinCurrent + ((y-fY1)/(fY2-fY1))*(fMaxCurrent-fMinCurrent);
476 } else {
477 if (x<=fX1) pos = fMinCurrent;
478 else if (x>=fX2) pos = fMaxCurrent;
479 else pos = fMinCurrent + ((x-fX1)/(fX2-fX1))*(fMaxCurrent-fMinCurrent);
480 }
481 return pos;
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// Tells if the axis is vertical or not.
486
488{
489 return fX1 == fX2;
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// Get a position corresponding to the value on the axis.
494
496{
497 if(value < fMinCurrent || value > fMaxCurrent) return;
498
499 if (fX1==fX2) {
500 x = fX1;
501 if (fMinCurrent != fMaxCurrent) {
502 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
504 else y = fY1 + (fY2 - fY1) *
506 } else {
507 y = fY1 + 0.5*(fY2-fY1);
508 }
509 } else {
510 y = fY1;
511 if (fMinCurrent != fMaxCurrent) {
512 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
514 else x = fX1 + (fX2 - fX1) *
516 } else {
517 x = fX1 + 0.5*(fX2-fX1);
518 }
519 }
520}
521
522////////////////////////////////////////////////////////////////////////////////
523/// Initialise the TParallelVar variables.
524
526{
527 fX1 = 0;
528 fX2 = 0;
529 fY1 = 0;
530 fY2 = 0;
531 fId = 0;
532 fVal = nullptr;
533 fMean = 0;
534 fMinInit = 0;
535 fMinCurrent = 0;
536 fMaxInit = 0;
537 fMaxCurrent = 0;
538 fMed = 0;
539 fQua1 = 0;
540 fQua3 = 0;
541 fNentries = 0;
542 fParallel = nullptr;
543 fHistogram = nullptr;
544 fNbins = 100;
545 fHistoLW = 2;
546 fHistoHeight = 0.5;
547 fRanges = nullptr;
548 SetBit(kLogScale,false);
549 SetBit(kShowBox,false);
550 SetBit(kShowBarHisto,true);
551}
552
553////////////////////////////////////////////////////////////////////////////////
554/// Paint the axis.
555
557{
558 TIter next(fRanges);
559 TParallelCoordRange* range;
560 while ((range = (TParallelCoordRange*)next())) range->Paint(option);
561
564 PaintLabels();
565}
566
567////////////////////////////////////////////////////////////////////////////////
568/// Paint the boxes in the case of a candle chart.
569
571{
572 TLine *line = new TLine();
574 line->SetLineWidth(1);
575 TBox *box = new TBox();
576 box->SetLineWidth(1);
577 box->SetLineColor(GetLineColor());
578 box->SetLineStyle(1);
579 box->SetFillStyle(0);
580
581 TFrame* frame = gPad->GetFrame();
582
583 Double_t boxSize;
584 if (fParallel->GetNvar() > 1) {
585 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
586 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
587 if (boxSize >= 0.03) boxSize = 0.03;
588 }
589 else boxSize = 0.03;
590
591 Double_t qua1,med,qua3,max,min;
592 Double_t a,b,maxinit,mininit;
593 if (TestBit(kLogScale)) {
596 if(fMinInit > 0) mininit = TMath::Log10(fMinInit);
597 else mininit = TMath::Log10(fMinCurrent);
598 maxinit = TMath::Log10(fMaxInit);
599 } else {
600 a = fMinCurrent;
602 mininit = fMinInit;
603 maxinit = fMaxInit;
604 }
605 if(fX1==fX2) {
606 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
607 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
608 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
609 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
610 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
611 } else {
612 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
613 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
614 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
615 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
616 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
617 }
618
619 // min and max lines.
620 if (fX1==fX2) {
621 line->PaintLine(fX1-boxSize,min,fX1+boxSize,min);
622 line->PaintLine(fX2-boxSize,max,fX2+boxSize,max);
623 } else {
624 line->PaintLine(min,fY1-boxSize,min,fY1+boxSize);
625 line->PaintLine(max,fY2-boxSize,max,fY2+boxSize);
626 }
627
628 // lines from min and max to the box.
629 line->SetLineStyle(7);
630 if (fX1==fX2) {
631 if (min<frame->GetY1()) min = frame->GetY1();
632 if (max>frame->GetY2()) max = frame->GetY2();
633 line->PaintLine(fX1,min,fX1,qua1);
634 line->PaintLine(fX1,qua3,fX1,max);
635 } else {
636 if (min<frame->GetX1()) min = frame->GetX1();
637 if (max>frame->GetX2()) max = frame->GetX2();
638 line->PaintLine(min,fY1,qua1,fY2);
639 line->PaintLine(qua3,fY1,max,fY2);
640 }
641
642 // Box
643 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
644 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
645
646 // Median line
647 line->SetLineStyle(1);
648 if(fX1==fX2) line->PaintLine(fX1-boxSize,med,fX1+boxSize,med);
649 else line->PaintLine(med,fY1-boxSize,med,fY1+boxSize);
650
651 // Paint average
652 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
653 Double_t mean;
654 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
655 else mean = fMean;
656 TMarker *mark = nullptr;
657 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
658 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
659 mark->Paint();
660 delete mark;
661 }
662
663 delete line;
664 delete box;
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Paint the histogram on the axis.
669
671{
672 Int_t i;
673
674 TFrame *frame = gPad->GetFrame();
675
676 if (!fHistogram) GetHistogram();
677
678 // Paint the axis body.
680 // Paint the axis body using bar chart.
681 TBox *b = new TBox();
682 b->SetFillStyle(GetFillStyle());
683 b->SetFillColor(GetFillColor());
684 b->SetLineStyle(1);
685 b->SetLineColor(GetFillColor());
686 b->SetLineWidth(1);
689 if (fX1 == fX2) {
690 // Vertical case.
691 Double_t dy = (fY2-fY1)/fNbins;
694 Double_t y1 = fY1,x2,y2;
695 for (i=1; i<=fNbins; i++) {
697 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
699 else y2=y1+dy;
700 b->PaintBox(fX1,y1,x2,y2,"l");
701 y1=y2;
702 v += dv;
703 }
704 } else {
705 // Horizontal case.
706 Double_t dx = (fX2-fX1)/fNbins;
709 Double_t x1 = fX1,x2,y2;
710 for (i=1; i<=fNbins; i++) {
711 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
713 else x2=x1+dx;
714 b->PaintBox(x1,fY1,x2,y2,"l");
715 x1=x2;
716 v+=dv;
717 }
718 }
719 delete b;
720 }
721 if (fHistoLW==0 && !TestBit(kShowBox)) {
722 // Paint the axis body as a simple line.
723 TLine* l = new TLine(fX1,fY1,fX2,fY2);
727 l->Paint();
728 delete l;
729 } else if (fHistoLW!=0){
730 // Paint the axis body using the color palette.
731 TLine *lb = new TLine();
735 Int_t theColor;
736 Int_t ncolors = gStyle->GetNumberOfColors();
737 if (fX1 == fX2) {
738 // Vertical case.
739 Double_t dy = (fY2-fY1)/fNbins;
740 Double_t y1 = fY1,y2;
743 for (i=1; i<=fNbins; i++) {
744 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
746 else y2=y1+dy;
747 lb->SetLineColor(gStyle->GetColorPalette(theColor));
748 lb->PaintLine(fX1,y1,fX1,y2);
749 y1=y2;
750 v+=dv;
751 }
752 } else {
753 // Horizontal case.
754 Double_t dx = (fX2-fX1)/fNbins;
757 Double_t x1 = fX1,x2;
758 for (i=1; i<=fNbins; i++) {
759 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
760 lb->SetLineColor(gStyle->GetColorPalette(theColor));
762 else x2=x1+dx;
763 lb->PaintLine(x1,fY1,x2,fY1);
764 x1=x2;
765 v+=dv;
766 }
767 }
768 delete lb;
769 }
770}
771
772////////////////////////////////////////////////////////////////////////////////
773/// Paint the axis labels and titles.
774
776{
777 TLatex* t = new TLatex();
778 TFrame *frame = gPad->GetFrame();
779 t->SetTextSize(0.03);
780 if (fX1==fX2) {
781 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
782 Double_t tlength = t->GetXsize();
783 if (fX1-0.5*tlength<0.01) {
784 t->SetTextAlign(11);
785 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
786 t->Paint();
787 } else if (fX1+0.5*tlength > 0.99) {
788 t->SetTextAlign(31);
789 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
790 t->Paint();
791 } else {
792 t->SetTextAlign(21);
793 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
794 }
796 t->SetTextAlign(21);
797 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%g",fMaxCurrent));
798 t->SetTextAlign(23);
799 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%g",fMinCurrent));
800 }
801 } else {
802 t->SetText(fX1-0.04,fY1+0.02,GetName());
803 t->SetTextSize(0.03);
804 Double_t tlength = t->GetXsize();
805 if (fX1-0.04-tlength<0.01) {
806 t->SetTextAlign(12);
807 t->SetText(0.01,fY1+0.02,GetName());
808 t->Paint();
809 } else {
810 t->SetTextAlign(32);
811 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
812 }
814 t->SetTextAlign(12);
815 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%g",fMinCurrent));
816 t->SetTextAlign(32);
817 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%g",fMaxCurrent));
818 }
819 }
820 delete t;
821}
822
823////////////////////////////////////////////////////////////////////////////////
824/// Print the axis main data.
825
826void TParallelCoordVar::Print(Option_t* /*option*/) const
827{
828 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
829 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
830 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Save the TParallelCoordVar as a macro. Can be used only in the context
835/// of TParallelCoord::SavePrimitive (pointer "TParallelCoord* para" is
836/// defined in TParallelCoord::SavePrimitive) with the option "pcalled".
837
838void TParallelCoordVar::SavePrimitive(std::ostream &out, Option_t *options)
839{
840 TString opt = options;
841 if (opt.Contains("pcalled")) {
842 out << " para_var->SetBit(TParallelCoordVar::kLogScale," << TestBit(kLogScale) << ");\n";
843 out << " para_var->SetBit(TParallelCoordVar::kShowBox," << TestBit(kShowBox) << ");\n";
844 out << " para_var->SetBit(TParallelCoordVar::kShowBarHisto," << TestBit(kShowBarHisto) << ");\n";
845 out << " para_var->SetHistogramBinning(" << fNbins << ");\n";
846 out << " para_var->SetHistogramLineWidth(" << fHistoLW << ");\n";
847 out << " para_var->SetInitMin(" << fMinInit << ");\n";
848 out << " para_var->SetInitMax(" << fMaxInit << ");\n";
849 out << " para_var->SetHistogramHeight(" << fHistoHeight << ");\n";
850 out << " para_var->GetMinMaxMean();\n";
851 out << " para_var->GetHistogram();\n";
852 SaveFillAttributes(out, "para_var", -1, -1);
853 SaveLineAttributes(out, "para_var", -1, -1, -1);
854 if (TestBit(kShowBox))
855 out << " para_var->GetQuantiles();\n";
856 TIter next(fRanges);
857 Int_t i = 1;
858 while (auto range = static_cast<TParallelCoordRange *>(next())) {
859 out << " //***************************************\n";
860 out << " // Create the " << i++ << "th range owned by the axis \"" << GetTitle() << "\".\n";
861 out << " para_sel = para->GetSelection(\"" << range->GetSelection()->GetTitle() << "\");\n";
863 TString::Format("para_var, %g, %g, para_sel", range->GetMin(), range->GetMax()));
864 out << " para_var->AddRange(para_newrange);\n";
865 out << " para_sel->Add(para_newrange);\n";
866 }
867 }
868}
869
870////////////////////////////////////////////////////////////////////////////////
871/// Set the axis to display a candle.
872
874{
876 if (box) SetHistogramHeight(0.5);
877 else {
880 }
881}
882
883////////////////////////////////////////////////////////////////////////////////
884/// Set the histogram binning.
885
887{
888 if (n < 0 || n == fNbins) return;
889 fNbins = n;
890 GetHistogram();
891}
892
893////////////////////////////////////////////////////////////////////////////////
894/// Set the height of the bar histogram.
895
904
905////////////////////////////////////////////////////////////////////////////////
906/// Set the current minimum of the axis.
907
912
913////////////////////////////////////////////////////////////////////////////////
914/// Set the current maximum of the axis.
915
920
921////////////////////////////////////////////////////////////////////////////////
922/// Set the limits within which one the entries must be painted.
923
925{
926 if (min>max) {
927 Double_t mem = min;
928 min = max;
929 max = mem;
930 }
931 if(TestBit(kLogScale) && max<=0) return;
932 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
933 fMinCurrent = min;
934 fMaxCurrent = max;
935
936 delete fHistogram;
937 fHistogram = nullptr;
938 GetHistogram();
939
943 }
944}
945
946////////////////////////////////////////////////////////////////////////////////
947/// If true, the pad is updated while the motion of a dragged range.
948
950{
951 TIter next(fRanges);
952 TParallelCoordRange* range;
953 while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kLiveUpdate,on);
954}
955
956////////////////////////////////////////////////////////////////////////////////
957/// Set the axis in log scale.
958
960{
961 if (log == TestBit (kLogScale)) return;
962 if (fMaxInit < 0) SetBit(kLogScale,false);
963 else if (log) {
964 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
965 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
966 SetBit(kLogScale,true);
969 } else {
970 SetBit(kLogScale,false);
973 }
974 GetQuantiles();
975 GetHistogram();
976}
977
978////////////////////////////////////////////////////////////////////////////////
979/// Set the variable values.
980
982{
983 if (fVal) delete [] fVal;
984 fVal = new Double_t[length];
986 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
988 GetHistogram();
990}
991
992////////////////////////////////////////////////////////////////////////////////
993/// Set the X position of the axis in the case of a vertical axis.
994/// and rotate the axis if it was horizontal.
995
997{
998 TFrame *frame = gPad->GetFrame();
999 if (!gl) {
1000 fY1 = frame->GetY1();
1001 fY2 = frame->GetY2();
1002 } else {
1005 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1006 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1007 }
1008 fX1 = fX2 = x;
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012/// Set the Y position of the axis in the case of a horizontal axis.
1013/// and rotate the axis if it was vertical.
1014
1016{
1017 TFrame *frame = gPad->GetFrame();
1018 if (!gl) {
1019 fX1 = frame->GetX1();
1020 fX2 = frame->GetX2();
1021 } else {
1024 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1025 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1026 }
1027 fY1 = fY2 = y;
1028}
@ kButton1Motion
Definition Buttons.h:20
@ kButton1Up
Definition Buttons.h:19
@ kButton1Down
Definition Buttons.h:17
@ kMouseEnter
Definition Buttons.h:23
@ kArrowVer
Definition GuiTypes.h:375
@ kArrowHor
Definition GuiTypes.h:375
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
@ kOrange
Definition Rtypes.h:67
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmin
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmax
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
int nentries
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
Fill Area Attributes class.
Definition TAttFill.h:21
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:240
Line Attributes class.
Definition TAttLine.h:21
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:47
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:44
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:289
virtual Float_t GetTextSize() const
Return the text size.
Definition TAttText.h:39
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:48
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:53
Create a Box.
Definition TBox.h:22
Double_t GetX1() const
Definition TBox.h:51
Double_t GetX2() const
Definition TBox.h:52
Double_t GetY1() const
Definition TBox.h:53
Double_t GetY2() const
Definition TBox.h:54
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Define a Frame.
Definition TFrame.h:19
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:9170
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:8778
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3489
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5239
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition TH1.cxx:8868
To draw Mathematical Formula.
Definition TLatex.h:20
Double_t GetXsize()
Return size of the formula along X in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2580
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition TLatex.cxx:2146
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2124
Use the TLine constructor to create a simple line.
Definition TLine.h:22
virtual void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition TLine.cxx:261
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:251
A doubly linked list.
Definition TList.h:38
void AddAt(TObject *obj, Int_t idx) override
Insert object at position idx in the list.
Definition TList.cxx:413
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
Manages Markers.
Definition TMarker.h:22
void Paint(Option_t *option="") override
Paint this marker with its current attributes.
Definition TMarker.cxx:292
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:776
A TParallelCoordRange is a range used for parallel coordinates plots.
void Paint(Option_t *options) override
Paint a TParallelCoordRange.
static TClass * Class()
bool IsIn(Double_t evtval)
Evaluate if the given value is within the range or not.
TParallelCoordSelect * GetSelection()
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
void HandleMouse(TVirtualPad &parent, Double_t x1, Double_t y1, Int_t px, Int_t py, Bool_t first=kFALSE)
void Paint(TVirtualPad &parent, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
void Paint(Option_t *option="") override
Paint the axis.
TH1F * fHistogram
! Histogram holding the variable distribution.
TH1F * GetHistogram()
Create or recreate the histogram.
char * GetObjectInfo(Int_t px, Int_t py) const override
Returns info about this axis.
void GetEntryXY(Long64_t n, Double_t &x, Double_t &y)
Get the position of the variable on the graph for the n'th entry.
Double_t GetValuefromXY(Double_t x, Double_t y)
Get the value corresponding to the position.
void PaintBoxPlot()
Paint the boxes in the case of a candle chart.
void PaintLabels()
Paint the axis labels and titles.
void ExecuteEvent(Int_t entry, Int_t px, Int_t py) override
Execute the corresponding entry.
bool GetVert() const
Tells if the axis is vertical or not.
void SetBoxPlot(bool box)
Set the axis to display a candle.
void PaintHistogram()
Paint the histogram on the axis.
Double_t fY1
y1 coordinate of the axis.
void SetCurrentMin(Double_t min)
Set the current minimum of the axis.
void SetY(Double_t y, bool gl)
Set the Y position of the axis in the case of a horizontal axis.
void SetLiveRangesUpdate(bool on)
If true, the pad is updated while the motion of a dragged range.
void SetX(Double_t x, bool gl)
Set the X position of the axis in the case of a vertical axis.
Double_t fX1
x1 coordinate of the axis.
~TParallelCoordVar() override
Destructor.
void SavePrimitive(std::ostream &out, Option_t *options) override
Save the TParallelCoordVar as a macro.
Double_t fMaxInit
Memory of the maximum when first initialized.
void SetCurrentMax(Double_t max)
Set the current maximum of the axis.
void SetLogScale(bool log)
Set the axis in log scale.
TList * fRanges
List of the TParallelRange owned by TParallelCoordVar.
void GetQuantiles()
Get the box plot values (quantiles).
Double_t fMinCurrent
Current used minimum.
void SetHistogramHeight(Double_t h=0)
Set the height of the bar histogram.
void DeleteVariable()
Delete variables.
TParallelCoordVar()
Default constructor.
Double_t fMinInit
Memory of the minimum when first initialized.
TParallelCoord * fParallel
Pointer to the TParallelCoord which owns the TParallelCoordVar.
Int_t fId
Id identifying the variable for the editor.
Int_t fNbins
Number of bins in fHistogram.
Long64_t fNentries
Number of stored entries values.
Int_t GetEntryWeight(Long64_t evtidx)
Get the entry weight: The weight of an entry for a given variable is the bin content of the histogram...
Double_t * fVal
![fNentries] Entries values for the variable.
Int_t fHistoLW
Line width used to draw the histogram line.
Double_t fMean
Average.
Double_t fY2
y2 coordinate of the axis.
void SetHistogramLineWidth(Int_t lw=2)
Double_t fX2
x2 coordinate of the axis.
void Init()
Initialise the TParallelVar variables.
void GetXYfromValue(Double_t value, Double_t &x, Double_t &y)
Get a position corresponding to the value on the axis.
void Print(Option_t *option="") const override
Print the axis main data.
void GetMinMaxMean()
Get mean, min and max of those variable.
bool Eval(Long64_t evtidx, TParallelCoordSelect *select)
Check if the entry is within the range(s) of "select".
void Draw(Option_t *option="") override
Draw the axis.
Double_t fQua1
First quantile (Q1).
void SetValues(Long64_t length, Double_t *val)
Set the variable values.
Double_t fQua3
Third quantile (Q3).
void SetHistogramBinning(Int_t n=100)
Set the histogram binning.
Double_t fMed
Median value (Q2).
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Computes the distance from the axis.
void SetCurrentLimits(Double_t min, Double_t max)
Set the limits within which one the entries must be painted.
Double_t fHistoHeight
Histogram Height.
Double_t fMaxCurrent
Current used maximum.
Parallel Coordinates class.
TParallelCoordSelect * GetCurrentSelection()
Return the selection currently being edited.
Double_t GetGlobalMin()
return the global minimum.
Long64_t GetNentries()
Long64_t GetCurrentFirst()
Long64_t GetCurrentN()
TList * GetVarList()
Double_t GetGlobalMax()
return the global maximum.
void SetGlobalMax(Double_t max)
Force all variables to adopt the same max.
void SetGlobalMin(Double_t min)
Force all variables to adopt the same min.
void RemoveVariable(TParallelCoordVar *var)
Delete a variable from the graph.
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
@ kGlobalScale
Every variable is on the same scale.
@ kCandleChart
To produce a candle chart.
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
Basic string class.
Definition TString.h:137
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition TStyle.cxx:1102
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition TStyle.cxx:1176
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition TText.h:74
Helper class to store interactive parameters for individual objects Should be used via gPad->Interact...
Definition TVirtualPad.h:77
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:53
virtual void UpdateAsync()=0
virtual Double_t AbsPixeltoX(Double_t px)=0
virtual void PaintPolyLine(Int_t n, Float_t *x, Float_t *y, Option_t *option="")=0
virtual Double_t AbsPixeltoY(Double_t py)=0
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
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=nullptr, Int_t type=7)
Computes sample quantiles, corresponding to the given probabilities.
Definition TMath.cxx:1207
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:775
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
TLine l
Definition textangle.C:4