Scatter plot (with colorbar) in pyroot

Hi!
This is my first post here, so excuse me if it is a repeated question (although I searched for similar posts).

I am completely new with Root, and I started learning it with with pyroot. Right now, my project consists in making a TTree and fill it with branches (containing some parameters from simulation output files). The reading of that output files is made by a program in python that storages arrays (for example, position along x and y axis and signal detected) and I am interested in make a scatter-colored plot like the image below:

That figure was made by matplotlib.pyplot.scatter and I want to reproduce something similar with Pyroot and save it like .png and .root (if necessary to edit it in the future without losing time reading it again), any ideas for this?

I only found results for histograms and I must note that this is NOT a histogram (we have dispersed points with no “grid” or “matrix” correlation), just a “value” for each “(x,y) pair”.

Thanks in advance!

You can create a TGraph2D and draw it using its own draw options or using options supported for 2D histograms.

If you want a nice plot, you’d better stay with “matplotlib.pyplot” (which you can also call from PyROOT).

Tank you for your answer. I made some test TGraph2D’s with few points and everything went OK, but now I am implementing this to my python program and something is not working (maybe a “bad” translation of python-to-root arrays?). Here is an example of my code:

import numpy as np
import matplotlib.pyplot as plt
import os
from array import array
from ROOT import TGraph2D
from ROOT import TCanvas, TPaveText, TPad, TF2
from ROOT import gROOT, gStyle

(...Reading part of the .dat file and storage 3 arrays: signal, x_column and y_column...)

Number_of_points = len(signal)
signal_2 = array( 'd', [0.] )
x_column_2 = array( 'd', [0.] )
y_ column_2 = array( 'd', [0.] )

for i in range( Number_of_points ):
    
    if i == 0: # First iteration:
        signal_2[0] = signal[i]
        x_column_2[0] = x_column[i]
        y_column_2[0] = y_column[i]
    else:
        signal_2.append(signal[i])
        x_column_2.append(x_column[i])
        y_column_2.append(y_column[i])
       
c1 = TCanvas( 'c1', 'Example of plot', 200, 10, 700, 900 )

graph = TGraph2D(Number_of_points ,x_column_2,y_column_2,signal_2)
graph.Draw("TRI1")
c1.SaveAs("my_signal.png")

The problem is in the last line, if I try to save the image the terminal gets frozen and doesn’t save anything (the same occurs if I save it as a .root file).
The main difference between my previous TGraph2D “quick examples” and this program lies in the arrays interpretation. Here, an (succesfull) example:

from array import array
x = array( 'd',[1,2,3,4,5] )
y = array( 'd', [20,24,29,36,45] )
z = array( 'd', [10,0,90,160,250] )
c = ROOT.TCanvas("c")
gr4 = ROOT.TGraph2D(5,x,y,z)
gr4.Draw()
c.Draw()
c.SaveAs("example.png")

Thanks again! :sweat_smile:

Try:

graph = TGraph2D(Number_of_points)
for i in range(Number_of_points): graph.SetPoint(i, x_column[i], y_column[i], signal[i])

Still happening the same…

Thinking about it, maybe it’s a better idea saving these 3 arrays in a TTree, make other program that read them and make a matplotlib.pyplot.scatter plot.
Now I have the following question: Is it possible to save an image (.png, .pdf, etc) in a TBranch?

If the “Number_of_points” is big, the Delaunay triangulation may take a lot of time.

BTW. just to make sure … try to add “c1.Update()” right after “Draw”.

1 Like

Again, it gets frozen (sorry for not attaching more info, no output message is displayed by the terminal…)

I tried to do the same but with lighter arrays (with only 2-3 elements per array) and still getting the same behavior, so I think it must be of the data type (but my arrays are composed by simple floats, I’m a little bit confused here), do Root understand the same type of floats that Python?

Despite all I learned that is not convenient make this type of plots with huge arrays like mine (~ 10000 points per plot), and build the data-plot program with matplotlib may be a better way. Thanks for your help @Wile_E_Coyote

There should be no problem with Python “float” (which is C / C++ “double”).

import ROOT
x = [1,2,3,4,5]
y = [20,24,29,36,45]
z = [10,0,90,160,250]
Number_of_points = len(z)
graph = ROOT.TGraph2D(Number_of_points)
for i in range(Number_of_points): graph.SetPoint(i, x[i], y[i], z[i])
c = ROOT.TCanvas("c")
graph.SetMarkerStyle(20); graph.Draw("PCOL Z")
c.SaveAs("example.png")
1 Like

This is weird but… It works! :sweat_smile: :rofl:

Maybe the issue was in the creation and update of the Canvas, I mixed parts and variables of different previous examples and that could be the hidden problem… I don’t know exactly why but your example was succesfull, @Wile_E_Coyote.
Thanks for your help! :grinning: