Random behavior when drawing tree on multiple pads

Hi,
I am trying to draw a tree on multiple pads with different options. However, the results varied when I run the SAME code several times. The first one is what I expected:


But for most of the time, I got the latter one.
Here is the macro I wrote to perform the drawing:

auto DrawT(TTree *const tree, const std::vector<size_t>& nEnts){	
	auto TC = new TCanvas();
	TC->Divide(2, 2);
	int colorInd = 0;
	size_t tcInd = 0;
	auto trd = tree->CloneTree();
	auto cBr = trd->Branch("color", &colorInd, "color/i");
	std::vector<const char*> nameV;
	for(auto branch: *(tree->GetListOfBranches()))	
		nameV.push_back(branch->GetName());
	for(size_t nEnt: nEnts){
		for(size_t i = 0; i != nEnt; ++i)
			cBr->Fill();
		++colorInd;
	}    //Draw different trees with different colors
	trd->SetMarkerStyle(8);
	do{
		std::stringstream ss;
		ss<<nameV[0]<<':'<<nameV[1]<<':'<<nameV[2]<<':'<<"color";
		TC->cd(++tcInd);    //Draw different combinations on different pads
		trd->Draw(ss.str().c_str(), "1");
	}while(next_combination(nameV.begin(), nameV.begin()+3, nameV.end()));
	return TC;
}

next_combination is a function I copied from StackOverflow which generates combinations of elements in a collection. I assume it worked just fine since I have tested it in ROOT prompt separately.

Here is the code I entered in the prompt:

.L $PATH_TO_THE_MACRO
TTree *tDat = new TTree("train","data from csv file");
tDat->ReadFile("$PATH_TO_THE_CSV_FILE", "var0/D:var1/D:var2/D:var3/D", ',');
auto cdr = DrawT(tDat, {40, 40, 40})     //(TCanvas *) @0x7fffc008ea00

Additional information may help:
I noticed that 4 graphs were drawn (the expected behavior) only when something was drawn previously, i.e. a TF1 function, but sometimes there were still 3 graphs drawn in this condition.
ROOT Version: 6.20/02
Platform: Arch Linux on WSL
Compiler: I installed the package from Arch community repository.

I have just noticed that the function I called in the prompt is an overloaded one of the macro I posted. I wrote it to pass initializer list literal instead of a vector. To avoid confusion, the overloaded one is posted here:

auto DrawT(TTree *const tree, const std::initializer_list<size_t>& nEnts){
	return DrawT(tree, std::vector<size_t>(nEnts));
}

I do not see why you would get different plots if you do exactly the same thing several times: If you plot the same variables from the same tree using the same selections you should get the same plots. Do you have you a reproducer we can run ?

I tried to put all the codes in a single file but things changed again. When I load the macro file and run the macro file with command root rep.cc, sometimes 3 plots were drawn but sometimes 2. Anyway this condition resembles the one I described initially, so I just post the macro here.

Please notice that the macro includes a CSV txt file.
rep.cc (1.8 KB) iris_train.txt (2.6 KB)

Your macro seems to have a problem. Can you fix ?

root [0]  .x rep.cc
Processing rep.cc...
In file included from input_line_8:1:
/Users/couet/Downloads/rep.cc:35:1: error: 'auto' return without trailing return type; deduced return types are a C++14 extension
auto DrawT(TTree *const tree, const std::vector<size_t>& nEnts){        
^
/Users/couet/Downloads/rep.cc:61:9: error: cannot initialize return object of type 'int' with an lvalue of type 'TCanvas *'
        return TC;
               

The problem was possibly caused by the different ROOT compile options. I learned that the ROOT provided by Arch community repository is complied with C++17 option enabled so the macro works on my machine. I edited my macro to give DrawT() an explicit return type and this should fix. However, I can’t make sure about the condition on your machine.
rep.cc (1.8 KB)

You macro runs now. I get many warnings:

root [0] 
Processing rep.cc...
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 1
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 2
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 3
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 4
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 5
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 6
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 7
Warning in <TTree::ReadStream>: Ignoring trailing ",1,0,0" while reading line 8
[...]

and the two following plots:

What is wrong ?

I didn’t read the entire row of the txt file so the trailing value caused the warnings. It’s pretty weird that on my machine I got this:

And this for another try:

You mean restarting ROOT ? or an other try in the same ROOT session ?
I just tried several times restarting ROOT. I get always the same.

I run the macro by passing it as a command line argument: root rep.cc, so I do restarted ROOT each time and I never got a complete version with all 4 plots. It seems to be a platform related problem?

Try to add, right before “return TC;”:
TC->cd(0); TC->Modified(); TC->Update();

I tried but the problem remained. Thank you for your attention anyway.

Which ROOT version ? On which machine ?

ROOT Version: 6.20/02
Platform: Arch Linux on WSL
Compiler: I installed the package from Arch community repository.

And this is what uname -a command prints:
Linux $HOSTNAME 4.4.0-18362-Microsoft #476-Microsoft Fri Nov 01 16:53:00 PST 2019 x86_64 GNU/Linux

I solved the problem in a even more weird way. After I separate the loop which generates combinations of strings I noticed that the problem occurred within that loop. It had nothing to do with the drawing but the combinations generated were incomplete. I modified my code as below and it worked. Still confusing about what caused the problem though.

auto DrawT(TTree *const tree, const std::vector<size_t>& nEnts){	
	auto TC = new TCanvas();
	TC->Divide(2, 2);
	int colorInd = 0;
	size_t tcInd = 0;
	auto trd = tree->CloneTree();
	auto cBr = trd->Branch("color", &colorInd, "color/i");
    //std::vector<const char*> nameV;
	std::vector<std::string> nameV;
	for(auto branch: *(tree->GetListOfBranches()))	
        //nameV.push_back(branch->GetName());
		nameV.emplace_back(branch->GetName());
	for(size_t nEnt: nEnts){
		for(size_t i = 0; i != nEnt; ++i)
			cBr->Fill();
		++colorInd;
	}
	trd->SetMarkerStyle(8);
	do{
		std::stringstream ss;
		ss<<nameV[0]<<':'<<nameV[1]<<':'<<nameV[2]<<':'<<"color";
		TC->cd(++tcInd);
		trd->Draw(ss.str().c_str(), "1");
	}while(next_combination(nameV.begin(), nameV.begin()+3, nameV.end()));
	return TC;
}