def __init__(self, graphType = 'Pie', data = [ [[],[]] ]): """ Draw pieChart. def __init__(self, graphType = 'Pie', data = [[dataList , dataLabels, graphTitle, graphHeight, graphWidth],...]) 'dataList' contains the list of list of proportionate amounts of the slices x1, x2, x3,..xn, the pie chart would have slices of percentages (x1/sum) * 100, (x2/sum) * 100, ... (xn/sum) * 100, where sum = x1 + x2 + x3 + ...+ xn 'dataLabels' are the corresponding list of list labels of the data given in 'dataList', so, it is expected that len(dataLabels) == len(dataList) 'graphTitle' is the title of the graph. 'graphHeight', 'graphWidth' are height and width of the graph, so the pie chart can be elliptical. The values default to 2*inch, 2*inch. One list [graphTitle, dataList ,dataLabels, graphHeight, graphWidth ] corresponds to one chart. 'dataLabels', 'graphTitle', 'graphHeight', and 'graphWidth' are optional When more than one Pie Chart is to be drawn, i.e., len(data) > 1, we draw as many charts aside to each other as possible (based on the height, width of the graph) Extensions can be made to include other attributes such as label angle, slice colors etc """ #Each chart is surrounded by self.chartSideCushion space on both the sides #Each row is preceeded and succeeded by a cusion of self.interRowSpace self.chartSideCushion = 7 self.interRowSpace = 21 #We fix the width assuming the pdf generated is either A4 of US Letter flowableWidth = 7.5 * inch data = self._setDefaults(data) flowableHeight, self.rowBasedData = self._computeFlowableHeightAndRowBasedData(flowableWidth, data) FlowableGraph.__init__(self, flowableWidth, flowableHeight) self.graphType = graphType #'self.minChartAreaWidth' minimum width of a chart, this affects the total number #of charts that can fit into a row self.minChartAreaWidth = 3*inch
def __init__(self, x_vals, x_label, y_vals, y_label, title, graphtypeList, legends = [], splitgraph = False, xAxisDigits = 3, yAxisDigits = 3, dataLblDigits = 3, displayDataLbls = True, dataLabelAngle = 0, xValsDisplayAngle = 0, strictYbounds = {}, additionalLine = []): #x_vals - list of integers represented as strings. Ex: ['1', '2', '10'] #x_label - X axis title as string. Ex: "Time" #y_vals - list of list of values. Ex: [[200, 300, 50], [1, 10, 12]] #y_label - Y axis title as string. Ex: "FrameRate" #title - Title for the graph as string. Ex: "Latency Measurement" #graphtypeList - list of graph types as strings. Only 'Bar' and 'Line' # supported for now. Ex: ['Line'] or ['Line', 'Bar'] #legends - List of legendLists. Each legendList should have a mandatory # legend Name followed by optional type and color. Types # supported now are 'Line' or 'Rect'. Color needs to be # specified as an index pointing to one of the colors of # colorList. # Ex: [['Min', 'Line', colorList[1]], ['Max'], ['Avg', 'Rect']] #splitGraph - Draws (tries to..) separate graphs for each set of # y_val in the same chart area. #xAxisDigits - number of digits after the decimal point for x axis #yAxisDigits - number of digits after the decimal point for y axis #dataLblDigits - number of digits after the decimal point for data label #displayDataLbls - Flag indicating whether data labels are to be displayed #dataLabelAngle - The angle at which the data label is to be displayed (so that we minimize the # probability of one data label over running on the adjacent data label #xValsDisplayAngle - The angle at which the x-axis ticks' names (categorys names) are to be displayed # to aviod each over running onto the adjacent one #strictYbounds- A dict containing the lower and upper bounds values, if any # { 'lower': lowerBoundValue], 'upper': upperBoundValue} #additionalLine- [x1, y1, x2, y2, String]. Allows a line to be drawn between points (x1, y1), # (x2, y2) where (x1, x2), (y1, y2) are the points in the XValueAxis, # YValueAxis respectively. 'String' is the string to be used for the l # drawn for this line. # This line is useful in such cases where a theoritical line needs to # be drawn width = 7.0 * inch height = 3.5 * inch FlowableGraph.__init__(self, width, height) self.x_vals = x_vals self.x_label = x_label self.y_vals = y_vals self.y_label = y_label self.title = title self.graphList = graphtypeList self.splitgraph = splitgraph self.betweenSplitsF = False self.numSplits = 0 self.tmpYVal = 0 self.legendList = legends self.legendsDrawnF = False self.labelsDrawnF = False self.xAxisDigits = xAxisDigits self.yAxisDigits = yAxisDigits self.dataLblDigits = dataLblDigits self.displayDataLbls = displayDataLbls self.dataLabelAngle = dataLabelAngle self.xValsDisplayAngle = xValsDisplayAngle self.additionalLine = additionalLine self.strictYbounds = strictYbounds #When a lower bound is give for self.y_vals, the assumption is one doesn't care #about the plots below this lower value, so make all the values which are lower #than the given lowest value (self.strictYbounds['lower']), as the lowest value #Yes, this is a hack if 'lower' in self.strictYbounds: for i, eachPlot in enumerate(self.y_vals[:]): #Iterate over copy, as we change the actual values for j, eachPoint in enumerate(eachPlot): if eachPoint < self.strictYbounds['lower']: self.y_vals[i][j] = self.strictYbounds['lower'] self.additionalLineF = False if self.additionalLine: self.additionalLineF = True