TH2F Variable Data Point Colors


_ROOT Version: 5
_Platform: Scientific Linux 6.10
_Compiler: g++ 4.4.7


Hi everyone,

I am trying to plot a set of data points in a TH2F and I want the data points to have difference colors. Is it possible? Or would I have to try to merge several TH2F on the same TCanvas and then write that to a TH2F?

Here is a working example of what I am trying to do. I understand that the colour variable is overwritten every time SetMarkerColor() is called. I was wondering what would be the best way to go about making this work.

Thanks in advance!

#include <iostream>
#include <cmath>
#include <vector>
#include <TFile.h>
#include <TH2F.h>

using namespace std;

int main(){

  int i = 0;
  int j = 0;
  vector< vector<int> > Data;
	
  Data.resize(3);
	
  for(i = 0; i < 50; i++){
	
    Data[0].push_back(i); //Fill x-axis values
    Data[1].push_back(i * i); //Fill y-axis values
  
    if(remainder(i, 10) == 0){ //Change histogram colour every 10 entries
		
      j++;
    }
		
    Data[2].push_back(j);
   }
	
  TFile* rootout = TFile::Open("Data.root", "recreate");
  TH2F* h1 = new TH2F("Data", "Data", 52, 0, 52, 2510, 0, 2510);

  h1->GetXaxis()->SetTitle("i");
  h1->GetYaxis()->SetTitle("j");

  h1->SetMarkerSize(1);
  h1->SetMarkerStyle(2);
	
  for(i = 0; i < (int)Data[0].size(); i++){
	
    h1->Fill(Data[0][i], Data[1][i]); //Fill histogram with the first two columns of vector
    h1->SetMarkerColor(Data[2][i]); //Set histogram colour using the last column
  }
	
  h1->Write();
  rootout->Close();

  return 0;
}

Why don’t you draw the TH2F using the option COL ?

I have added

h1->Draw("COL");

just before the Write() call and re-run the code, but I don’t see any difference in the output. Am I missing something obvious?

EDIT: I thought “col” means that colour is added based on the number of entries in a bin. However, in my example above, each data point appears only once, so I think it makes sense, that “col” produces a single colour, as every bin is equally full. I was looking for some way to make one histogram that contains several different colours for data points, regardless of how full their respective bins are.

I am confused about the kind of plot you want to get …
Are you sure you want a TH2F ? what I see looks more like a TGraph plot.

The example I gave is somewhat simplified, but I was looking to plot a set of data points, where the colour of the data points changes depending on the value of the points. Can a TGraph do something like that?

So you have a a 3d data set (x,y,z) where x and y is the position and z the bin content (value) which defines the color. That is the description of a TH2F plot with option COL. https://root.cern/doc/master/classTHistPainter.html#HP14

All my z values are 1, so I wanted to implement colour not based on the values of z, but based on the value of x or y, while also plotting x and y, not z (since it’s always 1).

so z is meaningless/no used if all the z values are 1 … Use it to encode the color and the col option will do the job for you

Sorry, I think I may have misunderstood you previous post. The vector Data has three rows: one row is x-values, the second one is y-values (square of x in the example above), the third I tried using to encode the colour value of each point, i.e.

h1->SetMarkerColor(Data[2][i]);

A histogram of vector Data would have no bin size >1, since x-values are all unique, and y-values are all a square of x, and therefore unique too. So I don’t think I can rely on “col” to assign colour, since it uses bin amplitude to make colour decisions. I wanted to use the third row of the vector to assign colour, but that just overwrites the previous SetMarkerColor() setting.

I am sorry if I misunderstood your advice. Could you please write a small pseudocode of what you mean, if I misunderstood you?

If this method of doing colours is doomed and won’t work, any alternatives are also welcome!

{
  Int_t x, y, z;
  TTree *t = new TTree("t", "t");
  t->Branch("Xvalue", &x); t->Branch("Yvalue", &y); t->Branch("Zcolour", &z);
  t->SetMarkerStyle(2); t->SetMarkerSize(1);
  Int_t j = 0;
  for(Int_t i = 0; i < 50; i++) {
    if (!(i % 10)) j++; // change colour every 10 entries
    x = i; y = i * i; z = j;
    t->Fill();
  }
  t->ResetBranchAddresses(); // detach from local variables
  // t->Print();
  t->Draw("Yvalue : Xvalue : Zcolour", "", "col");
#if 0 /* 0 or 1 */
  TH2 *h = (gPad ? ((TH2*)(gPad->GetPrimitive("htemp"))) : ((TH2*)0));
  if (h) h->SetTitle("it is whatever it is;magic x values;magic y values");
  if (gPad) { gPad->Modified(); gPad->Update(); }
#endif /* 0 or 1 */
}
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.