pyROOT memory management and the TCanvas

Today I ran into a rather nasty behavior of pyROOT. While this draws a line to the canvas:

def plot1():
    c = ROOT.TCanvas('c', 'c')
    l = ROOT.TLine(0, 0, 1, 1)
    l.Draw()
    c.SaveAs('plot1.png')

plot1()

and this draws a line to the canvas:

def aux2():
    l = ROOT.TLine(0, 0, 1, 1)
    return l

def plot2():
    c = ROOT.TCanvas('c', 'c')
    l = aux2()
    l.Draw()
    c.SaveAs('plot2.png')

plot2()

the following does NOT draw a line to the canvas:

def aux3():
    l = ROOT.TLine(0, 0, 1, 1)
    l.Draw()

def plot3():
    c = ROOT.TCanvas('c', 'c')
    aux3()
    c.SaveAs('plot3.png')

plot3()

It seems that in the latter case, the TLine gets garbage-collected aggressively enough to not be plotted at all. This behavior surprised me, because in libraries like Qt or matplotlib the canvas maintains a reference to the graphics once drawn, preventing this from happening. Is there any proposal to make pyROOT’s memory management smarter in cases like this?

mwe.py (491 Bytes)

Try DrawClone:

def aux3():
    l = ROOT.TLine(0, 0, 1, 1)
    l.DrawClone()

def plot3():
    c = ROOT.TCanvas('c', 'c')
    aux3()
    c.SaveAs('plot3.png')

plot3()

That seems reasonable enough. As an academic question, how does ROOT manage the memory for the clone? Is it garbage-collected?

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