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
185
187 {
188 Double_t valx = parent.AbsPixeltoX(px);
189 Double_t valy = parent.AbsPixeltoY(py);
190 if (first)
191 zooming = vertical ? (valx > x1) : (valy > y1);
192
193 if (zooming) {
194 pzoom2 = vertical ? valy : valx;
195 if (first)
196 pzoom1 = pzoom2;
197 } else {
198 pmove = vertical ? valx : valy;
199 }
200 }
201
203 {
204 Double_t xx[4], yy[4];
205
206 if (!zooming && vertical) {
207 xx[0] = xx[1] = pmove;
208 yy[0] = y1; yy[1] = y2;
209 } else if (!zooming && !vertical) {
210 xx[0] = x1; xx[1] = x2;
211 yy[0] = yy[1] = pmove;
212 } else if (zooming && vertical) {
213 xx[0] = xx[2] = x1 - 0.05;
214 xx[1] = xx[3] = x1 + 0.05;
215 yy[0] = yy[1] = pzoom1;
216 yy[2] = yy[3] = pzoom2;
217 } else {
218 xx[0] = xx[1] = pzoom1;
219 xx[2] = xx[3] = pzoom2;
220 yy[0] = yy[2] = y1 - 0.05;
221 yy[1] = yy[3] = y1 + 0.05;
222
223 }
224 parent.PaintPolyLine(2, xx, yy, "iparallelvar1");
225 if (zooming)
226 parent.PaintPolyLine(2, xx+2, yy+2, "iparallelvar2");
227 parent.UpdateAsync();
228 }
229
230};
231
232////////////////////////////////////////////////////////////////////////////////
233/// Execute the corresponding entry.
234
236{
237 if (!gPad)
238 return;
239
240 auto &parent = *gPad;
241
242 if (!parent.IsEditable() && entry != kMouseEnter)
243 return;
244
245 if (GetVert()) {
246 if (parent.AbsPixeltoX(px) - fX1 > 0)
247 parent.SetCursor(kArrowVer);
248 else
249 parent.SetCursor(kArrowHor);
250 } else {
251 if (parent.AbsPixeltoY(py) - fY1 > 0)
252 parent.SetCursor(kArrowHor);
253 else
254 parent.SetCursor(kArrowVer);
255 }
256
257 auto inter = parent.GetInteractive<TParallelCoordVarInteractive>(this);
258
259 switch (entry) {
260 case kButton1Down:
261 inter = parent.MakeInteractive<TParallelCoordVarInteractive>(this, GetVert());
262 parent.GetCanvas()->Selected(&parent, fParallel, 1);
263 // no break
264 case kButton1Motion:
265 if (inter) {
266 inter->HandleMouse(parent, fX1, fY1, px, py, entry == kButton1Down);
267 inter->Paint(parent, fX1, fY1, fX2, fY2);
268 }
269 break;
270 case kButton1Up: {
271 if (inter && inter->zooming) {
272 Double_t min, max;
273 if (GetVert()) {
274 min = GetValuefromXY(fX1, inter->pzoom1);
275 max = GetValuefromXY(fX1, inter->pzoom2);
276 } else {
277 min = GetValuefromXY(inter->pzoom1, fY1);
278 max = GetValuefromXY(inter->pzoom2, fY1);
279 }
280
281 if (min > max)
282 std::swap(min, max);
283
287 } else {
288 SetCurrentLimits(min,max);
289 }
290 } else if (inter && !inter->zooming) {
291 TFrame *frame = parent.GetFrame();
292 Double_t pos = 0;
293 if (GetVert()) {
294 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
295 pos = (inter->pmove - frame->GetX1()) / axisSpace;
296 } else {
297 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
298 pos = (inter->pmove - frame->GetY1()) / axisSpace;
299 }
300 Int_t n = pos < 0 ? -1 : (Int_t) pos;
301 if (n >= 0 && (UInt_t)n >= fParallel->GetNvar())
302 --n;
303 else if (n < fParallel->GetVarList()->IndexOf(this))
304 ++n;
305 fParallel->GetVarList()->Remove(this);
306 fParallel->GetVarList()->AddAt(this, n);
307 }
308
309 parent.Modified();
310 parent.FreeInteractive(this);
311 break;
312 }
313 }
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Get the position of the variable on the graph for the n'th entry.
318
320{
321 if(fX1==fX2){
322 x = fX1;
323 if (fMinCurrent != fMaxCurrent) {
324 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
326 else y = fY1 + (fY2 - fY1) *
328 } else {
329 y = fY1 + 0.5*(fY2-fY1);
330 }
331 } else {
332 y = fY1;
333 if (fMinCurrent != fMaxCurrent) {
334 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
336 else x = fX1 + (fX2 - fX1) *
338 } else {
339 x = fX1 + 0.5*(fX2-fX1);
340 }
341 }
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Get the entry weight: The weight of an entry for a given variable
346/// is the bin content of the histogram bin the entry is going through.
347
353
354////////////////////////////////////////////////////////////////////////////////
355/// Create or recreate the histogram.
356
358{
359 if (fHistogram) delete fHistogram;
360 fHistogram = nullptr;
361 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
362 fHistogram->SetDirectory(nullptr);
365 for(Long64_t li=first; li<first+nentries;++li) {
366 if(fVal[li] >= fMinCurrent && fVal[li] <= fMaxCurrent) fHistogram->Fill(fVal[li]);
367 }
368 return fHistogram;
369}
370
371////////////////////////////////////////////////////////////////////////////////
372/// Get mean, min and max of those variable.
373
375{
376 Double_t min,max,ave = 0;
377 min = DBL_MAX;
378 max = -DBL_MAX;
379 Long64_t first,nentries;
380 first = fParallel->GetCurrentFirst();
382 for(Long64_t li=first; li<first+nentries;++li){
383 if(fVal[li]<min) min = fVal[li];
384 if(fVal[li]>max) max = fVal[li];
385 ave+=fVal[li];
386 }
387
388 fMean = ave/((Double_t)nentries);
389 fMinCurrent = fMinInit = min;
390 fMaxCurrent = fMaxInit = max;
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Returns info about this axis.
395
397{
398 static char info[128];
399 info[0] = 0;
400
401 if (!gPad) return info;
402 Double_t xx = gPad->AbsPixeltoX(px);
403 Double_t yy = gPad->AbsPixeltoY(py);
404 if (fX1 == fX2) {
405 if (yy<fY1) {
406 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
407 } else if (yy>fY2) {
408 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
409 } else {
410 Double_t axislength = fY2-fY1;
411 Double_t pos = (yy-fY1)/axislength;
412 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent + pos*(fMaxCurrent-fMinCurrent));
413 }
414 } else {
415 if (xx<fX1) {
416 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
417 } else if(xx>fX2) {
418 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
419 } else {
420 Double_t axislength = fX2-fX1;
421 Double_t pos = (xx-fX1)/axislength;
422 snprintf(info,128,"%s = %f", GetTitle(), pos*(fMaxCurrent-fMinCurrent));
423 }
424 }
425 return info;
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Get the box plot values (quantiles).
430
432{
433 Double_t *quantiles = new Double_t[3];
434 quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.;
435 Double_t *prob = new Double_t[3];
436 prob[0]=0.25; prob[1]=0.5; prob[2] = 0.75;
439 if (!TestBit(kLogScale) && first==0 && nentries==fNentries) TMath::Quantiles(fNentries,3,fVal,quantiles,prob,false);
440 else {
441 Double_t* val = new Double_t[nentries];
442 Int_t selected = 0;
443 if(fMinInit<=0) {
444 for (Long64_t n=first;n<first+nentries;++n) {
445 if (fVal[n] >= fMinCurrent) {
446 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
447 else val[selected] = fVal[n];
448 ++selected;
449 }
450 }
451 } else {
452 for (Long64_t n=first;n<first+nentries;++n) {
453 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
454 else val[selected] = fVal[n];
455 ++selected;
456 }
457 }
458 TMath::Quantiles(selected,3,val,quantiles,prob,false);
459 delete [] val;
460 }
461 fQua1 = quantiles[0];
462 fMed = quantiles[1];
463 fQua3 = quantiles[2];
464 delete [] quantiles;
465 delete [] prob;
466}
467
468////////////////////////////////////////////////////////////////////////////////
469/// Get the value corresponding to the position.
470
472{
473 Double_t pos;
474 if (fMinCurrent == fMaxCurrent) return fMinCurrent;
475 if (fX1 == fX2) {
476 if (y<=fY1) pos = fMinCurrent;
477 else if (y>=fY2) pos = fMaxCurrent;
478 else pos = fMinCurrent + ((y-fY1)/(fY2-fY1))*(fMaxCurrent-fMinCurrent);
479 } else {
480 if (x<=fX1) pos = fMinCurrent;
481 else if (x>=fX2) pos = fMaxCurrent;
482 else pos = fMinCurrent + ((x-fX1)/(fX2-fX1))*(fMaxCurrent-fMinCurrent);
483 }
484 return pos;
485}
486
487////////////////////////////////////////////////////////////////////////////////
488/// Tells if the axis is vertical or not.
489
491{
492 return fX1 == fX2;
493}
494
495////////////////////////////////////////////////////////////////////////////////
496/// Get a position corresponding to the value on the axis.
497
499{
500 if(value < fMinCurrent || value > fMaxCurrent) return;
501
502 if (fX1==fX2) {
503 x = fX1;
504 if (fMinCurrent != fMaxCurrent) {
505 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
507 else y = fY1 + (fY2 - fY1) *
509 } else {
510 y = fY1 + 0.5*(fY2-fY1);
511 }
512 } else {
513 y = fY1;
514 if (fMinCurrent != fMaxCurrent) {
515 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
517 else x = fX1 + (fX2 - fX1) *
519 } else {
520 x = fX1 + 0.5*(fX2-fX1);
521 }
522 }
523}
524
525////////////////////////////////////////////////////////////////////////////////
526/// Initialise the TParallelVar variables.
527
529{
530 fX1 = 0;
531 fX2 = 0;
532 fY1 = 0;
533 fY2 = 0;
534 fId = 0;
535 fVal = nullptr;
536 fMean = 0;
537 fMinInit = 0;
538 fMinCurrent = 0;
539 fMaxInit = 0;
540 fMaxCurrent = 0;
541 fMed = 0;
542 fQua1 = 0;
543 fQua3 = 0;
544 fNentries = 0;
545 fParallel = nullptr;
546 fHistogram = nullptr;
547 fNbins = 100;
548 fHistoLW = 2;
549 fHistoHeight = 0.5;
550 fRanges = nullptr;
551 SetBit(kLogScale,false);
552 SetBit(kShowBox,false);
553 SetBit(kShowBarHisto,true);
554}
555
556////////////////////////////////////////////////////////////////////////////////
557/// Paint the axis.
558
560{
561 TIter next(fRanges);
562 TParallelCoordRange* range;
563 while ((range = (TParallelCoordRange*)next())) range->Paint(option);
564
567 PaintLabels();
568}
569
570////////////////////////////////////////////////////////////////////////////////
571/// Paint the boxes in the case of a candle chart.
572
574{
575 TLine *line = new TLine();
577 line->SetLineWidth(1);
578 TBox *box = new TBox();
579 box->SetLineWidth(1);
580 box->SetLineColor(GetLineColor());
581 box->SetLineStyle(1);
582 box->SetFillStyle(0);
583
584 TFrame* frame = gPad->GetFrame();
585
586 Double_t boxSize;
587 if (fParallel->GetNvar() > 1) {
588 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
589 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
590 if (boxSize >= 0.03) boxSize = 0.03;
591 }
592 else boxSize = 0.03;
593
594 Double_t qua1,med,qua3,max,min;
595 Double_t a,b,maxinit,mininit;
596 if (TestBit(kLogScale)) {
599 if(fMinInit > 0) mininit = TMath::Log10(fMinInit);
600 else mininit = TMath::Log10(fMinCurrent);
601 maxinit = TMath::Log10(fMaxInit);
602 } else {
603 a = fMinCurrent;
605 mininit = fMinInit;
606 maxinit = fMaxInit;
607 }
608 if(fX1==fX2) {
609 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
610 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
611 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
612 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
613 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
614 } else {
615 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
616 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
617 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
618 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
619 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
620 }
621
622 // min and max lines.
623 if (fX1==fX2) {
624 line->PaintLine(fX1-boxSize,min,fX1+boxSize,min);
625 line->PaintLine(fX2-boxSize,max,fX2+boxSize,max);
626 } else {
627 line->PaintLine(min,fY1-boxSize,min,fY1+boxSize);
628 line->PaintLine(max,fY2-boxSize,max,fY2+boxSize);
629 }
630
631 // lines from min and max to the box.
632 line->SetLineStyle(7);
633 if (fX1==fX2) {
634 if (min<frame->GetY1()) min = frame->GetY1();
635 if (max>frame->GetY2()) max = frame->GetY2();
636 line->PaintLine(fX1,min,fX1,qua1);
637 line->PaintLine(fX1,qua3,fX1,max);
638 } else {
639 if (min<frame->GetX1()) min = frame->GetX1();
640 if (max>frame->GetX2()) max = frame->GetX2();
641 line->PaintLine(min,fY1,qua1,fY2);
642 line->PaintLine(qua3,fY1,max,fY2);
643 }
644
645 // Box
646 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
647 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
648
649 // Median line
650 line->SetLineStyle(1);
651 if(fX1==fX2) line->PaintLine(fX1-boxSize,med,fX1+boxSize,med);
652 else line->PaintLine(med,fY1-boxSize,med,fY1+boxSize);
653
654 // Paint average
655 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
656 Double_t mean;
657 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
658 else mean = fMean;
659 TMarker *mark = nullptr;
660 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
661 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
662 mark->Paint();
663 delete mark;
664 }
665
666 delete line;
667 delete box;
668}
669
670////////////////////////////////////////////////////////////////////////////////
671/// Paint the histogram on the axis.
672
674{
675 Int_t i;
676
677 TFrame *frame = gPad->GetFrame();
678
679 if (!fHistogram) GetHistogram();
680
681 // Paint the axis body.
683 // Paint the axis body using bar chart.
684 TBox *b = new TBox();
685 b->SetFillStyle(GetFillStyle());
686 b->SetFillColor(GetFillColor());
687 b->SetLineStyle(1);
688 b->SetLineColor(GetFillColor());
689 b->SetLineWidth(1);
692 if (fX1 == fX2) {
693 // Vertical case.
694 Double_t dy = (fY2-fY1)/fNbins;
697 Double_t y1 = fY1,x2,y2;
698 for (i=1; i<=fNbins; i++) {
700 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
702 else y2=y1+dy;
703 b->PaintBox(fX1,y1,x2,y2,"l");
704 y1=y2;
705 v += dv;
706 }
707 } else {
708 // Horizontal case.
709 Double_t dx = (fX2-fX1)/fNbins;
712 Double_t x1 = fX1,x2,y2;
713 for (i=1; i<=fNbins; i++) {
714 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
716 else x2=x1+dx;
717 b->PaintBox(x1,fY1,x2,y2,"l");
718 x1=x2;
719 v+=dv;
720 }
721 }
722 delete b;
723 }
724 if (fHistoLW==0 && !TestBit(kShowBox)) {
725 // Paint the axis body as a simple line.
726 TLine* l = new TLine(fX1,fY1,fX2,fY2);
730 l->Paint();
731 delete l;
732 } else if (fHistoLW!=0){
733 // Paint the axis body using the color palette.
734 TLine *lb = new TLine();
738 Int_t theColor;
739 Int_t ncolors = gStyle->GetNumberOfColors();
740 if (fX1 == fX2) {
741 // Vertical case.
742 Double_t dy = (fY2-fY1)/fNbins;
743 Double_t y1 = fY1,y2;
746 for (i=1; i<=fNbins; i++) {
747 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
749 else y2=y1+dy;
750 lb->SetLineColor(gStyle->GetColorPalette(theColor));
751 lb->PaintLine(fX1,y1,fX1,y2);
752 y1=y2;
753 v+=dv;
754 }
755 } else {
756 // Horizontal case.
757 Double_t dx = (fX2-fX1)/fNbins;
760 Double_t x1 = fX1,x2;
761 for (i=1; i<=fNbins; i++) {
762 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
763 lb->SetLineColor(gStyle->GetColorPalette(theColor));
765 else x2=x1+dx;
766 lb->PaintLine(x1,fY1,x2,fY1);
767 x1=x2;
768 v+=dv;
769 }
770 }
771 delete lb;
772 }
773}
774
775////////////////////////////////////////////////////////////////////////////////
776/// Paint the axis labels and titles.
777
779{
780 TLatex* t = new TLatex();
781 TFrame *frame = gPad->GetFrame();
782 t->SetTextSize(0.03);
783 if (fX1==fX2) {
784 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
785 Double_t tlength = t->GetXsize();
786 if (fX1-0.5*tlength<0.01) {
787 t->SetTextAlign(11);
788 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
789 t->Paint();
790 } else if (fX1+0.5*tlength > 0.99) {
791 t->SetTextAlign(31);
792 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
793 t->Paint();
794 } else {
795 t->SetTextAlign(21);
796 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
797 }
799 t->SetTextAlign(21);
800 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%g",fMaxCurrent));
801 t->SetTextAlign(23);
802 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%g",fMinCurrent));
803 }
804 } else {
805 t->SetText(fX1-0.04,fY1+0.02,GetName());
806 t->SetTextSize(0.03);
807 Double_t tlength = t->GetXsize();
808 if (fX1-0.04-tlength<0.01) {
809 t->SetTextAlign(12);
810 t->SetText(0.01,fY1+0.02,GetName());
811 t->Paint();
812 } else {
813 t->SetTextAlign(32);
814 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
815 }
817 t->SetTextAlign(12);
818 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%g",fMinCurrent));
819 t->SetTextAlign(32);
820 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%g",fMaxCurrent));
821 }
822 }
823 delete t;
824}
825
826////////////////////////////////////////////////////////////////////////////////
827/// Print the axis main data.
828
829void TParallelCoordVar::Print(Option_t* /*option*/) const
830{
831 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
832 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
833 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
834}
835
836////////////////////////////////////////////////////////////////////////////////
837/// Save the TParallelCoordVar as a macro. Can be used only in the context
838/// of TParallelCoord::SavePrimitive (pointer "TParallelCoord* para" is
839/// defined in TParallelCoord::SavePrimitive) with the option "pcalled".
840
841void TParallelCoordVar::SavePrimitive(std::ostream &out, Option_t *options)
842{
843 TString opt = options;
844 if (opt.Contains("pcalled")) {
845 out << " para_var->SetBit(TParallelCoordVar::kLogScale," << TestBit(kLogScale) << ");\n";
846 out << " para_var->SetBit(TParallelCoordVar::kShowBox," << TestBit(kShowBox) << ");\n";
847 out << " para_var->SetBit(TParallelCoordVar::kShowBarHisto," << TestBit(kShowBarHisto) << ");\n";
848 out << " para_var->SetHistogramBinning(" << fNbins << ");\n";
849 out << " para_var->SetHistogramLineWidth(" << fHistoLW << ");\n";
850 out << " para_var->SetInitMin(" << fMinInit << ");\n";
851 out << " para_var->SetInitMax(" << fMaxInit << ");\n";
852 out << " para_var->SetHistogramHeight(" << fHistoHeight << ");\n";
853 out << " para_var->GetMinMaxMean();\n";
854 out << " para_var->GetHistogram();\n";
855 SaveFillAttributes(out, "para_var", -1, -1);
856 SaveLineAttributes(out, "para_var", -1, -1, -1);
857 if (TestBit(kShowBox))
858 out << " para_var->GetQuantiles();\n";
859 TIter next(fRanges);
860 Int_t i = 1;
861 while (auto range = static_cast<TParallelCoordRange *>(next())) {
862 out << " //***************************************\n";
863 out << " // Create the " << i++ << "th range owned by the axis \"" << GetTitle() << "\".\n";
864 out << " para_sel = para->GetSelection(\"" << range->GetSelection()->GetTitle() << "\");\n";
866 TString::Format("para_var, %g, %g, para_sel", range->GetMin(), range->GetMax()));
867 out << " para_var->AddRange(para_newrange);\n";
868 out << " para_sel->Add(para_newrange);\n";
869 }
870 }
871}
872
873////////////////////////////////////////////////////////////////////////////////
874/// Set the axis to display a candle.
875
877{
879 if (box) SetHistogramHeight(0.5);
880 else {
883 }
884}
885
886////////////////////////////////////////////////////////////////////////////////
887/// Set the histogram binning.
888
890{
891 if (n < 0 || n == fNbins) return;
892 fNbins = n;
893 GetHistogram();
894}
895
896////////////////////////////////////////////////////////////////////////////////
897/// Set the height of the bar histogram.
898
907
908////////////////////////////////////////////////////////////////////////////////
909/// Set the current minimum of the axis.
910
915
916////////////////////////////////////////////////////////////////////////////////
917/// Set the current maximum of the axis.
918
923
924////////////////////////////////////////////////////////////////////////////////
925/// Set the limits within which one the entries must be painted.
926
928{
929 if (min>max) {
930 Double_t mem = min;
931 min = max;
932 max = mem;
933 }
934 if(TestBit(kLogScale) && max<=0) return;
935 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
936 fMinCurrent = min;
937 fMaxCurrent = max;
938
939 delete fHistogram;
940 fHistogram = nullptr;
941 GetHistogram();
942
946 }
947}
948
949////////////////////////////////////////////////////////////////////////////////
950/// If true, the pad is updated while the motion of a dragged range.
951
953{
954 TIter next(fRanges);
955 TParallelCoordRange* range;
956 while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kLiveUpdate,on);
957}
958
959////////////////////////////////////////////////////////////////////////////////
960/// Set the axis in log scale.
961
963{
964 if (log == TestBit (kLogScale)) return;
965 if (fMaxInit < 0) SetBit(kLogScale,false);
966 else if (log) {
967 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
968 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
969 SetBit(kLogScale,true);
972 } else {
973 SetBit(kLogScale,false);
976 }
977 GetQuantiles();
978 GetHistogram();
979}
980
981////////////////////////////////////////////////////////////////////////////////
982/// Set the variable values.
983
985{
986 if (fVal) delete [] fVal;
987 fVal = new Double_t[length];
989 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
991 GetHistogram();
993}
994
995////////////////////////////////////////////////////////////////////////////////
996/// Set the X position of the axis in the case of a vertical axis.
997/// and rotate the axis if it was horizontal.
998
1000{
1001 TFrame *frame = gPad->GetFrame();
1002 if (!gl) {
1003 fY1 = frame->GetY1();
1004 fY2 = frame->GetY2();
1005 } else {
1008 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1009 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1010 }
1011 fX1 = fX2 = x;
1012}
1013
1014////////////////////////////////////////////////////////////////////////////////
1015/// Set the Y position of the axis in the case of a horizontal axis.
1016/// and rotate the axis if it was vertical.
1017
1019{
1020 TFrame *frame = gPad->GetFrame();
1021 if (!gl) {
1022 fX1 = frame->GetX1();
1023 fX2 = frame->GetX2();
1024 } else {
1027 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1028 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1029 }
1030 fY1 = fY2 = y;
1031}
@ 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:260
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:250
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 MakeInteractiv...
Definition TVirtualPad.h:72
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