pyROOT plot histogram in loop

Working on MacOS 14.4, python 3.12 root 6.30.04, I want to plot some lists of histograms on separate canvases, but currently they’re all being plotted on the final canvas.

Here’s a MWE, what I want is for all the blue histograms to be plotted on the first canvas and all the red histograms to be plotted on the second. Can anyone tell me what I’m doing wrong?

I’ve tried changing Draw("same") to DrawClone("same") but that results in a blank canvas.

import ROOT
from ROOT import TCanvas, gPad, kBlue, kRed

def histo_plotter(histo):
    ROOT.SetOwnership(histo,False)
    histo.Draw("same")
    return

class myclass:
    def __init__(self,run_no):
        self.run_no = run_no

    @staticmethod
    def canvas_creator(canv_name):
        my_canvas = TCanvas(canv_name,canv_name,900,700)
        return my_canvas

    @staticmethod
    def histo_maker(names,colour):
        h1=ROOT.TH1F(names[0],names[0],64,0,4)
        h1.FillRandom('gaus')
        h2=ROOT.TH1F(names[1],names[1],64,0,4)
        h2.FillRandom('gaus')

        h1.SetLineColor(colour)
        h2.SetLineColor(colour)
        
        histo_list = [h1,h2]
        return histo_list
        
def main():
    instances = [myclass(x) for x in range(2)]
    colours   = [kBlue, kRed]
    names     = [["h1", "h2"], ["h3","h4"]]
    
    histos = [instance.histo_maker(names[i_inst], colours[i_inst]) for i_inst, instance in enumerate(instances)]
    canvas_x_signals = [instance.canvas_creator(f"x_signals_{instance.run_no}") for instance in instances]
    
    for i_canv, canv in enumerate(canvas_x_signals):
        ROOT.SetOwnership(canv, False)
        [histo_plotter(x_histo) for x_histo in histos[i_canv]]
         canv.Modified()
        canv.Update()
        #    gPad.Update()
  
if __name__ == '__main__':
    main()

result:

Hi,

Thanks for the smooth reproducer!
It’s enough to “cd” into the canvas where you need to draw your histogram. In other words, if I understand correctly, you can achieve what you need with

# ...
for i_canv, canv in enumerate(canvas_x_signals):
        ROOT.SetOwnership(canv, False)
        canv.cd() # <---- This is the line missing in your code
        [histo_plotter(x_histo) for x_histo in histos[i_canv]]
        canv.Modified()
        canv.Update()
# ...

Please correct me if I misunderstood your goal!

Cheers,
Danilo

1 Like

Thanks that’s perfect!

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