I just spent a long time trying to work out how to draw an error band graph in ROOT without things looking completely ridiculous. Often ROOT will mess things up with Draw(“l3”) if you have data points that lie outside the range being plotted. To save others the major hassle involved, I’ve put my custom function here.

This function takes a TGraph or a TGraphAsymmErrors as an input and then draws the error band plot. Feel free to edit it for your own purposes of course. It enables you to create plots like:

An example of a plot using the DrawErrorBand() PyROOT function.

def DrawErrorBand(graph):
isErrorBand = graph.GetErrorYhigh(0) != -1 and graph.GetErrorYlow(0) != -1
npoints = graph.GetN()
if not isErrorBand:
graph.Draw("l same")
return
# Declare individual TGraph objects used in drawing error band
central, min, max = ROOT.TGraph(), ROOT.TGraph(), ROOT.TGraph()
shapes = []
for i in range((npoints-1)*4):
shapes.append(ROOT.TGraph())
# Set ownership of TGraph objects
ROOT.SetOwnership(central, False)
ROOT.SetOwnership( min, False)
ROOT.SetOwnership( max, False)
for shape in shapes:
ROOT.SetOwnership(shape, False)
# Get data points from TGraphAsymmErrors
x, y, ymin, ymax = [], [], [], []
for i in range(npoints):
tmpX, tmpY = ROOT.Double(0), ROOT.Double(0)
graph.GetPoint(i, tmpX, tmpY)
x.append(tmpX)
y.append(tmpY)
ymin.append(tmpY - graph.GetErrorYlow(i))
ymax.append(tmpY + graph.GetErrorYhigh(i))
# Fill central, min and max graphs
for i in range(npoints):
central.SetPoint(i, x[i], y[i])
min.SetPoint(i, x[i], ymin[i])
max.SetPoint(i, x[i], ymax[i])
# Fill shapes which will be shaded to create the error band
for i in range(npoints-1):
for version in range(4):
shapes[i+(npoints-1)*version].SetPoint((version+0)%4, x[i], ymax[i])
shapes[i+(npoints-1)*version].SetPoint((version+1)%4, x[i+1], ymax[i+1])
shapes[i+(npoints-1)*version].SetPoint((version+2)%4, x[i+1], ymin[i+1])
shapes[i+(npoints-1)*version].SetPoint((version+3)%4, x[i], ymin[i])
# Set attributes to those of input graph
central.SetLineColor(graph.GetLineColor())
central.SetLineStyle(graph.GetLineStyle())
central.SetLineWidth(graph.GetLineWidth())
min.SetLineColor(graph.GetLineColor())
min.SetLineStyle(graph.GetLineStyle())
max.SetLineColor(graph.GetLineColor())
max.SetLineStyle(graph.GetLineStyle())
for shape in shapes:
shape.SetFillColor(graph.GetFillColor())
shape.SetFillStyle(graph.GetFillStyle())
# Draw
for shape in shapes:
shape.Draw("f same")
min.Draw("l same")
max.Draw("l same")
central.Draw("l same")
ROOT.gPad.RedrawAxis()

### Like this:

Like Loading...

*Related*

DennisNice plot, you probably want to add a “RedrawAxis()”.

davidchall1Post authorThanks Dennis! I was wondering how to do this… (I’ve updated the code + plot)

AlkassHi! This is a nice code, I like it ðŸ˜‰ What the input of that should be ? Can it work with a plain TH1F?