Exemple #1
0
    def create_canvas(self, ratio=True):
        if ratio:
            self.canvas = Canvas(width=700, height=700)
            self.canvas.Draw()
            self.canvas.cd()
            self.main_pad = Pad(0., 0.25, 1., 1.)
            self.main_pad.Draw()
            self.canvas.cd()
            self.ratio_pad = Pad(0., 0., 1., 0.25)
            self.ratio_pad.Draw()

            self.main_pad.SetTicks(True)
            self.main_pad.SetBottomMargin(0.)
            self.main_pad.SetLeftMargin(0.15)
            self.main_pad.SetRightMargin(0.15)
            self.ratio_pad.SetLeftMargin(0.15)
            self.ratio_pad.SetRightMargin(0.15)
            self.ratio_pad.SetTopMargin(0.)
            self.ratio_pad.SetGridy()
            self.ratio_pad.SetBottomMargin(0.3)

        else:
            self.canvas = Canvas(width=700, height=700)
            self.canvas.Draw()
            self.canvas.cd()
            self.main_pad = Pad(0., 0., 1., 1.)
            self.main_pad.Draw()
            self.canvas.cd()
            self.ratio_pad = Pad(-1., -1., -.9, -.9)
            self.ratio_pad.Draw()  # put it outside the canvas
            self.main_pad.SetTicks(True)
            self.main_pad.SetTopMargin(0.15)
            self.main_pad.SetBottomMargin(0.15)
            self.main_pad.SetLeftMargin(0.15)
            self.main_pad.SetRightMargin(0.15)
Exemple #2
0
    def __init__(self, width=None, height=None,
                 xtitle=None, ytitle=None,
                 tick_length=15,
                 logy=False):

        super(SimplePlot, self).__init__(width=width, height=height)
        left, right, bottom, top = self.margin
        self.SetMargin(0, 0, 0, 0)

        # top pad for histograms
        with self:
            main = Pad(0., 0., 1., 1.)
            if logy:
                main.SetLogy()
            main.margin = (left, right, bottom, top)
            main.Draw()

        # draw axes
        with main:
            main_hist = Hist(1, 0, 1)
            main_hist.Draw('AXIS')

        if xtitle is not None:
            main_hist.xaxis.title = xtitle
        if ytitle is not None:
            main_hist.yaxis.title = ytitle

        # set the tick lengths
        tick_length_pixels(main, main_hist.xaxis, main_hist.yaxis,
                           tick_length)

        self.main = main
        self.main_hist = main_hist
        self.logy = logy
Exemple #3
0
                    if args.underflow:
                        h.SetBinContent(1,
                                        h.GetBinContent(1) +
                                        h.GetBinContent(0))  #
