Draw Lines on Histograms

HI, I’m new to ROOT and I’m trying to figure out how to add vertical lines (sort of like markers along the x-axis) to a histogram plot.

 self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ] = TH1F("IntenPosiKV", "Intensity vs Position (KV) for slice " + str(nz - iz) + " of " + str(nz), 270,0,270)
 self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ].Fill(iy, avgIntensity)

I tried this:

self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ].Add( TLine(0,10,0,100), const )

Any help is appreciated!


to draw lines on the same canvas where the histogram has been drawn, just draw the line with the “same” option.
You can have a look to these basic, but important, functionalities following the suggestions for beginners’ courses here root.cern.ch/getting-started .


Hi, the courses seem to be for C++ ROOT, while I’m currently using Pyroot at the moment.

When you say draw the line with the “same” option, do you mean:


I think you should take a look to the documentation nevertheless: it is full of examples of how to draw objects of various kinds. The translation to Python is straightforward.
And no, the line shall not be “added to the histogram” created and drawn separately.

1 Like

Is enough. No need for option “same”.

Hi, thanks for the tip - I’ll have a look at the documentation. Meanwhile I tried what you mentioned and the line didn’t appear. Could it because I have two canvases in the same loop?

Here’s the code in the loop:

for iz in range(nz):

        self.rootFile.mkdir( os.path.join( patient.id, str(iz) ) )   
        self.rootFile.cd( os.path.join( patient.id, str(iz) ) )
        self.histoDict[ patient.id ][ str(iz) ] = {}
        self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ] = TH1F("IntenPosiKV",\
                                                                     "Intensity vs Position (KV) for slice " + str(nz - iz) + " of " + str(nz),\
        self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ].SetXTitle( "Position along y-axis of image" )
        self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ].SetYTitle( "Average Intensity (Hounsfield Units)" )

        ixList = []

        for iy in range(ny):
          sumIntensity = 0

          for ix in range(nx):
            intensity = scan.imageStack[iy,ix,iz]
            # Frequency vs Intensity for KV scan
            self.histoDict[ patient.id ][ 'FreqIntKV' ].Fill(intensity)

            sumIntensity += intensity

            # Position of body
            if intensity > -400:
              if ix not in ixList:

          avgIntensity = sumIntensity / ny

          # Intensity vs position for each KV slice in scan
          self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ].Fill(iy, avgIntensity)

        ixList = sorted(ixList)
        ixListArranged = []
        for k, g in groupby( enumerate(ixList), lambda (i,x):i-x):
          ixListArranged.append( map(itemgetter(1),g) )   # Groups into lists of consecutive coordinates
        ixListLargest = max(ixListArranged, key = len)
        leftBound =  ixListLargest[0]
        rightBound =  ixListLargest[-1] 
        print "Left bound = " + str( leftBound ) + " for slice " + str(nz - iz)
        print "Right bound = " + str( rightBound ) + " for slice " + str(nz - iz)
        myLine = TLine( leftBound, -1000, leftBound, 1000 )
        myLine.Draw( "same" )

Also, rather than drawing the Histograms, I’ve actually saving them in a root file. Could that be why the myLine.Draw() can’t be saved?

Sorry I don’t follow you. Why would the I/O interfere in the plotting?
My suggestion would be to start from a simple test program, where you draw an histogram with a line on top.
Then, once this is under control, you can start fresh again with the code you put snippets of and redo the same.

Oui, and this:

myLine = TLine( leftBound, -1000, leftBound, 1000 ) myLine.Draw( "same" )
Second time brings ‘myLine’ reference count to null and Python deletes. Need to keep alive, e.g. by assigning to histogram:self.histoDict[ patient.id ][ str(iz) ][ "IntenPosiKV" ]._line = myLine

Can save TLine in file, but does not self redraw after loading histogram. Need load line and then draw as well.