Logo ROOT  
Reference Guide
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 "Riostream.h"
17#include "TROOT.h"
18#include "TLatex.h"
19#include "TLine.h"
20#include "TVirtualPad.h"
21#include "TVirtualX.h"
22#include "TMath.h"
23#include "TH1.h"
24#include "TStyle.h"
25#include "TBox.h"
26#include "TCollection.h"
27#include "TList.h"
28#include "TFrame.h"
29#include "TCanvas.h"
30#include "TMarker.h"
31
33
34/** \class TParallelCoordVar
35
36TParallelCoord axes. Class containing a variable for the TParallelCoord.
37
38Options can be defined each axis separately using the right mouse click. These
39options can be applied to every axes using the editor.
40
41 - Axis width: If set to 0, the axis is simply a line. If higher, a color
42 histogram is drawn on the axis.
43 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
44
45The order in which the variables are drawn is essential to see the clusters. The
46axes can be dragged to change their position. A zoom is also available. The
47logarithm scale is also available by right clicking on the axis.
48*/
49
50////////////////////////////////////////////////////////////////////////////////
51/// Default constructor.
52
55{
56 Init();
57}
58
59////////////////////////////////////////////////////////////////////////////////
60///Destructor.
61
63{
64 if (fHistogram) delete fHistogram;
65 if (fRanges){
66 TIter next(fRanges);
68 while((range = (TParallelCoordRange*)next())) fParallel->CleanUpSelections(range);
69 fRanges->Delete();
70 delete fRanges;
71 }
72 if (fVal) delete [] fVal;
73}
74
75////////////////////////////////////////////////////////////////////////////////
76/// Normal constructor. By default, the title and the name are the expression
77/// given to TTree::Draw. The name can be changed by the user (the label on the
78/// plot) but not the title.
79
81 :TNamed(title,title), TAttLine(1,1,1), TAttFill(kOrange+9,3001)
82{
83 Init();
84 fId = id;
85 fParallel = parallel;
86 fRanges = new TList();
88
90
91 for(Long64_t ui = 0;ui<fParallel->GetNentries();++ui) fVal[ui]=val[ui];
92
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Add a range to the current selection on the axis.
100
102{
103 if (!range) {
105 if (select) {
106 range = new TParallelCoordRange(this,0,0,select);
107 fRanges->Add(range);
108 range->GetSelection()->Add(range);
109 } else {
110 Error("AddRange","You must create a selection before adding ranges.");
111 }
112 } else {
113 fRanges->Add(range);
114 range->GetSelection()->Add(range);
115 }
116}
117
118////////////////////////////////////////////////////////////////////////////////
119/// Delete variables.
120
122{
124 delete this;
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Computes the distance from the axis.
129
131{
132 if(!gPad) return 9999;
133 Double_t xx = gPad->AbsPixeltoX(px);
134 Double_t yy = gPad->AbsPixeltoY(py);
135 Double_t dist = 9999;
136
137 if (fX1==fX2) {
138 if (yy>fY1+0.01 && yy<fY2-0.01) dist = TMath::Abs(xx - fX1);
139 } else {
140 if (xx>fX1+0.01 && xx<fX2-0.01) dist = TMath::Abs(yy - fY1);
141 }
142 if (dist<=0.005) return 0;
143 else return 9999;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// Draw the axis.
148
150{
151 AppendPad(option);
152}
153
154////////////////////////////////////////////////////////////////////////////////
155/// Check if the entry is within the range(s) of "select". Two ranges on a
156/// single axis are conjugated as a "or": to be selected, the entry must be in
157/// one of the ranges.
158
160{
161 if (fRanges->GetSize() > 0){
162 TIter next(fRanges);
163 Bool_t inarange = kFALSE;
164 Bool_t noOwnedRange = kTRUE;
165 TParallelCoordRange *range;
166 while ((range = (TParallelCoordRange*)next())){
167 if(select->Contains(range)) {
168 noOwnedRange = kFALSE;
169 if(range->IsIn(fVal[evtidx])) inarange = kTRUE;
170 }
171 }
172 if (noOwnedRange) return kTRUE;
173 else return inarange;
174 }
175 else return kTRUE;
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Execute the corresponding entry.
180
182{
183 if (!gPad) return;
184 if (!gPad->IsEditable() && entry!=kMouseEnter) return;
185
186 static Int_t pxold, pyold;
187 static Int_t zoom; // -1:nothing zoomed or translated, 0:translating the axis, 1:zooming
188 static Int_t pzoomold;
189 static Bool_t first = kTRUE;
190
191 Int_t px1,px2,py1,py2,n=-1;
192 px1 = gPad->XtoAbsPixel(fX1);
193 px2 = gPad->XtoAbsPixel(fX2);
194 py1 = gPad->YtoAbsPixel(fY1);
195 py2 = gPad->YtoAbsPixel(fY2);
196
197 if(fX1 == fX2) {
198 if(gPad->AbsPixeltoX(px)-fX1 > 0) gPad->SetCursor(kArrowVer);
199 else gPad->SetCursor(kArrowHor);
200 } else {
201 if(gPad->AbsPixeltoY(py)-fY1 > 0) gPad->SetCursor(kArrowHor);
202 else gPad->SetCursor(kArrowVer);
203 }
204
205 gVirtualX->SetLineColor(-1);
206 switch (entry) {
207 case kButton1Down:
208 if (fX1==fX2){
209 ((TCanvas*)gPad)->Selected(gPad,fParallel,1);
210 if(gPad->AbsPixeltoX(px)-fX1 > 0){
211 zoom = 1;
212 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
213 first = kTRUE;
214 pzoomold = py;
215 } else {
216 zoom = 0;
217 gVirtualX->DrawLine(px,py1,px,py2);
218 }
219 } else {
220 if(gPad->AbsPixeltoY(py)-fY1 > 0){
221 zoom = 1;
222 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
223 first=kTRUE;
224 pzoomold = px;
225 } else {
226 zoom = 0;
227 gVirtualX->DrawLine(px1,py,px2,py);
228 }
229 }
230 pxold = px;
231 pyold = py;
232 break;
233 case kButton1Up: {
234 Double_t xx = gPad->AbsPixeltoX(px);
235 Double_t yy = gPad->AbsPixeltoY(py);
236 TFrame *frame = gPad->GetFrame();
237 if (fX1==fX2) {
238 if(zoom == 0){
239 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
240 Double_t pos = (xx - frame->GetX1())/axisSpace;
241 if (pos < 0) n = -1;
242 else n = (Int_t)pos;
243 } else {
244 Double_t min = GetValuefromXY(xx,yy);
245 Double_t max = GetValuefromXY(xx,gPad->AbsPixeltoY(pzoomold));
246 if(TMath::Abs(min-max) < 0.00001) return; // Avoid zooming if the axis is just clicked.
248 if (min>max) {
249 Double_t mem = min;
250 min = max; max = mem;
251 }
254 } else {
255 SetCurrentLimits(min,max);
256 }
257 }
258 } else {
259 if(zoom == 0) {
260 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
261 Double_t pos = (yy-frame->GetY1())/axisSpace;
262 if (pos < 0) n= -1;
263 else n = (Int_t)pos;
264 } else {
265 Double_t min = GetValuefromXY(xx,yy);
266 Double_t max = GetValuefromXY(gPad->AbsPixeltoX(pzoomold),yy);
267 SetCurrentLimits(min,max);
268 }
269 }
270 if(zoom == 0){
271 if (n>=0 && (UInt_t)n>=fParallel->GetNvar()) --n;
272 else if (n<fParallel->GetVarList()->IndexOf(this)) ++n;
273 fParallel->GetVarList()->Remove(this);
274 fParallel->GetVarList()->AddAt(this,n);
275 }
276 gPad->Modified();
277 break;
278 }
279 case kMouseMotion:
280 pxold=px;
281 pyold=py;
282 break;
283 case kButton1Motion:
284 if(fX1==fX2){
285 if(zoom==0){
286 gPad->SetCursor(kArrowHor);
287 gVirtualX->DrawLine(pxold,py1,pxold,py2);
288 gVirtualX->DrawLine(px,py1,px,py2);
289 } else if(zoom==1) {
290 gPad->SetCursor(kArrowVer);
291 if(!first) gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),pyold,gPad->XtoAbsPixel(fX1+0.05),pyold);
292 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
293 first = kFALSE;
294 }
295 } else {
296 if(zoom==0){
297 gPad->SetCursor(kArrowVer);
298 gVirtualX->DrawLine(px1,pyold,px2,pyold);
299 gVirtualX->DrawLine(px1,py,px2,py);
300 } else if(zoom==1){
301 gPad->SetCursor(kArrowHor);
302 if(!first) gVirtualX->DrawLine(pxold,gPad->YtoAbsPixel(fY1-0.05),pxold,gPad->YtoAbsPixel(fY1+0.05));
303 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
304 first = kFALSE;
305 }
306 }
307 pxold = px;
308 pyold = py;
309 break;
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
346{
347 Int_t bin = 1 + (Int_t)((fVal[evtidx] - fMinCurrent)/((fMaxCurrent-fMinCurrent)/fNbins));
348 return (Int_t)fHistogram->GetBinContent(bin);
349}
350
351////////////////////////////////////////////////////////////////////////////////
352/// Create or recreate the histogram.
353
355{
356 if (fHistogram) delete fHistogram;
357 fHistogram = NULL;
358 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
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;
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,kFALSE);
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,kFALSE);
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/// Get a position corresponding to the value on the axis.
486
488{
489 if(value < fMinCurrent || value > fMaxCurrent) return;
490
491 if (fX1==fX2) {
492 x = fX1;
493 if (fMinCurrent != fMaxCurrent) {
494 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
496 else y = fY1 + (fY2 - fY1) *
497 (value - fMinCurrent) / (fMaxCurrent - fMinCurrent);
498 } else {
499 y = fY1 + 0.5*(fY2-fY1);
500 }
501 } else {
502 y = fY1;
503 if (fMinCurrent != fMaxCurrent) {
504 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
506 else x = fX1 + (fX2 - fX1) *
507 (value - fMinCurrent) / (fMaxCurrent - fMinCurrent);
508 } else {
509 x = fX1 + 0.5*(fX2-fX1);
510 }
511 }
512}
513
514////////////////////////////////////////////////////////////////////////////////
515/// Initialise the TParallelVar variables.
516
518{
519 fX1 = 0;
520 fX2 = 0;
521 fY1 = 0;
522 fY2 = 0;
523 fId = 0;
524 fVal = NULL;
525 fMean = 0;
526 fMinInit = 0;
527 fMinCurrent = 0;
528 fMaxInit = 0;
529 fMaxCurrent = 0;
530 fMed = 0;
531 fQua1 = 0;
532 fQua3 = 0;
533 fNentries = 0;
534 fParallel = NULL;
535 fHistogram = NULL;
536 fNbins = 100;
537 fHistoLW = 2;
538 fHistoHeight = 0.5;
539 fRanges = NULL;
543}
544
545////////////////////////////////////////////////////////////////////////////////
546/// Paint the axis.
547
549{
550 TIter next(fRanges);
551 TParallelCoordRange* range;
552 while ((range = (TParallelCoordRange*)next())) range->Paint(option);
553
556 PaintLabels();
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Paint the boxes in the case of a candle chart.
561
563{
564 TLine *line = new TLine();
566 line->SetLineWidth(1);
567 TBox *box = new TBox();
568 box->SetLineWidth(1);
569 box->SetLineColor(GetLineColor());
570 box->SetLineStyle(1);
571 box->SetFillStyle(0);
572
573 TFrame* frame = gPad->GetFrame();
574
575 Double_t boxSize;
576 if (fParallel->GetNvar() > 1) {
577 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
578 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
579 if (boxSize >= 0.03) boxSize = 0.03;
580 }
581 else boxSize = 0.03;
582
583 Double_t qua1,med,qua3,max,min;
584 Double_t a,b,maxinit,mininit;
585 if (TestBit(kLogScale)) {
588 if(fMinInit > 0) mininit = TMath::Log10(fMinInit);
589 else mininit = TMath::Log10(fMinCurrent);
590 maxinit = TMath::Log10(fMaxInit);
591 } else {
592 a = fMinCurrent;
594 mininit = fMinInit;
595 maxinit = fMaxInit;
596 }
597 if(fX1==fX2) {
598 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
599 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
600 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
601 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
602 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
603 } else {
604 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
605 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
606 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
607 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
608 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
609 }
610
611 // min and max lines.
612 if (fX1==fX2) {
613 line->PaintLine(fX1-boxSize,min,fX1+boxSize,min);
614 line->PaintLine(fX2-boxSize,max,fX2+boxSize,max);
615 } else {
616 line->PaintLine(min,fY1-boxSize,min,fY1+boxSize);
617 line->PaintLine(max,fY2-boxSize,max,fY2+boxSize);
618 }
619
620 // lines from min and max to the box.
621 line->SetLineStyle(7);
622 if (fX1==fX2) {
623 if (min<frame->GetY1()) min = frame->GetY1();
624 if (max>frame->GetY2()) max = frame->GetY2();
625 line->PaintLine(fX1,min,fX1,qua1);
626 line->PaintLine(fX1,qua3,fX1,max);
627 } else {
628 if (min<frame->GetX1()) min = frame->GetX1();
629 if (max>frame->GetX2()) max = frame->GetX2();
630 line->PaintLine(min,fY1,qua1,fY2);
631 line->PaintLine(qua3,fY1,max,fY2);
632 }
633
634 // Box
635 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
636 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
637
638 // Median line
639 line->SetLineStyle(1);
640 if(fX1==fX2) line->PaintLine(fX1-boxSize,med,fX1+boxSize,med);
641 else line->PaintLine(med,fY1-boxSize,med,fY1+boxSize);
642
643 // Paint average
644 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
645 Double_t mean;
646 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
647 else mean = fMean;
648 TMarker *mark = NULL;
649 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
650 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
651 mark->Paint();
652 delete mark;
653 }
654
655 delete line;
656 delete box;
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Paint the histogram on the axis.
661
663{
664 Int_t i;
665
666 TFrame *frame = gPad->GetFrame();
667
668 if (!fHistogram) GetHistogram();
669
670 // Paint the axis body.
672 // Paint the axis body using bar chart.
673 TBox *b = new TBox();
674 b->SetFillStyle(GetFillStyle());
675 b->SetFillColor(GetFillColor());
676 b->SetLineStyle(1);
677 b->SetLineColor(GetFillColor());
678 b->SetLineWidth(1);
681 if (fX1 == fX2) {
682 // Vertical case.
683 Double_t dy = (fY2-fY1)/fNbins;
686 Double_t y1 = fY1,x2,y2;
687 for (i=1; i<=fNbins; i++) {
688 x2 = fX1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*
689 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
691 else y2=y1+dy;
692 b->PaintBox(fX1,y1,x2,y2,"l");
693 y1=y2;
694 v += dv;
695 }
696 } else {
697 // Horizontal case.
698 Double_t dx = (fX2-fX1)/fNbins;
701 Double_t x1 = fX1,x2,y2;
702 for (i=1; i<=fNbins; i++) {
703 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
705 else x2=x1+dx;
706 b->PaintBox(x1,fY1,x2,y2,"l");
707 x1=x2;
708 v+=dv;
709 }
710 }
711 delete b;
712 }
713 if (fHistoLW==0 && !TestBit(kShowBox)) {
714 // Paint the axis body as a simple line.
715 TLine* l = new TLine(fX1,fY1,fX2,fY2);
716 l->SetLineWidth(GetLineWidth());
717 l->SetLineColor(GetLineColor());
718 l->SetLineStyle(GetLineColor());
719 l->Paint();
720 delete l;
721 } else if (fHistoLW!=0){
722 // Paint the axis body using the color palette.
723 TLine *lb = new TLine();
727 Int_t theColor;
728 Int_t ncolors = gStyle->GetNumberOfColors();
729 if (fX1 == fX2) {
730 // Vertical case.
731 Double_t dy = (fY2-fY1)/fNbins;
732 Double_t y1 = fY1,y2;
735 for (i=1; i<=fNbins; i++) {
736 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
738 else y2=y1+dy;
739 lb->SetLineColor(gStyle->GetColorPalette(theColor));
740 lb->PaintLine(fX1,y1,fX1,y2);
741 y1=y2;
742 v+=dv;
743 }
744 } else {
745 // Horizontal case.
746 Double_t dx = (fX2-fX1)/fNbins;
749 Double_t x1 = fX1,x2;
750 for (i=1; i<=fNbins; i++) {
751 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
752 lb->SetLineColor(gStyle->GetColorPalette(theColor));
754 else x2=x1+dx;
755 lb->PaintLine(x1,fY1,x2,fY1);
756 x1=x2;
757 v+=dv;
758 }
759 }
760 delete lb;
761 }
762}
763
764////////////////////////////////////////////////////////////////////////////////
765/// Paint the axis labels and titles.
766
768{
769 TLatex* t = new TLatex();
770 TFrame *frame = gPad->GetFrame();
771 t->SetTextSize(0.03);
772 if (fX1==fX2) {
773 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
774 Double_t tlength = t->GetXsize();
775 if (fX1-0.5*tlength<0.01) {
776 t->SetTextAlign(11);
777 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
778 t->Paint();
779 } else if (fX1+0.5*tlength > 0.99) {
780 t->SetTextAlign(31);
781 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
782 t->Paint();
783 } else {
784 t->SetTextAlign(21);
785 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
786 }
788 t->SetTextAlign(21);
789 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%g",fMaxCurrent));
790 t->SetTextAlign(23);
791 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%g",fMinCurrent));
792 }
793 } else {
794 t->SetText(fX1-0.04,fY1+0.02,GetName());
795 t->SetTextSize(0.03);
796 Double_t tlength = t->GetXsize();
797 if (fX1-0.04-tlength<0.01) {
798 t->SetTextAlign(12);
799 t->SetText(0.01,fY1+0.02,GetName());
800 t->Paint();
801 } else {
802 t->SetTextAlign(32);
803 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
804 }
806 t->SetTextAlign(12);
807 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%g",fMinCurrent));
808 t->SetTextAlign(32);
809 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%g",fMaxCurrent));
810 }
811 }
812 delete t;
813}
814
815////////////////////////////////////////////////////////////////////////////////
816/// Print the axis main data.
817
818void TParallelCoordVar::Print(Option_t* /*option*/) const
819{
820 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
821 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
822 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// Save the TParallelCoordVar as a macro. Can be used only in the context
827/// of TParallelCoord::SavePrimitive (pointer "TParallelCoord* para" is
828/// defined in TParallelCoord::SavePrimitive) with the option "pcalled".
829
830void TParallelCoordVar::SavePrimitive(std::ostream & out, Option_t* options)
831{
832 TString opt = options;
833 if (opt.Contains("pcalled")) {
834 out<<" var->SetBit(TParallelCoordVar::kLogScale,"<<TestBit(kLogScale)<<");"<<std::endl;
835 out<<" var->SetBit(TParallelCoordVar::kShowBox,"<<TestBit(kShowBox)<<");"<<std::endl;
836 out<<" var->SetBit(TParallelCoordVar::kShowBarHisto,"<<TestBit(kShowBarHisto)<<");"<<std::endl;
837 out<<" var->SetHistogramBinning("<<fNbins<<");"<<std::endl;
838 out<<" var->SetHistogramLineWidth("<<fHistoLW<<");"<<std::endl;
839 out<<" var->SetInitMin("<<fMinInit<<");"<<std::endl;
840 out<<" var->SetInitMax("<<fMaxInit<<");"<<std::endl;
841 out<<" var->SetHistogramHeight("<<fHistoHeight<<");"<<std::endl;
842 out<<" var->GetMinMaxMean();"<<std::endl;
843 out<<" var->GetHistogram();"<<std::endl;
844 out<<" var->SetFillStyle("<<GetFillStyle()<<");"<<std::endl;
845 out<<" var->SetFillColor("<<GetFillColor()<<");"<<std::endl;
846 out<<" var->SetLineColor("<<GetLineColor()<<");"<<std::endl;
847 out<<" var->SetLineWidth("<<GetLineWidth()<<");"<<std::endl;
848 out<<" var->SetLineStyle("<<GetLineStyle()<<");"<<std::endl;
849 if (TestBit(kShowBox)) out<<" var->GetQuantiles();"<<std::endl;
850 TIter next(fRanges);
851 TParallelCoordRange* range;
852 Int_t i = 1;
853 while ((range = (TParallelCoordRange*)next())) {
854 out<<" //***************************************"<<std::endl;
855 out<<" // Create the "<<i<<"th range owned by the axis \""<<GetTitle()<<"\"."<<std::endl;
856 out<<" TParallelCoordSelect* sel = para->GetSelection(\""<<range->GetSelection()->GetTitle()<<"\");"<<std::endl;
857 out<<" TParallelCoordRange* newrange = new TParallelCoordRange(var,"<<range->GetMin()<<","<<range->GetMax()<<",sel);"<<std::endl;
858 out<<" var->AddRange(newrange);"<<std::endl;
859 out<<" sel->Add(newrange);"<<std::endl;
860 ++i;
861 }
862 }
863}
864
865////////////////////////////////////////////////////////////////////////////////
866/// Set the axis to display a candle.
867
869{
871 if (box) SetHistogramHeight(0.5);
872 else {
875 }
876}
877
878////////////////////////////////////////////////////////////////////////////////
879/// Set the histogram binning.
880
882{
883 if (n < 0 || n == fNbins) return;
884 fNbins = n;
885 GetHistogram();
886}
887
888////////////////////////////////////////////////////////////////////////////////
889/// Set the height of the bar histogram.
890
892{
893 fHistoHeight = h;
895 if(h!=0) SetBit(kShowBarHisto,kTRUE);
897 }
898}
899
900////////////////////////////////////////////////////////////////////////////////
901/// Set the current minimum of the axis.
902
904{
905 fMinCurrent = min;
906}
907
908////////////////////////////////////////////////////////////////////////////////
909/// Set the current maximum of the axis.
910
912{
913 fMaxCurrent = max;
914}
915
916////////////////////////////////////////////////////////////////////////////////
917/// Set the limits within which one the entries must be painted.
918
920{
921 if (min>max) {
922 Double_t mem = min;
923 min = max;
924 max = mem;
925 }
926 if(TestBit(kLogScale) && max<=0) return;
927 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
928 fMinCurrent = min;
929 fMaxCurrent = max;
930
931 delete fHistogram;
932 fHistogram = NULL;
933 GetHistogram();
934
938 }
939}
940
941////////////////////////////////////////////////////////////////////////////////
942/// If true, the pad is updated while the motion of a dragged range.
943
945{
946 TIter next(fRanges);
947 TParallelCoordRange* range;
948 while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kLiveUpdate,on);
949}
950
951////////////////////////////////////////////////////////////////////////////////
952/// Set the axis in log scale.
953
955{
956 if (log == TestBit (kLogScale)) return;
958 else if (log) {
959 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
960 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
964 } else {
968 }
969 GetQuantiles();
970 GetHistogram();
971}
972
973////////////////////////////////////////////////////////////////////////////////
974/// Set the variable values.
975
977{
978 if (fVal) delete [] fVal;
979 fVal = new Double_t[length];
980 fNentries = length;
981 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
983 GetHistogram();
985}
986
987////////////////////////////////////////////////////////////////////////////////
988/// Set the X position of the axis in the case of a vertical axis.
989/// and rotate the axis if it was horizontal.
990
992{
993 TFrame *frame = gPad->GetFrame();
994 if (!gl) {
995 fY1 = frame->GetY1();
996 fY2 = frame->GetY2();
997 } else {
1000 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1001 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
1002 }
1003 fX1 = fX2 = x;
1004}
1005
1006////////////////////////////////////////////////////////////////////////////////
1007/// Set the Y position of the axis in the case of a horizontal axis.
1008/// and rotate the axis if it was vertical.
1009
1011{
1012 TFrame *frame = gPad->GetFrame();
1013 if (!gl) {
1014 fX1 = frame->GetX1();
1015 fX2 = frame->GetX2();
1016 } else {
1019 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1020 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1021 }
1022 fY1 = fY2 = y;
1023}
@ kMouseMotion
Definition: Buttons.h:23
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kButton1Down
Definition: Buttons.h:17
@ kMouseEnter
Definition: Buttons.h:23
@ kArrowVer
Definition: GuiTypes.h:373
@ kArrowHor
Definition: GuiTypes.h:373
#define b(i)
Definition: RSha256.hxx:100
#define h(i)
Definition: RSha256.hxx:106
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:43
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
long long Long64_t
Definition: RtypesCore.h:71
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
@ kOrange
Definition: Rtypes.h:65
XFontStruct * id
Definition: TGX11.cxx:108
int nentries
Definition: THbookFile.cxx:89
double log(double)
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
#define gPad
Definition: TVirtualPad.h:287
#define gVirtualX
Definition: TVirtualX.h:338
#define snprintf
Definition: civetweb.c:1540
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
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 Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
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 Float_t GetTextSize() const
Return the text size.
Definition: TAttText.h:36
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
Create a Box.
Definition: TBox.h:24
Double_t GetX1() const
Definition: TBox.h:52
Double_t GetX2() const
Definition: TBox.h:53
Double_t GetY1() const
Definition: TBox.h:54
Double_t GetY2() const
Definition: TBox.h:55
The Canvas class.
Definition: TCanvas.h:27
Bool_t Contains(const char *name) const
Definition: TCollection.h:169
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Define a Frame.
Definition: TFrame.h:19
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8393
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:8006
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4907
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:8091
To draw Mathematical Formula.
Definition: TLatex.h:18
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2521
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2050
virtual void Paint(Option_t *option="")
Paint.
Definition: TLatex.cxx:2029
A simple line.
Definition: TLine.h:23
virtual void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition: TLine.cxx:384
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:821
virtual void AddAt(TObject *obj, Int_t idx)
Insert object at position idx in the list.
Definition: TList.cxx:305
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
Manages Markers.
Definition: TMarker.h:23
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
A TParallelCoordRange is a range used for parallel coordinates plots.
Bool_t IsIn(Double_t evtval)
Evaluate if the given value is within the range or not.
virtual void Paint(Option_t *options)
Paint a TParallelCoordRange.
virtual Double_t GetMin()
TParallelCoordSelect * GetSelection()
virtual Double_t GetMax()
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
const char * GetTitle() const
Returns title of object.
TParallelCoord axes.
TH1F * GetHistogram()
Create or recreate the histogram.
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 SetLogScale(Bool_t log)
Set the axis in log scale.
void PaintBoxPlot()
Paint the boxes in the case of a candle chart.
void PaintLabels()
Paint the axis labels and titles.
void PaintHistogram()
Paint the histogram on the axis.
void SetCurrentMin(Double_t min)
Set the current minimum of the axis.
void SavePrimitive(std::ostream &out, Option_t *options)
Save the TParallelCoordVar as a macro.
virtual void Print(Option_t *option="") const
Print the axis main data.
void SetLiveRangesUpdate(Bool_t on)
If true, the pad is updated while the motion of a dragged range.
void SetX(Double_t x, Bool_t gl)
Set the X position of the axis in the case of a vertical axis.
void SetY(Double_t y, Bool_t gl)
Set the Y position of the axis in the case of a horizontal axis.
void SetBoxPlot(Bool_t box)
Set the axis to display a candle.
void SetCurrentMax(Double_t max)
Set the current maximum of the axis.
TList * fRanges
[fNentries] Entries values for the variable.
void GetQuantiles()
Get the box plot values (quantiles).
void SetHistogramHeight(Double_t h=0)
Set the height of the bar histogram.
void DeleteVariable()
Delete variables.
TParallelCoordVar()
Histogram holding the variable distribution.
virtual void Draw(Option_t *option="")
Draw the axis.
TParallelCoord * fParallel
Bool_t Eval(Long64_t evtidx, TParallelCoordSelect *select)
Check if the entry is within the range(s) of "select".
virtual void Paint(Option_t *option="")
Paint the axis.
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...
virtual ~TParallelCoordVar()
Destructor.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes the distance from the axis.
void SetHistogramLineWidth(Int_t lw=2)
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Returns info about this axis.
void Init()
Initialise the TParallelVar variables.
virtual void ExecuteEvent(Int_t entry, Int_t px, Int_t py)
Execute the corresponding entry.
void GetXYfromValue(Double_t value, Double_t &x, Double_t &y)
Get a position corresponding to the value on the axis.
void GetMinMaxMean()
Get mean, min and max of those variable.
void SetValues(Long64_t length, Double_t *val)
Set the variable values.
void SetHistogramBinning(Int_t n=100)
Set the histogram binning.
void SetCurrentLimits(Double_t min, Double_t max)
Set the limits within which one the entries must be painted.
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.
UInt_t GetNvar()
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
Basic string class.
Definition: TString.h:131
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:1056
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:1122
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition: TText.h:75
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
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
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:754
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: first.py:1
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
#define mark(osub)
Definition: triangle.c:1206