#                        h = h.merge_bins([(0, 1),])

                    h.drawstyle = 'hist'
                    h.color = sigCOLORS[i]
                    h.legendstyle = 'L'
                    h.linewidth = 2
                    hs.append(h)
                    legItems.append(h)

            if args.dataset == 'all':
                # divide canvas to draw ratio
                mainPad = Pad(0, 0.25, 1, 1.)
                mainPad.SetBottomMargin(0.0)
                mainPad.Draw()
                subPad = Pad(0, 0.05, 1, 0.24)
                subPad.SetTopMargin(0.02)
                subPad.SetBottomMargin(0.25)
                subPad.Draw()
            else:
                mainPad = ROOT.gPad

            mainPad.cd()
            legend = Legend(legItems,
                            pad=mainPad,
                            margin=0.25,
                            leftmargin=0.45,
                            topmargin=0.02,
Exemple #4
0
#bg_scaled_cut = Cut("1")#Cut("pileupWeight*normweight*mcEventWeight*"+str(lumipb)) * cut
#top_cutfix    =  bg_scaled_cut

#WW_cutfix     = Cut("mcChannelNumber!=361068") * bg_scaled_cut

#==================== BEGINS ================================#

for (variable, xmin, xmax, nbins, xtitle,
     ytitle) in zip(variable_list, xmin_list, xmax_list, nbins_list,
                    xtitle_list, ytitle_list):
    # Canvas Variables and declaration
    canvas = Canvas(width=700, height=500)
    bottom_padmargin = 0.0
    left_padmargin = 0.0
    right_padmargin = 0.0
    pad = Pad(left_padmargin, 0.15 - bottom_padmargin, 1 - right_padmargin,
              0.95)
    #    pad.SetTopMargin(0.2)
    pad.Draw()
    pad.cd()
    # if variable != 'RISR':
    #pad.SetLogy()
    pad.SetLogy()
    pad.SetGrid()

    #    pad    = Canvas(0,0.3,1,1)

    ##### KEEP THIS
    #    canvas.Divide(1, 2)

    #    pad = canvas.cd(1)
    canvas = Canvas(width=canvaswidth,height=int((1-(1-doRatio)*0.2)*canvasheight))
    canvas.SetFrameBorderMode(0)

    topmargins    = (1.0 , 1.0 )
    bottommargins = (0.0  , 0.4  )
    leftmargins   = (0.0  , 0.0  )
    rightmargins  = (0.0  , 0.0  )
    
    top    = topmargins[doRatio]
    bottom = bottommargins[doRatio]
    left   = leftmargins[doRatio]
    right  = 1 - rightmargins[doRatio]

    canvas.cd()

    histpad = Pad(left,bottom,right, top,color="white",bordersize =5)
    if not doRatio:
        histpad.SetBottomMargin(0.15)

    histpad.SetFrameBorderMode(0)

    histpad.Draw()
    histpad.SetLogy()
    histpad.cd()
    histpad.SetFrameBorderSize(2)
    histpad.SetFrameLineWidth(2);

    canvas.cd()
    #ratiopad    = Pad(leftmargins[1],0.00,1 - rightmargins[1],bottommargins[1]-0.02)
    ratiopad    = Pad(leftmargins[1],0.00,1 - rightmargins[1],bottommargins[1]-0.02)
    ratiopad.SetBottomMargin(0.33)
        normalisations = {}
        hists = {}
        maxY = 0
        minY = 99999999

        for f in files:
            normalisations[f] = read_tuple_from_file(files[f])['QCD']
            hists[f] = value_error_tuplelist_to_hist(
                normalisations[f], reco_bin_edges_vis[variable]).Rebin(2)
            maxY = max([maxY] + list(hists[f].y()))
            minY = min([minY] + list(hists[f].y()))

        if minY <= 0: minY = 0.1

        can = Canvas()
        pad1 = Pad(0, 0.3, 1, 1)
        pad2 = Pad(0, 0, 1, 0.3)
        pad1.Draw()
        pad2.Draw()
        pad1.cd()

        # print normalisations
        hists['central'].SetLineColor(2)
        hists['central'].SetLineWidth(3)
        hists['central'].SetLineStyle(3)
        hists['central'].GetYaxis().SetRangeUser(minY * 0.9, maxY * 1.2)
        hists['central'].Draw('HIST E')

        hists['QCD_signal_MC'].SetLineColor(4)
        hists['QCD_signal_MC'].SetLineWidth(3)
        hists['QCD_signal_MC'].SetLineStyle(1)
Exemple #7
0
    def __init__(self,
                 width=None,
                 height=None,
                 offset=0,
                 ratio_height=None,
                 ratio_margin=26,
                 ratio_limits=(0, 2),
                 ratio_divisions=4,
                 prune_ratio_ticks=False,
                 ratio_line_values=(1, ),
                 ratio_line_width=2,
                 ratio_line_style='dashed',
                 xtitle=None,
                 ytitle=None,
                 ratio_title=None,
                 tick_length=15,
                 logy=False):

        # first init as normal canvas
        super(RatioPlot, self).__init__(width=width, height=height)

        # get margins in pixels
        left, right, bottom, top = self.margin_pixels
        default_height = self.height
        default_frame_height = default_height - bottom - top

        if ratio_height is None:
            ratio_height = default_height / 4.

        self.height += int(ratio_height) + ratio_margin + offset
        self.margin = (0, 0, 0, 0)

        main_height = default_frame_height + top + ratio_margin / 2. + offset
        ratio_height += ratio_margin / 2. + bottom

        # top pad for histograms
        with self:
            main = Pad(0., ratio_height / self.height, 1., 1.)
            if logy:
                main.SetLogy()
            main.margin_pixels = (left, right, ratio_margin / 2., top)
            main.Draw()

        # bottom pad for ratio plot
        with self:
            ratio = Pad(0, 0, 1, ratio_height / self.height)
            ratio.margin_pixels = (left, right, bottom, ratio_margin / 2.)
            ratio.Draw()

        # draw main axes
        with main:
            main_hist = Hist(1, 0, 1)
            main_hist.Draw('AXIS')

        # hide x-axis labels and title on main pad
        xaxis, yaxis = main_hist.xaxis, main_hist.yaxis
        xaxis.SetLabelOffset(1000)
        xaxis.SetTitleOffset(1000)
        # adjust y-axis title spacing
        yaxis.SetTitleOffset(yaxis.GetTitleOffset() * self.height /
                             default_height)

        # draw ratio axes
        with ratio:
            ratio_hist = Hist(1, 0, 1)
            ratio_hist.Draw('AXIS')

        # adjust x-axis label and title spacing
        xaxis, yaxis = ratio_hist.xaxis, ratio_hist.yaxis

        xaxis.SetLabelOffset(xaxis.GetLabelOffset() * self.height /
                             ratio_height)
        xaxis.SetTitleOffset(xaxis.GetTitleOffset() * self.height /
                             ratio_height)
        # adjust y-axis title spacing
        yaxis.SetTitleOffset(yaxis.GetTitleOffset() * self.height /
                             default_height)

        if ratio_limits is not None:
            low, high = ratio_limits
            if prune_ratio_ticks:
                delta = 0.01 * (high - low) / float(ratio_divisions % 100)
                low += delta
                high -= delta
            yaxis.SetLimits(low, high)
            yaxis.SetRangeUser(low, high)
            yaxis.SetNdivisions(ratio_divisions)

        if xtitle is not None:
            ratio_hist.xaxis.title = xtitle
        if ytitle is not None:
            main_hist.yaxis.title = ytitle
        if ratio_title is not None:
            ratio_hist.yaxis.title = ratio_title

        # set the tick lengths
        tick_length_pixels(main, main_hist.xaxis, main_hist.yaxis, tick_length)
        tick_length_pixels(ratio, ratio_hist.xaxis, ratio_hist.yaxis,
                           tick_length)

        # draw ratio lines
        lines = []
        if ratio_line_values:
            with ratio:
                for value in ratio_line_values:
                    line = Line(0, value, 1, value)
                    line.linestyle = ratio_line_style
                    line.linewidth = ratio_line_width
                    line.Draw()
                    lines.append(line)
        self.lines = lines

        self.main = main
        self.main_hist = main_hist
        self.ratio = ratio
        self.ratio_hist = ratio_hist
        self.ratio_limits = ratio_limits
        self.logy = logy
Exemple #8
0
        # draw the text we need
        textConfigs = plots.get('config', {}).get('texts', [])
        textLocals = plots_path.get('texts', [])
        for text in chain(textConfigs, textLocals):
          # attach the label
          label = ROOT.TLatex(text['x'], text['y'], text['label'])
          label.SetTextFont(text['font'])
          label.SetTextSize(text['size'])
          label.SetNDC()
          label.Draw()

        # draw the ratio
        if plots_path.get('ratio', plots_config.get('ratio', False)):
          canvas.get_pad(0).set_bottom_margin(0.3)
          p = Pad(0,0,1,1)  # create new pad, fullsize to have equal font-sizes in both plots
          #p.set_top_margin(1-canvas.get_bottom_margin())  # top-boundary (should be 1-thePad->GetBottomMargin())
          p.set_top_margin(1-canvas.get_pad(0).get_bottom_margin())  # top-boundary (should be 1-thePad->GetBottomMargin())
          p.set_right_margin(canvas.get_right_margin())
          p.set_left_margin(canvas.get_left_margin())
          p.set_fill_style(0)  # needs to be transparent
          p.set_gridy(True)
          p.Draw()
          p.cd()

          # do ratio for each histogram in solo hist
          for i,hist in enumerate(soloHists):
            # if (i>0): continue

            ratio = Hist.divide(hist, sum(hstack))
            ratio.draw("same")
Exemple #9
0
        stack.sum.Integral()
    except:
        print "stack has no integral!"
        continue

    if plotWithMPL:
        gs = mpl.gridspec.GridSpec(2, 1, height_ratios=[4, 1])
        gs.update(wspace=0.00, hspace=0.00)
        axes = plt.subplot(gs[0])
        axes_ratio = plt.subplot(gs[1], sharex=axes)
        plt.setp(axes.get_xticklabels(), visible=False)

    if plotWithROOT:
        c = Canvas(700, 700)
        c.cd()
        pad1 = Pad(0, 0.3, 1, 1.0)
        pad1.SetBottomMargin(0)
        # Upper and lower plot are joined
        pad1.SetGrid()
        # Vertical grid
        pad1.Draw()
        # Draw the upper pad: pad1
        c.cd()
        pad2 = Pad(0, 0.05, 1, 0.3)
        pad2.SetTopMargin(0)
        # Upper and lower plot are joined
        pad2.SetBottomMargin(0.3)
        # Upper and lower plot are joined
        pad2.SetGrid()
        # Vertical grid
        pad2.Draw()
Exemple #10
0
    def draw_to_canvas(self):
        """
        Draw this figure to a canvas, which is then returned.
        """
        if len(self._plottables) == 0:
            raise IndexError("No plottables defined")
        c = Canvas(width=self.style.canvasWidth,
                   height=self.style.canvasHeight,
                   size_includes_decorations=True)
        if self.legend.position == 'seperate':
            legend_width = .2
            pad_legend = Pad(1 - legend_width, 0, 1., 1., name="legend")
            pad_legend.SetLeftMargin(0.0)
            pad_legend.SetFillStyle(0)  # make this pad transparent
            pad_legend.Draw()
        else:
            legend_width = 0
        pad_plot = Pad(
            0.,
            0.,
            1 - legend_width,
            1.,
            name="plot",
        )
        pad_plot.SetMargin(*self.style.plot_margins)
        pad_plot.Draw()
        pad_plot.cd()

        # awkward hack around a bug in get limits where everything fails if one plottable is shitty...
        xmin, xmax, ymin, ymax = None, None, None, None
        for pdic in self._plottables:
            try:
                limits = get_limits(pdic['p'],
                                    logx=self.plot.logx,
                                    logy=self.plot.logy)
                # Beware: Python 2 evaluates min/max of None in an undefined way with no error! Wow...
                xmin = min([xmin, limits[0]
                            ]) if xmin is not None else limits[0]
                xmax = max([xmax, limits[1]
                            ]) if xmax is not None else limits[1]
                ymin = min([ymin, limits[2]
                            ]) if ymin is not None else limits[2]
                ymax = max([ymax, limits[3]
                            ]) if ymax is not None else limits[3]
            except (TypeError, ValueError):
                # some plottables do not work with this rootpy function (eg. graph without points, tf1)
                # TODO: should be fixed upstream
                pass
        # overwrite these ranges if defaults are given
        if self.plot.xmin is not None:
            xmin = self.plot.xmin
        if self.plot.xmax is not None:
            xmax = self.plot.xmax
        if self.plot.ymax is not None:
            ymax = self.plot.ymax
        if self.plot.ymin is not None:
            ymin = self.plot.ymin

        if not all([val is not None for val in [xmin, xmax, ymin, ymax]]):
            raise TypeError(
                "unable to determine plot axes ranges from the given plottables"
            )

        colors = get_color_generator(self.plot.palette,
                                     self.plot.palette_ncolors)

        # draw an empty frame within the given ranges;
        frame_from_plottable = [
            p for p in self._plottables if p.get('use_as_frame')
        ]
        if len(frame_from_plottable) > 0:
            frame = frame_from_plottable[0]['p'].Clone('__frame')
            frame.Reset()
            frame.SetStats(0)
            frame.xaxis.SetRangeUser(xmin, xmax)
            frame.yaxis.SetRangeUser(ymin, ymax)
            frame.GetXaxis().SetTitle(self.xtitle)
            frame.GetYaxis().SetTitle(self.ytitle)
            self._theme_plottable(frame)
            frame.Draw()
        else:
            frame = Graph()
            frame.SetName("__frame")
            # add a silly point in order to have root draw this frame...
            frame.SetPoint(0, 0, 0)
            frame.GetXaxis().SetLimits(xmin, xmax)
            frame.GetYaxis().SetLimits(ymin, ymax)
            frame.SetMinimum(ymin)
            frame.SetMaximum(ymax)
            frame.GetXaxis().SetTitle(self.xtitle)
            frame.GetYaxis().SetTitle(self.ytitle)
            self._theme_plottable(frame)
            # Draw this frame: 'A' should draw the axis, but does not work if nothing else is drawn.
            # L would draw a line between the points but is seems to do nothing if only one point is present
            # P would also draw that silly point but we don't want that!
            frame.Draw("AL")

        xtick_length = frame.GetXaxis().GetTickLength()
        ytick_length = frame.GetYaxis().GetTickLength()

        for i, pdic in enumerate(self._plottables):
            obj = pdic['p']
            if isinstance(obj, ROOT.TLegendEntry):
                _root_color = Color(pdic['color'])
                _root_markerstyle = MarkerStyle(pdic['markerstyle'])
                obj.SetMarkerStyle(_root_markerstyle('root'))
                obj.SetMarkerColor(_root_color('root'))

            elif isinstance(obj, (ROOT.TH1, ROOT.TGraph, ROOT.TF1)):
                self._theme_plottable(obj)
                obj.SetMarkerStyle(pdic.get('markerstyle', 'circle'))
                if pdic.get('color', None):
                    obj.color = pdic['color']
                else:
                    try:
                        color = next(colors)
                    except StopIteration:
                        log.warning("Ran out of colors; defaulting to black")
                        color = 1
                    obj.color = color
                xaxis = obj.GetXaxis()
                yaxis = obj.GetYaxis()

                # Set the title to the given title:
                obj.title = self.title

                # the xaxis depends on the type of the plottable :P
                if isinstance(obj, ROOT.TGraph):
                    # SetLimit on a TH1 is simply messing up the
                    # lables of the axis to screw over the user, presumably...
                    xaxis.SetLimits(xmin, xmax)
                    yaxis.SetLimits(ymin, ymax)  # for unbinned data
                    # 'P' plots the current marker, 'L' would connect the dots with a simple line
                    # see: https://root.cern.ch/doc/master/classTGraphPainter.html for more draw options
                    drawoption = 'Psame'
                elif isinstance(obj, ROOT.TH1):
                    obj.SetStats(0)
                    xaxis.SetRangeUser(xmin, xmax)
                    yaxis.SetRangeUser(ymin, ymax)
                    drawoption = 'same'
                elif isinstance(obj, ROOT.TF1):
                    # xaxis.SetLimits(xmin, xmax)
                    # yaxis.SetLimits(ymin, ymax)  # for unbinned data
                    drawoption = 'same'
                obj.Draw(drawoption)
            # Its ok if obj is non; then we just add it to the legend.
            else:
                raise TypeError("Un-plottable type given.")
        pad_plot.SetTicks()
        pad_plot.SetLogx(self.plot.logx)
        pad_plot.SetLogy(self.plot.logy)
        pad_plot.SetGridx(self.plot.gridx)
        pad_plot.SetGridy(self.plot.gridy)

        # do we have legend titles?
        if any([pdic.get('legend_title') for pdic in self._plottables]):
            leg = self._create_legend()
            longest_label = 0
            for pdic in self._plottables:
                if not pdic.get('legend_title', False):
                    continue
                leg.AddEntry(pdic['p'], pdic['legend_title'])
                if len(pdic['legend_title']) > longest_label:
                    longest_label = len(pdic['legend_title'])

            # Set the legend position
            # vertical:
            if self.legend.position.startswith('t'):
                leg_hight = leg.y2 - leg.y1
                leg.y2 = 1 - pad_plot.GetTopMargin() - ytick_length
                leg.y1 = leg.y2 - leg_hight
            elif self.legend.position.startswith('b'):
                leg_hight = leg.y2 - leg.y1
                leg.y1 = pad_plot.GetBottomMargin() + ytick_length
                leg.y2 = leg.y1 + leg_hight
            # horizontal:
            if self.legend.position[1:].startswith('l'):
                leg_width = 0.3
                leg.x1 = pad_plot.GetLeftMargin() + xtick_length
                leg.x2 = leg.x1 + leg_width
            elif self.legend.position[1:].startswith('r'):
                leg_width = 0.3
                leg.x2 = 1 - pad_plot.GetRightMargin() - xtick_length
                leg.x1 = leg.x2 - leg_width
            if self.legend.position == 'seperate':
                with pad_legend:
                    leg.Draw()
            else:
                leg.Draw()
        if self.plot.logx:
            pad_plot.SetLogx(True)
        if self.plot.logy:
            pad_plot.SetLogy(True)
        pad_plot.Update(
        )  # needed sometimes with import of canvas. maybe because other "plot" pads exist...
        return c
   hist.markercolor = color
   hist.fillcolor = color
   hist.title += ' [%s, %s]' % (low_edge, up_edge)
   low_edge = up_edge
   hist.drawstyle = 'P'
   hist.inlegend = True
   hist.legendstyle = 'p'
   hist.xaxis.title = 'Optimization iteration (Bin)'
   hist.yaxis.title = 'Relative uncertainty'

for idx, json in enumerate(jsons):
   for hist, fit_bin in zip(hists, json):
      hist[idx+1].value = fit_bin['one_sigma']['relative']

canvas = Canvas(800, 800)
pad = Pad(0, 0., 1., 0.33)
pad.SetPad(0, 0.33, 1., 1.)
pad.Draw()
lower_pad = Pad(0, 0., 1., 0.33)
lower_pad.Draw()

nhists = len(hists)
nlegends = int(ceil(float(nhists) / 5))
nhist_for_leg = int(ceil(float(nhists)/nlegends))
legends = []
#left_margin = 0.1
#right_margin = 0.77
left_margin = 0.05
right_margin = 0.82
for _ in range(nlegends-1):
   legends.append(