def plotHists(hists, files, xtitle, ytitle, title, pdfname, ly=False): c = ROOT.TCanvas("c", "c", 900, 600) pad1 = ROOT.TPad("pad1", "This is pad1", 0.0, 0.0, 0.9, 1.0, 0) pad2 = ROOT.TPad("pad2", "This is pad2", 0.85, 0.0, 1.0, 1.0, 0) pad1.Draw() pad2.Draw() pad1.cd() start = 0 label = Legend("") multi = ROOT.TMultiGraph() for i in range( len(hists) ): #This loops over the files. nhists(f1,f2,f3) is the format of hists. temp = files[i].GetName() if (p_ops.Normalized): hists[i] = NormalizeGraph(hists[i]) hists[i].SetLineColorAlpha(color[i], alphas[i]) hists[i].SetMarkerColorAlpha(color[i], alphas[i]) hists[i].SetMarkerStyle(style[i]) hists[i].SetMarkerSize(1) hists[i].SetLineWidth(2) # print 'i ' , i , ' MINIMUM: ' , hists[i].GetHistogram().GetMinimum() , ' MAXIMUM : ' , hists[i].GetHistogram().GetMaximum(), label.Add(hists[i], tag[i], "P") multi.Add(hists[i]) multi.Draw("AP") ROOT.gStyle.SetErrorX(0.0001) multi.SetMaximum(1.02 * multi.GetHistogram().GetMaximum()) multi.SetTitle(title) multi.GetXaxis().SetTitle(xtitle) multi.GetYaxis().SetTitle(ytitle) multi.GetXaxis().SetNdivisions(8) multi.GetYaxis().SetNdivisions(8) multi.GetXaxis().CenterTitle() multi.GetYaxis().CenterTitle() multi.SetMinimum(0) #if ly==True: #multi.SetMinimum(multi.GetHistogram().GetMinimum()+1e-4) if ly: multi.SetMinimum(multi.GetHistogram().GetMinimum() + 1e-4) ROOT.gPad.SetLogy(1) pad2.cd() label.Draw(0.0, .7) latex = TLatex() latex.SetNDC() c.SaveAs(pdfname) c.Clear() print "END OF PLOTTING FUNCTION "
def hasLegend( self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None, title=None, labelOrdering=None, leftToRight=False, ): """ Declare that the plot has a legend with a given number of columns and location. """ self.legend = Legend( columns=columns, scatterPoints=scatterPoints, drawFrame=draw_frame, location=location, figLegend=False, labelSize=labelSize, bboxToAnchor=bbox_to_anchor, title=title, labelOrdering=labelOrdering, leftToRight=leftToRight, )
def hasLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize = None, title=None, labelOrdering=None, leftToRight=False): """ Declare that the plot has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = False, labelSize = labelSize, bboxToAnchor = bbox_to_anchor, title = title, labelOrdering = labelOrdering, leftToRight = leftToRight)
def plotHists(hists, files, xtitle, ytitle, title, pdfname, ly=False): c = ROOT.TCanvas() start = 0 label = Legend("") multi = ROOT.TMultiGraph() for i in range( len(hists) ): #This loops over the files. nhists(f1,f2,f3) is the format of hists. temp = files[i].GetName() #print 'printing Temp ' , temp temp = temp.split('_MinBias')[0] if temp in tag: temp = temp + " , version %s " % (i + 1) hists[i].SetLineColor(color[i]) hists[i].SetMarkerColor(color[i]) hists[i].SetMarkerStyle(style[i]) hists[i].SetMarkerSize(1) hists[i].SetLineWidth(2) # print 'i ' , i , ' MINIMUM: ' , hists[i].GetHistogram().GetMinimum() , ' MAXIMUM : ' , hists[i].GetHistogram().GetMaximum(), label.Add(hists[i], tag[i], "L") multi.Add(hists[i]) multi.Draw("AP") ROOT.gStyle.SetErrorX(0.0001) #multi.SetMaximum(1.02*multi.GetHistogram().GetMaximum()) multi.SetMaximum(0.25) multi.SetMinimum(0.0) multi.SetTitle(title) multi.GetXaxis().SetTitle(xtitle) multi.GetYaxis().SetTitle(ytitle) multi.GetXaxis().SetNdivisions(10) label.Draw(0.2, .95) if ly == True: ROOT.gPad.SetLogy(1) latex = TLatex() latex.SetNDC() #latex.DrawLatex(0.2,0.90,"#font[62]{#scale[0.9]{lucidEvtOr}}") c.SaveAs(pdfname) c.Clear() print "END OF PLOTTING FUNCTION "
def plotHists(hists, files, xtitle, ytitle, title, pdfname, ly=False): c = ROOT.TCanvas() start = 0 label = Legend("") multi = ROOT.TMultiGraph() for i in range( len(hists) ): #This loops over the files. nhists(f1,f2,f3) is the format of hists. temp = files[i].GetName() if (p_ops.Normalized): hists[i] = NormalizeGraph(hists[i]) hists[i].SetLineColor(color[i]) hists[i].SetMarkerColor(color[i]) hists[i].SetMarkerStyle(style[i]) hists[i].SetMarkerSize(1) hists[i].SetLineWidth(2) # print 'i ' , i , ' MINIMUM: ' , hists[i].GetHistogram().GetMinimum() , ' MAXIMUM : ' , hists[i].GetHistogram().GetMaximum(), label.Add(hists[i], tag[i], "L") multi.Add(hists[i]) #multi.SetMaximum(15) #multi.SetMinimum(5) multi.Draw("ALP") ROOT.gStyle.SetErrorX(0.0001) multi.SetMaximum(1.02 * multi.GetHistogram().GetMaximum()) multi.SetTitle(title) multi.GetXaxis().SetTitle(xtitle) multi.GetYaxis().SetTitle(ytitle) multi.GetXaxis().SetTitle('Median density #rho [GeV]') multi.GetYaxis().SetTitle('normalized counts') multi.GetXaxis().SetNdivisions(10) label.Draw(0.6, .95) if ly == True: ROOT.gPad.SetLogy(1) latex = TLatex() latex.SetNDC() c.SaveAs(pdfname) c.Clear() print "END OF PLOTTING FUNCTION "
def hasFigLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None): """ Declare that the figure has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = True, labelSize = labelSize, bboxToAnchor = bbox_to_anchor)
def plotHists(hists, files, xtitle, ytitle, title, pdfname, ly=False): c = ROOT.TCanvas() start = 0 label = Legend(p_ops.legendname) multi = ROOT.TMultiGraph() for i in range( len(hists) ): #This loops over the files. nhists(f1,f2,f3) is the format of hists. temp = files[i].GetName() if (p_ops.Normalized): hists[i] = NormalizeGraph(hists[i]) hists[i].SetLineColor(color[i]) hists[i].SetMarkerColor(color[i]) hists[i].SetMarkerStyle(style[i]) hists[i].SetMarkerSize(1) hists[i].SetLineWidth(2) hists[i].Rebin() # print 'i ' , i , ' MINIMUM: ' , hists[i].GetHistogram().GetMinimum() , ' MAXIMUM : ' , hists[i].GetHistogram().GetMaximum(), label.Add(hists[i], tag[i], "L") multi.Add(hists[i]) cluslabel = Legend("15 GeV < p_{T_{trigger}} < 20 GeV") #multi.SetMaximum(15) #multi.SetMinimum(5) multi.Draw("ALP") ROOT.gStyle.SetErrorX(0.0001) multi.SetMaximum(1.02 * multi.GetHistogram().GetMaximum()) multi.SetTitle(title) multi.GetXaxis().SetTitle(xtitle) multi.GetYaxis().SetTitle(ytitle) #multi.GetXaxis().SetTitle('x_{obs}^{Pb}:= #frac{p_{T}^{#gamma}e^{-#eta^{#gamma}} + p_{T}^{jet}e^{-#eta^{jet}}}{2E_{Pb}}') multi.GetXaxis().SetTitleSize(0.04) multi.GetXaxis().SetTitleOffset(1.6) #multi.GetYaxis().SetTitle('#frac{1}{N_{trig}}#frac{dN}{dx_{obs}^{Pb}}') #multi.GetXaxis().SetTitle('#Delta #phi (rads)') multi.GetXaxis().SetTitle(p_ops.xaxislabel) #multi.GetYaxis().SetTitle('#frac{1}{N_{trig}}#frac{dN}{d#Delta #phi}}') #multi.GetXaxis().SetRangeUser(0.005, 0.020) multi.GetXaxis().SetNdivisions(10) label.Draw(0.6, .96) cluslabel.Draw(0.55, 0.65) if ly == True: ROOT.gPad.SetLogy(1) latex = TLatex() latex.SetNDC() c.SaveAs(pdfname) c.Clear() print "END OF PLOTTING FUNCTION "
def __init__(self, leaf): self.file = File(leaf) self.legend = Legend(leaf) self.contour = Contour(leaf) self.title = Title(leaf) self.uv = UV(leaf)
class Plot(object): """ Represents a single plot, usually consisting of a single X and Y axis. """ def __init__(self): self.plots = [] self.title = None self.xFormatter = None self.yFormatter = None self.yLabel = None self.xLabel = None self.legend = None self.xlim = None self.ylim = None self.twinxLabel = None self.twinxIndex = -1 self.twinxLimits = None self.lineStyles = None self.lineColors = None self.markers = None self.width = None self.height = None self.dpi = 100 self.plotParams = None self.logx = False self.logy = False self.loglog = False self.logbase = 10 self.logbasex = None self.logbasey = None self._grid = Grid() self._grid.visible = False self.insets = [] self.hideTicks = False self.latex = False self.axesLabelSize = None self.xTickLabelSize = None self.yTickLabelSize = None self.titleProperties = LabelProperties() self.tight = False self.projection = None @property def grid(self): return self._grid @grid.setter def grid(self, value): if isinstance(value, bool) and value == True: self._grid.visible = True else: raise AttributeError("Plot.grid cannot be re-assigned") def setTitleProperties(self, **propList): self.__setProperties(self.titleProperties, propList) def __setProperties(self, propsDict, propList): for (key, val) in propList.items(): propsDict[key] = val def __str__(self): return str(self.__dict__) def setAxesLabelSize(self, size): self.axesLabelSize = size def setXTickLabelSize(self, size): self.xTickLabelSize = size def setYTickLabelSize(self, size): self.yTickLabelSize = size def setLegendLabelSize(self, size): if self.legend is None: self.legend = Legend() self.legend.labelSize = size def split(self, pieces): splitPlots = [copy.deepcopy(self) for i in xrange(pieces)] for plot in splitPlots: plot.plots = [] for plot in self.plots: elements = plot.split(pieces) for i in xrange(pieces): splitPlots[i].add(elements[i]) splitPlots[i].setXLimits(min(elements[i].xValues), max(elements[i].xValues)) return splitPlots def getDimensions(self): if self.width is None: (self.width, self.height) = getGoldenRatioDimensions(8.0) elif self.height is None: (goldWidth, goldHeight) = getGoldenRatioDimensions(self.width) self.height = goldHeight return (self.width, self.height) def hideTickLabels(self): self.hideTicks = True def setDimensions(self, width=None, height=None, dpi=100): self.width = width self.height = height self.dpi = dpi def add(self, plottableObject): """ Add a plottable object (a Line, Bar, etc.) to this plot, causing it to be drawn when the plot is drawn. """ if not issubclass(plottableObject.__class__, PlotInfo): raise BoomslangPlotConfigurationException( "All objects added to a Plot must be a subclass of PlotInfo") self.plots.append(plottableObject) def addInset(self, plot, **kwargs): inset = Inset(plot, **kwargs) self.insets.append(inset) def addLineStyle(self, style): """ Add a line style to the list of line styles through which the plot will cycle when drawing lines. If no line styles are specified, the plot will default to the line style specified in the Line objects themselves. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineStyles is None: self.lineStyles = [] currStyle = LineStyle() currStyle.style = style self.lineStyles.append(currStyle) def addLineColor(self, color): """ Add a line color to the list of line colors through which the plot will cycle when drawing lines. If no line colors are specified, the line colors specified by the Line objects themselves will be used. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineColors is None: self.lineColors = [] self.lineColors.append(color) def addMarker(self, marker): if self.markers is None: self.markers = [] currMarker = Marker() currMarker.marker = marker self.markers.append(currMarker) def getNumPlots(self): """ Get the number of plottable objects currently registered for this plot. """ return len(self.plots) def setTwinX(self, label, index, yMin=None, yMax=None): """ Make the plot use a secondary y-axis with the provided label. All registered plottable objects at or after the given index will use this second axis. """ self.twinxLabel = label self.twinxIndex = index if yMin is not None and yMax is not None: self.twinxLimits = (yMin, yMax) def setYFormatter(self, formatter): """ Set the y-axis formatter used by this plot to the given function. """ self.yFormatter = pylab.FuncFormatter(formatter) def setXFormatter(self, formatter): """ Set the x-axis formatter used by this plot to the given function. """ self.xFormatter = pylab.FuncFormatter(formatter) def setXLabel(self, xLabel): """ Set the x-axis label. """ self.xLabel = xLabel def setYLabel(self, yLabel): """ Set the y-axis label. """ self.yLabel = yLabel def setXLimits(self, minX, maxX): """ Set the minimum and maximum values for the x-axis. """ self.xlim = (minX, maxX) def setYLimits(self, minY, maxY): """ Set the minimum and maximum values for the y-axis. """ self.ylim = (minY, maxY) def hasFigLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None): """ Declare that the figure has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = True, labelSize = labelSize, bboxToAnchor = bbox_to_anchor) def hasLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize = None): """ Declare that the plot has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = False, labelSize = labelSize, bboxToAnchor = bbox_to_anchor) def setTitle(self, title): self.title = title def __cmp__(self, other): if not isinstance(other, Plot): raise ValueError("Can't compare a Plot with a non-Plot") return cmp(self.title, other.title) def __setupLayout(self): layout = PlotLayout() (width, height) = self.getDimensions() layout.setPlotDimensions(width, height, dpi=self.dpi) if self.plotParams is not None: layout.setPlotParameters(**self.plotParams) if self.latex == True: layout.useLatexLabels() if self.axesLabelSize is not None: layout.setAxesLabelSize(self.axesLabelSize) if self.xTickLabelSize is not None: layout.setXTickLabelSize(self.xTickLabelSize) if self.yTickLabelSize is not None: layout.setYTickLabelSize(self.yTickLabelSize) layout.addPlot(self) return layout def useLatexLabels(self): self.latex = True def plot(self): """ Draw this plot to a matplotlib canvas. """ layout = self.__setupLayout() layout.plot() def plot_fig(self): layout = self.__setupLayout() return layout._doPlot() def setPlotParameters(self, **kwdict): self.plotParams = dict(kwdict) if "left" not in self.plotParams: self.plotParams["left"] = 0.12 if "bottom" not in self.plotParams: self.plotParams["bottom"] = 0.10 if "right" not in self.plotParams: self.plotParams["right"] = 0.90 if "top" not in self.plotParams: self.plotParams["top"] = 0.90 if "wspace" not in self.plotParams: self.plotParams["wspace"] = 0.20 if "hspace" not in self.plotParams: self.plotParams["hspace"] = 0.20 def save(self, filename, **kwargs): """ Save this plot to a file. """ layout = self.__setupLayout() layout.save(filename,**kwargs) def subplot(self, fig, row, column, position, projection): kwdict = {} if projection is not None: kwdict["projection"] = projection ax = fig.add_subplot(row, column, position, **kwdict) return self.drawPlot(fig, ax) def drawPlot(self, fig, ax): """ Used by PlotLayout to plot the graph at a given location in the layout. """ ax2 = None if self.tight: ax.autoscale_view(tight=True) for inset in self.insets: inset.draw(fig, ax) if self.hideTicks == True: for xtl in ax.get_xticklabels(): xtl.set_visible(False) for xtick in ax.get_xticklines(): xtick.set_visible(False) for ytl in ax.get_yticklabels(): ytl.set_visible(False) for ytick in ax.get_yticklines(): ytick.set_visible(False) if self.grid.visible == True: self.grid.draw(fig, ax) if self.loglog or self.logx: myBase = None if self.logbasex is not None: myBase = self.logbasex else: myBase = self.logbase ax.set_xscale('log', basex=myBase) if self.loglog or self.logy: myBase = None if self.logbasey is not None: myBase = self.logbasey else: myBase = self.logbase ax.set_yscale('log', basey=myBase) if self.twinxIndex > 0: ax2 = ax.twinx() ax2.set_ylabel(self.twinxLabel) if self.twinxLimits is not None: ax2.set_ylim(ymin=self.twinxLimits[0], ymax=self.twinxLimits[1]) plotHandles = [] plotLabels = [] if self.xFormatter is not None: ax.xaxis.set_major_formatter(self.xFormatter) if self.yFormatter is not None: ax.yaxis.set_major_formatter(self.yFormatter) if self.title is not None: ax.set_title(self.title, **self.titleProperties) i = 0 myAxis = ax hasLineStyles = self.lineStyles is not None hasColors = self.lineColors is not None hasMarkers = self.markers is not None numLineStyles = 1 numColors = 1 numMarkers = 1 if hasLineStyles: numLineStyles = len(self.lineStyles) if hasColors: numColors = len(self.lineColors) if hasMarkers: numMarkers = len(self.markers) plotIndex = 0 for plotInfo in self.plots: if self.twinxIndex >= 0 and i == self.twinxIndex: myAxis = ax2 myLineStyle = None myColor = None myMarker = None # cycle through styles first, then markers, then colors colorIndex = (plotIndex / (numMarkers * numLineStyles)) % numColors markerIndex = (plotIndex / numLineStyles) % numMarkers lineStyleIndex = plotIndex % numLineStyles if hasLineStyles: myLineStyle = self.lineStyles[lineStyleIndex].style if hasColors: myColor = self.lineColors[colorIndex] if hasMarkers: myMarker = self.markers[markerIndex].marker plotIndex += 1 if myLineStyle is not None: plotInfo.lineStyle = myLineStyle if myMarker is not None: plotInfo.marker = myMarker if myColor is not None: plotInfo.color = myColor plotInfo._preDraw() (currPlotHandles, currPlotLabels) = plotInfo.draw(fig, myAxis) labelIndices = [x for x in range(len(currPlotLabels)) \ if currPlotLabels[x] is not None] if len(labelIndices) > 0: plotHandles.extend([currPlotHandles[x] for x in labelIndices]) plotLabels.extend([currPlotLabels[x] for x in labelIndices]) if plotInfo.xLimits is not None: if self.xlim is None: self.xlim = plotInfo.xLimits else: (myXMin, myXMax) = plotInfo.xLimits self.xlim = (min(self.xlim[0], myXMin), max(self.xlim[1], myXMax)) i += 1 if self.xlim is not None: ax.set_xlim(xmin=self.xlim[0], xmax=self.xlim[1]) if self.ylim is not None: ax.set_ylim(ymin=self.ylim[0], ymax=self.ylim[1]) if self.xLabel is not None: ax.set_xlabel(self.xLabel) if self.yLabel is not None: ax.set_ylabel(self.yLabel) if self.legend is not None: if len(plotHandles) == 0: print >>sys.stderr, "ERROR: Plot wanted to draw a legend, " \ "but none of its elements have labels" sys.exit(1) if self.twinxIndex > 0: legendAxis = ax2 else: legendAxis = ax self.legend.draw(fig, legendAxis, plotHandles, plotLabels) return (plotHandles, plotLabels)
def setLegendLabelSize(self, size): if self.legend is None: self.legend = Legend() self.legend.labelSize = size
def Plotting(histos, purity, variable, rebin=1, title='', ymax=None): hSR, hBR, hBR_scaled, hSub, hMC, hweights = histos #hSR, hBR ,hMC = GetHistos(variable,rebin) hBR.SetTitle(title) #hBR.SetMinimum(0) hBR.Draw() hBR.SetMaximum(hBR.GetMaximum() * 1.2) hBR.GetYaxis().SetNdivisions(22) hBR.GetXaxis().SetNdivisions(9) hBR_scaled.Draw('samehist') #hBR_scaled.Draw('samehist') hSR.Draw('same') label = Legend(labeltitle) label.Add(hSR, "Signal Region", "P") label.Add(hBR, "Bkg Region", "P") label.Add(hBR_scaled, "Bkg Region, scaled by purity", "L") label.Draw(0.45, 0.90) plotname = variable + '_step1_purity%2.3f' % purity['nominal'] canvas.SaveAs('IntermediateStep_' + plotname + "_DATANAME_%s.pdf" % dataname) canvas.Clear() ######################## hMC.SetFillColorAlpha(ROOT.kOrange, 0.70) #hMC.Draw('hist') hs = ROOT.THStack() hs.Add(hSub) hs.Add(hBR) #hs.Add(hBR_scaled,'hist') hs.Draw('nostack') if (ymax > 0): hs.SetMaximum(ymax) else: hs.SetMaximum(hBR.GetMaximum() * 1.2) hs.SetTitle(title) hs.GetYaxis().SetNdivisions(12) hs.GetXaxis().SetNdivisions(10) #hSys = ObtainSystematicVariation(purity, rebin, variable) #hs.Add(hSys) #hSys.SetFillColorAlpha(ROOT.kGray,0.5) #hSys.SetFillStyle(3144) #hSys.Draw("E2same") #hSub.Draw("same") #hSys.Draw("E2same") #hMC.Draw("samehist") label = Legend(labeltitle) label.Add(hSub, "#gamma-jet", "P") #label.Add(hMC, "Pythia LO #gamma-jet","L") label.Add(hBR, "#pi^{0}-jet ", "P") label.Draw(.2, .90) latex = TLatex() latex.SetNDC() latex.SetTextColor(1) latex.DrawLatex(0.65, 0.88, "15 < p_{T}^{trig} < 20 GeV") latex.DrawLatex(0.65, 0.81, "p_{T}^{jet} > 5 GeV") if (variable != 'dPhi'): latex.DrawLatex(0.65, 0.74, "#Delta#phi > #pi/2") # myText(0.6,0.82,ROOT.kBlack, "12 < p_{T}^{trig} < 16 GeV") #myText(0.6,0.76, kBlack, "p_{T}^{jet} > 5 GeV") #myText(0.6,0.71,kBlack, "#Delta #phi > #pi/2") canvas.SaveAs('Final_' + plotname + "_DATANAME_%s.pdf" % dataname) canvas.Clear()
mc_truth = responseMatrix.ProjectionX() mc_reco = responseMatrix.ProjectionY() mc_truth.SetLineColorAlpha(2, 0.8) mc_reco.SetLineColorAlpha(4, 0.8) ##draw mc truth, mc reco, response matrix c = ROOT.TCanvas('c', 'c', 1600, 600) c.Divide(3) c.cd(1) responseMatrix.Draw('colz') responseMatrix.SetTitle('; x^{true}_{J} ; x^{reco}_{J} ') ROOT.gPad.SetLogz() c.cd(2) label = Legend("") label.Add(mc_reco, 'MC Reco', 'L') label.Add(mc_truth, 'MC True', 'L') hs_mc = ROOT.THStack() hs_mc.Add(mc_reco) hs_mc.Add(mc_truth) hs_mc.Draw('nostack') hs_mc.SetTitle('; x^{reco}_{J}; counts') label.Draw(0.5, .87) c.cd(3) ratio_mc = mc_truth.Clone() ratio_mc.SetMinimum(0) ratio_mc.SetLineColor(1)
class Plot(object): """ Represents a single plot, usually consisting of a single X and Y axis. """ def __init__(self): self.plots = [] self.title = None """ The plot's title (will be centered above the axes themselves) """ self.xFormatter = None self.yFormatter = None self.yLabel = None """ The label for the plot's y-axis """ self.xLabel = None """ The label for the plot's x-axis """ self._xLabelProperties = LabelProperties() self._yLabelProperties = LabelProperties() self.legend = None self._xLimits = None self._yLimits = None self.twinxLabel = None self.twinxIndex = -1 self.twinxLimits = None self.lineStyles = None self.lineColors = None self.markers = None self.width = None self.height = None self.dpi = 100 self.plotParams = None self.logx = False """ If true, this plot's x-axis will be drawn in log scale. """ self.logy = False """ If true, this plot's y-axis will be drawn in log scale. """ self.loglog = False """ If true, both this plot's axes will be drawn in log scale. """ self.logbase = 10 """ The base of the logarithm used to draw log scale axes. """ self.logbasex = None """ The base of the logarithm used to draw the x-axis. Overrides `logbase`, and only takes effect if logx or loglog are True. """ self.logbasey = None """ The base of the logarithm used to draw the y-axis. Overrides `logbase`, and only takes effect if logy or loglog are True. """ self._grid = Grid() self._grid.visible = False self.insets = [] self.hideTicks = False """ If True, this plot's tick labels are hidden. """ self.titleSize = None """ The size of the text used for plot title. """ self.latex = False self.axesLabelSize = None """ The size of the text used for labeling the x and y axes. """ self.xTickLabelSize = None """ The size of the text used for x-axis tick labels """ self.yTickLabelSize = None """ The size of the text used for y-axis tick labels """ self.titleProperties = LabelProperties() self.tight = False """ If True, this plot is auto-scaled so that axis labels don't get cut off. """ self.allows_tight = True self.projection = None """ Defines the projection used when drawing this plot. The only currently supported value other than the standard (no projection) is 'polar'. """ @property def xLabelProperties(self): """ A dictionary of properties that control the appearance of the X axis' axis label. See :ref:`styling-labels` for more information on which properties can be set. """ return self._xLabelProperties @xLabelProperties.setter def xLabelProperties(self, propsobj): self._xLabelProperties.update(propsobj) @property def yLabelProperties(self): """ A dictionary of properties that control the appearance of the Y axis' axis label. See :ref:`styling-labels` for more information on which properties can be set. """ return self._yLabelProperties @yLabelProperties.setter def yLabelProperties(self, propsobj): self._yLabelProperties.update(propsobj) @property def xLimits(self): """ A pair giving the minimum and maximum values visible on the x-axis. """ return self._xLimits @xLimits.setter def xLimits(self, value): if type(value) not in [tuple, list] or len(value) != 2: raise AttributeError("xLimits must be set to a (min, max) tuple") self._xLimits = tuple(value) @property def yLimits(self): """ A pair giving the minimum and maximum values visible on the x-axis. """ return self._yLimits @yLimits.setter def yLimits(self, value): if type(value) not in [tuple, list] or len(value) != 2: raise AttributeError("yLimits must be set to a (min, max) tuple") self._yLimits = value @property def legendLabelSize(self): """ The size of the text in this plot's legend. """ return self.legend.labelSize @legendLabelSize.setter def legendLabelSize(self, size): self.setLegendLabelSize(size) @property def grid(self): """ A boomslang.Grid.Grid that defines the properties of this plot's grid lines. See :ref:`plots-grid-lines` for configuration options. """ return self._grid @grid.setter def grid(self, value): if isinstance(value, bool) and value == True: self._grid.visible = True else: raise AttributeError("Plot.grid cannot be re-assigned") def setTitleProperties(self, **propList): """ Set the properties of the title. See :ref:`styling-labels` for more information about valid properties. """ self.__setProperties(self.titleProperties, propList) def __setProperties(self, propsDict, propList): for (key, val) in propList.items(): propsDict[key] = val def __str__(self): return str(self.__dict__) def setTitleSize(self, size): self.titleSize = size def setAxesLabelSize(self, size): self.axesLabelSize = size def setXTickLabelSize(self, size): self.xTickLabelSize = size def setYTickLabelSize(self, size): self.yTickLabelSize = size def setLegendLabelSize(self, size): if self.legend is None: self.legend = Legend() self.legend.labelSize = size def split(self, pieces): """ Split this plot into `pieces` separate plots, each showing a different portion of the x-axis """ splitPlots = [copy.deepcopy(self) for i in xrange(pieces)] for plot in splitPlots: plot.plots = [] for plot in self.plots: elements = plot.split(pieces) for i in xrange(pieces): splitPlots[i].add(elements[i]) splitPlots[i].setXLimits(min(elements[i].xValues), max(elements[i].xValues)) return splitPlots def getDimensions(self): """ Get the dimensions of this plot. """ if self.width is None: (self.width, self.height) = getGoldenRatioDimensions(8.0) elif self.height is None: (goldWidth, goldHeight) = getGoldenRatioDimensions(self.width) self.height = goldHeight return (self.width, self.height) def hideTickLabels(self): self.hideTicks = True def setDimensions(self, width=None, height=None, dpi=100): """ Set the dimensions for this plot to `width` x `height` """ self.width = width self.height = height self.dpi = dpi def add(self, plottableObject): """ Add a plottable object (a Line, Bar, etc.) to this plot, causing it to be drawn when the plot is drawn. """ if not issubclass(plottableObject.__class__, PlotInfo): raise BoomslangPlotConfigurationException("All objects added to a Plot must be a subclass of PlotInfo") self.plots.append(plottableObject) def addInset(self, plot, **kwargs): """ Add `plot` (a Plot object) as an inset to this plot object. Valid arguments are as follows: ============ ==================================================================================================================== Argument Description ============ ==================================================================================================================== ``width`` The width of the inset as a fraction of the size of the parent plot ``height`` The height of the inset as a fraction of the size of the parent plot ``location`` The location of the inset. See :ref:`plots-locations` for valid locations. ``padding`` The amount of padding between the edge of the parent plot and the inset as a fraction of the size of the parent plot ============ ==================================================================================================================== """ inset = Inset(plot, **kwargs) self.insets.append(inset) def addLineStyle(self, style): """ Add a line style to the list of line styles through which the plot will cycle when drawing lines. If no line styles are specified, the plot will default to the line style specified in the Line objects themselves. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineStyles is None: self.lineStyles = [] currStyle = LineStyle() currStyle.style = style self.lineStyles.append(currStyle) def addLineColor(self, color): """ Add a line color to the list of line colors through which the plot will cycle when drawing lines. If no line colors are specified, the line colors specified by the Line objects themselves will be used. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineColors is None: self.lineColors = [] self.lineColors.append(color) def addMarker(self, marker): """ Add a marker style to the list of marker styles through which the plot will cycle when drawing lines. If no markers are specified, the markers specified by the Line objects themselves will be used. Note that, when drawing lines, all line style/color combinations are cycled through with a given marker before a new marker is chosen. """ if self.markers is None: self.markers = [] currMarker = Marker() currMarker.marker = marker self.markers.append(currMarker) def getNumPlots(self): # Get the number of plottable objects currently registered for this # plot. return len(self.plots) def setTwinX(self, label, index, yMin=None, yMax=None): """ Make the plot use a secondary y-axis with the provided label. All registered plottable objects at or after the given index will use this second axis. """ self.twinxLabel = label self.twinxIndex = index if yMin is not None and yMax is not None: self.twinxLimits = (yMin, yMax) def setYFormatter(self, formatter): """ Set the y-axis formatter used by this plot to the given function. """ self.yFormatter = pylab.FuncFormatter(formatter) def setXFormatter(self, formatter): """ Set the x-axis formatter used by this plot to the given function. """ self.xFormatter = pylab.FuncFormatter(formatter) def setXLabel(self, xLabel): self.xLabel = xLabel def setYLabel(self, yLabel): self.yLabel = yLabel def setXLimits(self, minX, maxX): self.xLimits = (minX, maxX) def setYLimits(self, minY, maxY): self.yLimits = (minY, maxY) def hasFigLegend( self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None, title=None, labelOrdering=None, leftToRight=False, ): """ Declare that the figure has a legend with a given number of columns and location. """ self.legend = Legend( columns=columns, scatterPoints=scatterPoints, drawFrame=draw_frame, location=location, figLegend=True, labelSize=labelSize, bboxToAnchor=bbox_to_anchor, title=title, labelOrdering=labelOrdering, leftToRight=leftToRight, ) def hasLegend( self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None, title=None, labelOrdering=None, leftToRight=False, ): """ Declare that the plot has a legend with a given number of columns and location. """ self.legend = Legend( columns=columns, scatterPoints=scatterPoints, drawFrame=draw_frame, location=location, figLegend=False, labelSize=labelSize, bboxToAnchor=bbox_to_anchor, title=title, labelOrdering=labelOrdering, leftToRight=leftToRight, ) def setTitle(self, title): self.title = title def __cmp__(self, other): if not isinstance(other, Plot): raise ValueError("Can't compare a Plot with a non-Plot") return cmp(self.title, other.title) def __setupLayout(self): layout = PlotLayout() (width, height) = self.getDimensions() layout.setPlotDimensions(width, height, dpi=self.dpi) if self.plotParams is not None: layout.setPlotParameters(**self.plotParams) if self.titleSize is not None: layout.setTitleSize(self.titleSize) if self.latex == True: layout.useLatexLabels() if self.axesLabelSize is not None: layout.setAxesLabelSize(self.axesLabelSize) if self.xTickLabelSize is not None: layout.setXTickLabelSize(self.xTickLabelSize) if self.yTickLabelSize is not None: layout.setYTickLabelSize(self.yTickLabelSize) layout.addPlot(self) return layout def useLatexLabels(self): self.latex = True def plot(self): """ Draw this plot to a matplotlib canvas. """ layout = self.__setupLayout() layout.plot() def plot_fig(self): layout = self.__setupLayout() return layout._doPlot() def setPlotParameters(self, **kwdict): """ Set the margins of this plot. See `matplotlib's SubplotParams documentation <http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.SubplotParams>`_ for more details. It is recommended that you set :py:attr:`boomslang.Plot.Plot.tight` to True instead of setting these parameters. """ self.plotParams = dict(kwdict) if "left" not in self.plotParams: self.plotParams["left"] = 0.12 if "bottom" not in self.plotParams: self.plotParams["bottom"] = 0.10 if "right" not in self.plotParams: self.plotParams["right"] = 0.90 if "top" not in self.plotParams: self.plotParams["top"] = 0.90 if "wspace" not in self.plotParams: self.plotParams["wspace"] = 0.20 if "hspace" not in self.plotParams: self.plotParams["hspace"] = 0.20 def save(self, filename, **kwargs): """ Save this plot to a file. """ layout = self.__setupLayout() layout.save(filename, **kwargs) def subplot(self, fig, row, column, position, projection): kwdict = {} if projection is not None: kwdict["projection"] = projection ax = fig.add_subplot(row, column, position, **kwdict) return self.drawPlot(fig, ax) def drawPlot(self, fig, ax): """ Used by PlotLayout to plot the graph at a given location in the layout. """ ax2 = None if self.tight and self.allows_tight: ax.autoscale_view(tight=True) for inset in self.insets: inset.draw(fig, ax) if self.hideTicks == True: for xtl in ax.get_xticklabels(): xtl.set_visible(False) for xtick in ax.get_xticklines(): xtick.set_visible(False) for ytl in ax.get_yticklabels(): ytl.set_visible(False) for ytick in ax.get_yticklines(): ytick.set_visible(False) if self.grid.visible == True: self.grid.draw(fig, ax) if self.loglog or self.logx: myBase = None if self.logbasex is not None: myBase = self.logbasex else: myBase = self.logbase ax.set_xscale("log", basex=myBase) if self.loglog or self.logy: myBase = None if self.logbasey is not None: myBase = self.logbasey else: myBase = self.logbase ax.set_yscale("log", basey=myBase) if self.twinxIndex > 0: ax2 = ax.twinx() ax2.set_ylabel(self.twinxLabel) if self.twinxLimits is not None: ax2.set_ylim(ymin=self.twinxLimits[0], ymax=self.twinxLimits[1]) plotHandles = [] plotLabels = [] if self.xFormatter is not None: ax.xaxis.set_major_formatter(self.xFormatter) if self.yFormatter is not None: ax.yaxis.set_major_formatter(self.yFormatter) if self.title is not None: ax.set_title(self.title, **self.titleProperties) i = 0 myAxis = ax hasLineStyles = self.lineStyles is not None hasColors = self.lineColors is not None hasMarkers = self.markers is not None numLineStyles = 1 numColors = 1 numMarkers = 1 if hasLineStyles: numLineStyles = len(self.lineStyles) if hasColors: numColors = len(self.lineColors) if hasMarkers: numMarkers = len(self.markers) plotIndex = 0 for plotInfo in self.plots: if self.twinxIndex >= 0 and i == self.twinxIndex: myAxis = ax2 myLineStyle = None myColor = None myMarker = None # cycle through styles first, then markers, then colors colorIndex = (plotIndex / (numMarkers * numLineStyles)) % numColors markerIndex = int(plotIndex / numLineStyles) % numMarkers lineStyleIndex = plotIndex % numLineStyles if hasLineStyles: myLineStyle = self.lineStyles[lineStyleIndex].style if hasColors: myColor = self.lineColors[colorIndex] if hasMarkers: myMarker = self.markers[markerIndex].marker plotIndex += 1 if myLineStyle is not None: plotInfo.lineStyle = myLineStyle if myMarker is not None: plotInfo.marker = myMarker if myColor is not None: plotInfo.color = myColor plotInfo._preDraw() (currPlotHandles, currPlotLabels) = plotInfo.draw(fig, myAxis) labelIndices = [x for x in range(len(currPlotLabels)) if currPlotLabels[x] is not None] if len(labelIndices) > 0: plotHandles.extend([currPlotHandles[x] for x in labelIndices]) plotLabels.extend([currPlotLabels[x] for x in labelIndices]) if plotInfo.xLimits is not None: if self.xLimits is None: self.xLimits = plotInfo.xLimits else: (myXMin, myXMax) = plotInfo.xLimits self.xLimits = (min(self.xLimits[0], myXMin), max(self.xLimits[1], myXMax)) i += 1 if self.xLimits is not None: ax.set_xlim(xmin=self.xLimits[0], xmax=self.xLimits[1]) if self.yLimits is not None: ax.set_ylim(ymin=self.yLimits[0], ymax=self.yLimits[1]) if self.xLabel is not None: ax.set_xlabel(self.xLabel, **self.xLabelProperties) if self.yLabel is not None: ax.set_ylabel(self.yLabel, **self.yLabelProperties) if self.legend is not None: if len(plotHandles) == 0: print >>sys.stderr, "ERROR: Plot wanted to draw a legend, " "but none of its elements have labels" sys.exit(1) if self.twinxIndex > 0: legendAxis = ax2 else: legendAxis = ax self.legend.draw(fig, legendAxis, plotHandles, plotLabels) return (plotHandles, plotLabels)
class Plot(object): """ Represents a single plot, usually consisting of a single X and Y axis. """ def __init__(self): self.plots = [] self.title = None """ The plot's title (will be centered above the axes themselves) """ self.xFormatter = None self.yFormatter = None self.yLabel = None """ The label for the plot's y-axis """ self.xLabel = None """ The label for the plot's x-axis """ self._xLabelProperties = LabelProperties() self._yLabelProperties = LabelProperties() self.legend = None self._xLimits = None self._yLimits = None self.twinxLabel = None self.twinxIndex = -1 self.twinxLimits = None self.lineStyles = None self.lineColors = None self.markers = None self.width = None self.height = None self.dpi = 100 self.plotParams = None self.logx = False """ If true, this plot's x-axis will be drawn in log scale. """ self.logy = False """ If true, this plot's y-axis will be drawn in log scale. """ self.loglog = False """ If true, both this plot's axes will be drawn in log scale. """ self.logbase = 10 """ The base of the logarithm used to draw log scale axes. """ self.logbasex = None """ The base of the logarithm used to draw the x-axis. Overrides `logbase`, and only takes effect if logx or loglog are True. """ self.logbasey = None """ The base of the logarithm used to draw the y-axis. Overrides `logbase`, and only takes effect if logy or loglog are True. """ self._grid = Grid() self._grid.visible = False self.insets = [] self.hideTicks = False """ If True, this plot's tick labels are hidden. """ self.titleSize = None """ The size of the text used for plot title. """ self.latex = False self.axesLabelSize = None """ The size of the text used for labeling the x and y axes. """ self.xTickLabelSize = None """ The size of the text used for x-axis tick labels """ self.yTickLabelSize = None """ The size of the text used for y-axis tick labels """ self.titleProperties = LabelProperties() self.tight = False """ If True, this plot is auto-scaled so that axis labels don't get cut off. """ self.allows_tight = True self.projection = None """ Defines the projection used when drawing this plot. The only currently supported value other than the standard (no projection) is 'polar'. """ @property def xLabelProperties(self): """ A dictionary of properties that control the appearance of the X axis' axis label. See :ref:`styling-labels` for more information on which properties can be set. """ return self._xLabelProperties @xLabelProperties.setter def xLabelProperties(self, propsobj): self._xLabelProperties.update(propsobj) @property def yLabelProperties(self): """ A dictionary of properties that control the appearance of the Y axis' axis label. See :ref:`styling-labels` for more information on which properties can be set. """ return self._yLabelProperties @yLabelProperties.setter def yLabelProperties(self, propsobj): self._yLabelProperties.update(propsobj) @property def xLimits(self): """ A pair giving the minimum and maximum values visible on the x-axis. """ return self._xLimits @xLimits.setter def xLimits(self, value): if type(value) not in [tuple, list] or len(value) != 2: raise AttributeError("xLimits must be set to a (min, max) tuple") self._xLimits = tuple(value) @property def yLimits(self): """ A pair giving the minimum and maximum values visible on the x-axis. """ return self._yLimits @yLimits.setter def yLimits(self, value): if type(value) not in [tuple, list] or len(value) != 2: raise AttributeError("yLimits must be set to a (min, max) tuple") self._yLimits = value @property def legendLabelSize(self): """ The size of the text in this plot's legend. """ return self.legend.labelSize @legendLabelSize.setter def legendLabelSize(self, size): self.setLegendLabelSize(size) @property def grid(self): """ A boomslang.Grid.Grid that defines the properties of this plot's grid lines. See :ref:`plots-grid-lines` for configuration options. """ return self._grid @grid.setter def grid(self, value): if isinstance(value, bool) and value == True: self._grid.visible = True else: raise AttributeError("Plot.grid cannot be re-assigned") def setTitleProperties(self, **propList): """ Set the properties of the title. See :ref:`styling-labels` for more information about valid properties. """ self.__setProperties(self.titleProperties, propList) def __setProperties(self, propsDict, propList): for (key, val) in propList.items(): propsDict[key] = val def __str__(self): return str(self.__dict__) def setTitleSize(self, size): self.titleSize = size def setAxesLabelSize(self, size): self.axesLabelSize = size def setXTickLabelSize(self, size): self.xTickLabelSize = size def setYTickLabelSize(self, size): self.yTickLabelSize = size def setLegendLabelSize(self, size): if self.legend is None: self.legend = Legend() self.legend.labelSize = size def split(self, pieces): """ Split this plot into `pieces` separate plots, each showing a different portion of the x-axis """ splitPlots = [copy.deepcopy(self) for i in xrange(pieces)] for plot in splitPlots: plot.plots = [] for plot in self.plots: elements = plot.split(pieces) for i in xrange(pieces): splitPlots[i].add(elements[i]) splitPlots[i].setXLimits( min(elements[i].xValues), max(elements[i].xValues)) return splitPlots def getDimensions(self): """ Get the dimensions of this plot. """ if self.width is None: (self.width, self.height) = getGoldenRatioDimensions(8.0) elif self.height is None: (goldWidth, goldHeight) = getGoldenRatioDimensions(self.width) self.height = goldHeight return (self.width, self.height) def hideTickLabels(self): self.hideTicks = True def setDimensions(self, width=None, height=None, dpi=100): """ Set the dimensions for this plot to `width` x `height` """ self.width = width self.height = height self.dpi = dpi def add(self, plottableObject): """ Add a plottable object (a Line, Bar, etc.) to this plot, causing it to be drawn when the plot is drawn. """ if not issubclass(plottableObject.__class__, PlotInfo): raise BoomslangPlotConfigurationException( "All objects added to a Plot must be a subclass of PlotInfo") self.plots.append(plottableObject) def addInset(self, plot, **kwargs): """ Add `plot` (a Plot object) as an inset to this plot object. Valid arguments are as follows: ============ ==================================================================================================================== Argument Description ============ ==================================================================================================================== ``width`` The width of the inset as a fraction of the size of the parent plot ``height`` The height of the inset as a fraction of the size of the parent plot ``location`` The location of the inset. See :ref:`plots-locations` for valid locations. ``padding`` The amount of padding between the edge of the parent plot and the inset as a fraction of the size of the parent plot ============ ==================================================================================================================== """ inset = Inset(plot, **kwargs) self.insets.append(inset) def addLineStyle(self, style): """ Add a line style to the list of line styles through which the plot will cycle when drawing lines. If no line styles are specified, the plot will default to the line style specified in the Line objects themselves. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineStyles is None: self.lineStyles = [] currStyle = LineStyle() currStyle.style = style self.lineStyles.append(currStyle) def addLineColor(self, color): """ Add a line color to the list of line colors through which the plot will cycle when drawing lines. If no line colors are specified, the line colors specified by the Line objects themselves will be used. Note that, when drawing lines, all line styles for a given color are cycled through before another color is used. """ if self.lineColors is None: self.lineColors = [] self.lineColors.append(color) def addMarker(self, marker): """ Add a marker style to the list of marker styles through which the plot will cycle when drawing lines. If no markers are specified, the markers specified by the Line objects themselves will be used. Note that, when drawing lines, all line style/color combinations are cycled through with a given marker before a new marker is chosen. """ if self.markers is None: self.markers = [] currMarker = Marker() currMarker.marker = marker self.markers.append(currMarker) def getNumPlots(self): # Get the number of plottable objects currently registered for this # plot. return len(self.plots) def setTwinX(self, label, index, yMin=None, yMax=None): """ Make the plot use a secondary y-axis with the provided label. All registered plottable objects at or after the given index will use this second axis. """ self.twinxLabel = label self.twinxIndex = index if yMin is not None and yMax is not None: self.twinxLimits = (yMin, yMax) def setYFormatter(self, formatter): """ Set the y-axis formatter used by this plot to the given function. """ self.yFormatter = pylab.FuncFormatter(formatter) def setXFormatter(self, formatter): """ Set the x-axis formatter used by this plot to the given function. """ self.xFormatter = pylab.FuncFormatter(formatter) def setXLabel(self, xLabel): self.xLabel = xLabel def setYLabel(self, yLabel): self.yLabel = yLabel def setXLimits(self, minX, maxX): self.xLimits = (minX, maxX) def setYLimits(self, minY, maxY): self.yLimits = (minY, maxY) def hasFigLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize=None, title=None, labelOrdering=None, leftToRight=False): """ Declare that the figure has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = True, labelSize = labelSize, bboxToAnchor = bbox_to_anchor, title = title, labelOrdering = labelOrdering, leftToRight = leftToRight) def hasLegend(self, columns=1, location="best", scatterPoints=3, draw_frame=True, bbox_to_anchor=None, labelSize = None, title=None, labelOrdering=None, leftToRight=False): """ Declare that the plot has a legend with a given number of columns and location. """ self.legend = Legend(columns = columns, scatterPoints = scatterPoints, drawFrame = draw_frame, location = location, figLegend = False, labelSize = labelSize, bboxToAnchor = bbox_to_anchor, title = title, labelOrdering = labelOrdering, leftToRight = leftToRight) def setTitle(self, title): self.title = title def __cmp__(self, other): if not isinstance(other, Plot): raise ValueError("Can't compare a Plot with a non-Plot") return cmp(self.title, other.title) def __setupLayout(self): layout = PlotLayout() (width, height) = self.getDimensions() layout.setPlotDimensions(width, height, dpi=self.dpi) if self.plotParams is not None: layout.setPlotParameters(**self.plotParams) if self.titleSize is not None: layout.setTitleSize(self.titleSize) if self.latex == True: layout.useLatexLabels() if self.axesLabelSize is not None: layout.setAxesLabelSize(self.axesLabelSize) if self.xTickLabelSize is not None: layout.setXTickLabelSize(self.xTickLabelSize) if self.yTickLabelSize is not None: layout.setYTickLabelSize(self.yTickLabelSize) layout.addPlot(self) return layout def useLatexLabels(self): self.latex = True def plot(self): """ Draw this plot to a matplotlib canvas. """ layout = self.__setupLayout() layout.plot() def plot_fig(self): layout = self.__setupLayout() return layout._doPlot() def setPlotParameters(self, **kwdict): """ Set the margins of this plot. See `matplotlib's SubplotParams documentation <http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.SubplotParams>`_ for more details. It is recommended that you set :py:attr:`boomslang.Plot.Plot.tight` to True instead of setting these parameters. """ self.plotParams = dict(kwdict) if "left" not in self.plotParams: self.plotParams["left"] = 0.12 if "bottom" not in self.plotParams: self.plotParams["bottom"] = 0.10 if "right" not in self.plotParams: self.plotParams["right"] = 0.90 if "top" not in self.plotParams: self.plotParams["top"] = 0.90 if "wspace" not in self.plotParams: self.plotParams["wspace"] = 0.20 if "hspace" not in self.plotParams: self.plotParams["hspace"] = 0.20 def save(self, filename, **kwargs): """ Save this plot to a file. """ layout = self.__setupLayout() layout.save(filename,**kwargs) def subplot(self, fig, row, column, position, projection): kwdict = {} if projection is not None: kwdict["projection"] = projection ax = fig.add_subplot(row, column, position, **kwdict) return self.drawPlot(fig, ax) def drawPlot(self, fig, ax): """ Used by PlotLayout to plot the graph at a given location in the layout. """ ax2 = None if self.tight and self.allows_tight: ax.autoscale_view(tight=True) for inset in self.insets: inset.draw(fig, ax) if self.hideTicks == True: for xtl in ax.get_xticklabels(): xtl.set_visible(False) for xtick in ax.get_xticklines(): xtick.set_visible(False) for ytl in ax.get_yticklabels(): ytl.set_visible(False) for ytick in ax.get_yticklines(): ytick.set_visible(False) if self.grid.visible == True: self.grid.draw(fig, ax) if self.loglog or self.logx: myBase = None if self.logbasex is not None: myBase = self.logbasex else: myBase = self.logbase ax.set_xscale('log', basex=myBase) if self.loglog or self.logy: myBase = None if self.logbasey is not None: myBase = self.logbasey else: myBase = self.logbase ax.set_yscale('log', basey=myBase) if self.twinxIndex > 0: ax2 = ax.twinx() ax2.set_ylabel(self.twinxLabel) if self.twinxLimits is not None: ax2.set_ylim(ymin=self.twinxLimits[0], ymax=self.twinxLimits[1]) plotHandles = [] plotLabels = [] if self.xFormatter is not None: ax.xaxis.set_major_formatter(self.xFormatter) if self.yFormatter is not None: ax.yaxis.set_major_formatter(self.yFormatter) if self.title is not None: ax.set_title(self.title, **self.titleProperties) i = 0 myAxis = ax hasLineStyles = self.lineStyles is not None hasColors = self.lineColors is not None hasMarkers = self.markers is not None numLineStyles = 1 numColors = 1 numMarkers = 1 if hasLineStyles: numLineStyles = len(self.lineStyles) if hasColors: numColors = len(self.lineColors) if hasMarkers: numMarkers = len(self.markers) plotIndex = 0 for plotInfo in self.plots: if self.twinxIndex >= 0 and i == self.twinxIndex: myAxis = ax2 myLineStyle = None myColor = None myMarker = None # cycle through styles first, then markers, then colors colorIndex = (plotIndex / (numMarkers * numLineStyles)) % numColors markerIndex = int(plotIndex / numLineStyles) % numMarkers lineStyleIndex = plotIndex % numLineStyles if hasLineStyles: myLineStyle = self.lineStyles[lineStyleIndex].style if hasColors: myColor = self.lineColors[colorIndex] if hasMarkers: myMarker = self.markers[markerIndex].marker plotIndex += 1 if myLineStyle is not None: plotInfo.lineStyle = myLineStyle if myMarker is not None: plotInfo.marker = myMarker if myColor is not None: plotInfo.color = myColor plotInfo._preDraw() (currPlotHandles, currPlotLabels) = plotInfo.draw(fig, myAxis) labelIndices = [x for x in range(len(currPlotLabels)) \ if currPlotLabels[x] is not None] if len(labelIndices) > 0: plotHandles.extend([currPlotHandles[x] for x in labelIndices]) plotLabels.extend([currPlotLabels[x] for x in labelIndices]) if plotInfo.xLimits is not None: if self.xLimits is None: self.xLimits = plotInfo.xLimits else: (myXMin, myXMax) = plotInfo.xLimits self.xLimits = (min(self.xLimits[0], myXMin), max(self.xLimits[1], myXMax)) i += 1 if self.xLimits is not None: ax.set_xlim(xmin=self.xLimits[0], xmax=self.xLimits[1]) if self.yLimits is not None: ax.set_ylim(ymin=self.yLimits[0], ymax=self.yLimits[1]) if self.xLabel is not None: ax.set_xlabel(self.xLabel, **self.xLabelProperties) if self.yLabel is not None: ax.set_ylabel(self.yLabel, **self.yLabelProperties) if self.legend is not None: if len(plotHandles) == 0: print >>sys.stderr, "ERROR: Plot wanted to draw a legend, " \ "but none of its elements have labels" sys.exit(1) if self.twinxIndex > 0: legendAxis = ax2 else: legendAxis = ax self.legend.draw(fig, legendAxis, plotHandles, plotLabels) return (plotHandles, plotLabels)
files, allhists[i][0].GetXaxis().GetTitle(), allhists[i][0].GetYaxis().GetTitle(), allhists[i][0].GetTitle(), output_dir + "/" + hists[i] + Tag + '_Comparison.pdf', ly=False) c = ROOT.TCanvas() c.SetGrid(0, 1) #allhists[0][0].Print() zero = ROOT.TF1('zero', '[0]+[1]*x', -5, 4000) zero.SetLineColor(2) g_ratio = [] multi = ROOT.TMultiGraph() label = Legend("") print len(tag) if len(tag) > 1: for i in range(len(hists)): g_ratio.append(DivideGraphs(allhists[i][0], allhists[i][1])) #zero.SetLineColor(1) #g_ratio[0].Fit(zero) g_ratio[0].SetMarkerSize(1) g_ratio[0].SetMarkerColor(color[1]) g_ratio[0].Print() print 'Mean of ratios ', '%.3f' % g_ratio[0].GetMean( 2), ' %, RMS of ratios ', '%.3f' % g_ratio[0].GetRMS(2), " % " multi.Add(g_ratio[0]) #label.Add(g_ratio[0],tag[1]+"/"+tag[0]) for j in range(2, len(tag)):
eff_Lambda.Print() purity_NN = fMC.Get("Purity_NN") purity_Lambda = fMC.Get("Purity_Lambda") closure_NN = fMC.Get("ClosureTest_NN") closure_Lambda = fMC.Get("ClosureTest_Lambda") #fdata = ROOT.TFile("fout_195783.root") fdata = ROOT.TFile("fout_DATA.root") DeepPionSpectra = fdata.Get("DeepPionSpectra") MergedPionLambdaSpectra = fdata.Get("MergedPionLambdaSpectra") MergedPionLambdaSpectra.Print() c = ROOT.TCanvas("c", "c") l = Legend("") purity_NN.SetLineColorAlpha(2, 0.85) purity_Lambda.SetLineColorAlpha(4, 0.85) purity_NN.SetMarkerColorAlpha(2, 0.85) purity_Lambda.SetMarkerColorAlpha(4, 0.85) l.Add(purity_NN, "NN>0.85", "L") l.Add(purity_Lambda, "#lambda_{0}^{2} > 0.27", "L") purity_NN.SetTitle("; p_{T} cluster [GeV]; purity") purity_NN.GetXaxis().SetRangeUser(8.0, 25.0) purity_NN.SetMaximum(1.0) purity_NN.SetMinimum(0.0) purity_NN.Draw() purity_Lambda.Draw("same") purity_NN.SetLineColorAlpha(2, 0.85)
def Print(self, path, **kwargs): r"""Print the plot to a file. Creates a :class:`.Canvas` and draws all registered objects into their associated :class:`Pad`. The canvas is saved as a PDF/PNG/... file with the absolute path defined by **path**. If a file with the same name already exists it will be overwritten (can be changed with the **overwrite** keyword argument). If **mkdir** is set to ``True`` (default: ``False``) directories in **path** with do not yet exist will be created automatically. The properties of the of the plot and canvas can be configured via their respective properties passed as keyword arguments. :param path: path of the output file (must end with '.pdf', '.png', ...) :type path: ``str`` :param \**kwargs: :class:`.Plot` and :class:`.Canvas` properties + additional properties (see below) Keyword Arguments: * **inject<N>** (``list``, ``tuple``, ``ROOT.TObject``) -- inject a (list of) *drawable* :class:`ROOT` object(s) to pad **<N>** (default: 0), object properties can be specified by passing instead a ``tuple`` of the format :code:`(obj, props)` where :code:`props` is a ``dict`` holding the object properties (default: \[\]) * **overwrite** (``bool``) -- overwrite an existing file located at **path** (default: ``True``) * **mkdir** (``bool``) -- create non-existing directories in **path** (default: ``False``) """ for idx, injections in { int(k[6:]) if len(k) > 6 else 0: kwargs.pop(k) for k in dict(kwargs.items()) if k.startswith("inject") }.items(): if not isinstance(injections, list): injections = [injections] self.Inject(idx, *injections) properties = DissectProperties(kwargs, [Plot, Canvas]) ROOT.gStyle.SetOptStat(0) ROOT.gStyle.SetPaintTextFormat("4.2f") canvas = Canvas("{}_Canvas".format(self._name), template=str(self._npads), **properties["Canvas"]) legend = {} self.DeclareProperties(**properties["Plot"]) self.AddPlotDecorations() for i, store in self._store.items(): pad = Pad("{}_Pad-{}".format(canvas.GetName(), i), **self._padproperties[i]) pad.Draw() pad.cd() legend[i] = Legend( "{}_Legend".format(pad.GetName()), xshift=pad.GetLegendXShift(), yshift=pad.GetLegendYShift(), ) canvas.SetSelectedPad(pad) for obj, objprops in store: with UsingProperties(obj, **objprops): if any([ obj.InheritsFrom(tcls) for tcls in ["TH1", "THStack"] ]): legend[i].Register(obj) suffix = "SAME" if pad.GetDrawFrame() else "" obj.Draw(obj.GetDrawOption() + suffix) if pad.GetDrawFrame(): pad.RedrawAxis() if pad.GetDrawLegend(): legend[i].Draw("SAME") canvas.cd() canvas.Print(path) if os.path.isfile(path): logger.info("Created plot: '{}'".format(path)) canvas.Delete()