~alf-rodrigo/cairoplot/trunk

« back to all changes in this revision

Viewing changes to trunk/cairoplot.py

  • Committer: Rodrigo Moreira Araujo
  • Date: 2009-04-02 23:00:30 UTC
  • Revision ID: rodrigo@scrooge-20090402230030-oc5vkq30vwhchlg3
cairoplot.py: Legends and pie pieces now start at the same angle thanks to Diego.

Show diffs side-by-side

added added

removed removed

Lines of Context:
826
826
                 y_bounds = None,
827
827
                 series_colors = None,
828
828
                 main_dir = None):
829
 
 
 
829
        
830
830
        self.bounds = {}
831
831
        self.bounds[HORZ] = x_bounds
832
832
        self.bounds[VERT] = y_bounds
1033
1033
                 height = 480,
1034
1034
                 background = "white light_gray",
1035
1035
                 border = 0,
1036
 
                 series_labels = False,
1037
1036
                 display_values = False,
1038
1037
                 grid = False,
1039
1038
                 rounded_corners = False,
1040
1039
                 stack = False,
1041
1040
                 three_dimension = False,
 
1041
                 series_labels = None,
1042
1042
                 x_labels = None,
1043
1043
                 y_labels = None,
1044
1044
                 x_bounds = None,
1202
1202
                 height = 480,
1203
1203
                 background = "white light_gray",
1204
1204
                 border = 0,
1205
 
                 series_labels = None,
1206
1205
                 display_values = False,
1207
1206
                 grid = False,
1208
1207
                 rounded_corners = False,
1209
1208
                 stack = False,
1210
1209
                 three_dimension = False,
 
1210
                 series_labels = None,
1211
1211
                 x_labels = None,
1212
1212
                 y_labels = None,
1213
1213
                 x_bounds = None,
1375
1375
                    
1376
1376
                    x0 += inner_step
1377
1377
    
 
1378
class StreamChart(VerticalBarPlot):
 
1379
    def __init__(self, 
 
1380
                 surface = None,
 
1381
                 data = None,
 
1382
                 width = 640,
 
1383
                 height = 480,
 
1384
                 background = "white light_gray",
 
1385
                 border = 0,
 
1386
                 grid = False,
 
1387
                 series_legend = None,
 
1388
                 x_labels = None,
 
1389
                 x_bounds = None,
 
1390
                 y_bounds = None,
 
1391
                 series_colors = None):
 
1392
 
 
1393
        VerticalBarPlot.__init__(self, surface, data, width, height, background, border, 
 
1394
                                 False, grid, False, True, False,
 
1395
                                 None, x_labels, None, x_bounds, y_bounds, series_colors)
 
1396
    
 
1397
    def calc_steps(self):
 
1398
        other_dir = other_direction(self.main_dir)    
 
1399
        self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0]
 
1400
        if self.series_amplitude:
 
1401
            self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude
 
1402
        else:
 
1403
            self.steps[self.main_dir] = 0.00
 
1404
        series_length = len(self.data)
 
1405
        self.steps[other_dir] = float(self.plot_dimensions[other_dir])/series_length
 
1406
    
 
1407
    def render_legend(self):
 
1408
        pass
 
1409
    
 
1410
    def ground(self, index):
 
1411
        sum_values = sum(self.data[index])
 
1412
        return -0.5*sum_values
 
1413
    
 
1414
    def calc_angles(self):
 
1415
        middle = self.plot_top - self.plot_dimensions[VERT]/2.0
 
1416
        self.angles = [tuple([0.0 for x in range(len(self.data)+1)])]
 
1417
        for x_index in range(1, len(self.data)-1):
 
1418
            t = []
 
1419
            x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ]
 
1420
            x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ]
 
1421
            y0 = middle - self.ground(x_index-1)*self.steps[VERT]
 
1422
            y2 = middle - self.ground(x_index+1)*self.steps[VERT]
 
1423
            t.append(math.atan(float(y0-y2)/(x0-x2)))
 
1424
            for data_index in range(len(self.data[x_index])):
 
1425
                x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ]
 
1426
                x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ]
 
1427
                y0 = middle - self.ground(x_index-1)*self.steps[VERT] - self.data[x_index-1][data_index]*self.steps[VERT]
 
1428
                y2 = middle - self.ground(x_index+1)*self.steps[VERT] - self.data[x_index+1][data_index]*self.steps[VERT]
 
1429
                
 
1430
                for i in range(0,data_index):
 
1431
                    y0 -= self.data[x_index-1][i]*self.steps[VERT]
 
1432
                    y2 -= self.data[x_index+1][i]*self.steps[VERT]
 
1433
                
 
1434
                if data_index == len(self.data[0])-1 and False:
 
1435
                    self.context.set_source_rgba(0.0,0.0,0.0,0.3)
 
1436
                    self.context.move_to(x0,y0)
 
1437
                    self.context.line_to(x2,y2)
 
1438
                    self.context.stroke()
 
1439
                    self.context.arc(x0,y0,2,0,2*math.pi)
 
1440
                    self.context.fill()
 
1441
                t.append(math.atan(float(y0-y2)/(x0-x2)))
 
1442
            self.angles.append(tuple(t))
 
1443
        self.angles.append(tuple([0.0 for x in range(len(self.data)+1)]))
 
1444
    
 
1445
    def render_plot(self):
 
1446
        self.calc_angles()
 
1447
        middle = self.plot_top - self.plot_dimensions[VERT]/2.0
 
1448
        p = 0.4*self.steps[HORZ]
 
1449
        for data_index in range(len(self.data[0])-1,-1,-1):
 
1450
            self.context.set_source_rgba(*self.series_colors[data_index])
 
1451
            
 
1452
            #draw the upper line
 
1453
            for x_index in range(len(self.data)-1) :
 
1454
                x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ]
 
1455
                y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT]
 
1456
                x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ]
 
1457
                y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT]
 
1458
                
 
1459
                for i in range(0,data_index):
 
1460
                    y1 -= self.data[x_index][i]*self.steps[VERT]
 
1461
                    y2 -= self.data[x_index+1][i]*self.steps[VERT]
 
1462
                
 
1463
                if x_index == 0:
 
1464
                    self.context.move_to(x1,y1)
 
1465
                
 
1466
                ang1 = self.angles[x_index][data_index+1]
 
1467
                ang2 = self.angles[x_index+1][data_index+1] + math.pi
 
1468
                self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1),
 
1469
                                      x2+p*math.cos(ang2),y2+p*math.sin(ang2),
 
1470
                                      x2,y2)
 
1471
 
 
1472
            for x_index in range(len(self.data)-1,0,-1) :
 
1473
                x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ]
 
1474
                y1 = middle - self.ground(x_index)*self.steps[VERT]
 
1475
                x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ]
 
1476
                y2 = middle - self.ground(x_index - 1)*self.steps[VERT]
 
1477
                
 
1478
                for i in range(0,data_index):
 
1479
                    y1 -= self.data[x_index][i]*self.steps[VERT]
 
1480
                    y2 -= self.data[x_index-1][i]*self.steps[VERT]
 
1481
                
 
1482
                if x_index == len(self.data)-1:
 
1483
                    self.context.line_to(x1,y1+2)
 
1484
                
 
1485
                #revert angles by pi degrees to take the turn back
 
1486
                ang1 = self.angles[x_index][data_index] + math.pi
 
1487
                ang2 = self.angles[x_index-1][data_index]
 
1488
                self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1),
 
1489
                                      x2+p*math.cos(ang2),y2+p*math.sin(ang2),
 
1490
                                      x2,y2+2)
 
1491
 
 
1492
            self.context.close_path()
 
1493
            self.context.fill()
 
1494
            
 
1495
            if False:
 
1496
                self.context.move_to(self.borders[HORZ] + 0.5*self.steps[HORZ], middle)
 
1497
                for x_index in range(len(self.data)-1) :
 
1498
                    x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ]
 
1499
                    y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT]
 
1500
                    x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ]
 
1501
                    y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT]
 
1502
                    
 
1503
                    for i in range(0,data_index):
 
1504
                        y1 -= self.data[x_index][i]*self.steps[VERT]
 
1505
                        y2 -= self.data[x_index+1][i]*self.steps[VERT]
 
1506
                    
 
1507
                    ang1 = self.angles[x_index][data_index+1]
 
1508
                    ang2 = self.angles[x_index+1][data_index+1] + math.pi
 
1509
                    self.context.set_source_rgba(1.0,0.0,0.0)
 
1510
                    self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi)
 
1511
                    self.context.fill()
 
1512
                    self.context.set_source_rgba(0.0,0.0,0.0)
 
1513
                    self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi)
 
1514
                    self.context.fill()
 
1515
                    '''self.context.set_source_rgba(0.0,0.0,0.0,0.3)
 
1516
                    self.context.arc(x2,y2,2,0,2*math.pi)
 
1517
                    self.context.fill()'''
 
1518
                    self.context.move_to(x1,y1)
 
1519
                    self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1))
 
1520
                    self.context.stroke()
 
1521
                    self.context.move_to(x2,y2)
 
1522
                    self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2))
 
1523
                    self.context.stroke()
 
1524
            if False:
 
1525
                for x_index in range(len(self.data)-1,0,-1) :
 
1526
                    x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ]
 
1527
                    y1 = middle - self.ground(x_index)*self.steps[VERT]
 
1528
                    x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ]
 
1529
                    y2 = middle - self.ground(x_index - 1)*self.steps[VERT]
 
1530
                    
 
1531
                    for i in range(0,data_index):
 
1532
                        y1 -= self.data[x_index][i]*self.steps[VERT]
 
1533
                        y2 -= self.data[x_index-1][i]*self.steps[VERT]
 
1534
                    
 
1535
                    #revert angles by pi degrees to take the turn back
 
1536
                    ang1 = self.angles[x_index][data_index] + math.pi
 
1537
                    ang2 = self.angles[x_index-1][data_index]
 
1538
                    self.context.set_source_rgba(0.0,1.0,0.0)
 
1539
                    self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi)
 
1540
                    self.context.fill()
 
1541
                    self.context.set_source_rgba(0.0,0.0,1.0)
 
1542
                    self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi)
 
1543
                    self.context.fill()
 
1544
                    '''self.context.set_source_rgba(0.0,0.0,0.0,0.3)
 
1545
                    self.context.arc(x2,y2,2,0,2*math.pi)
 
1546
                    self.context.fill()'''
 
1547
                    self.context.move_to(x1,y1)
 
1548
                    self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1))
 
1549
                    self.context.stroke()
 
1550
                    self.context.move_to(x2,y2)
 
1551
                    self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2))
 
1552
                    self.context.stroke()
 
1553
            #break
 
1554
            
 
1555
            #self.context.arc(self.dimensions[HORZ]/2, self.dimensions[VERT]/2,50,0,3*math.pi/2)
 
1556
            #self.context.fill()
 
1557
            
 
1558
 
1378
1559
class PiePlot(Plot):
1379
1560
    def __init__ (self,
1380
1561
            surface = None, 
1424
1605
        next_angle = 0
1425
1606
        x0,y0 = self.center
1426
1607
        cr = self.context
 
1608
        cr.set_source_rgba(*self.series_colors[0])
 
1609
        cr.arc(x0,y0,self.radius + 10,0, 2*math.pi)
 
1610
        cr.stroke()
1427
1611
        for number,key in enumerate(self.series_labels):
1428
1612
            next_angle = angle + 2.0*math.pi*self.data[number]/self.total
1429
1613
            cr.set_source_rgba(*self.series_colors[number])
1436
1620
            angle = next_angle
1437
1621
 
1438
1622
    def render_plot(self):
1439
 
        angle = 3*math.pi/2.0
 
1623
        angle = 0
1440
1624
        next_angle = 0
1441
1625
        x0,y0 = self.center
1442
1626
        cr = self.context
1943
2127
                      height, 
1944
2128
                      background = "white light_gray", 
1945
2129
                      border = 0, 
1946
 
                      series_labels = None,
1947
2130
                      display_values = False,
1948
2131
                      grid = False,
1949
2132
                      rounded_corners = False,
1950
2133
                      stack = False,
1951
2134
                      three_dimension = False,
 
2135
                      series_labels = None,
1952
2136
                      x_labels = None, 
1953
2137
                      y_labels = None, 
1954
2138
                      x_bounds = None, 
1982
2166
        CairoPlot.vertical_bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False)
1983
2167
    '''
1984
2168
    
1985
 
    plot = VerticalBarPlot(name, data, width, height, background, border, series_labels,
 
2169
    plot = VerticalBarPlot(name, data, width, height, background, border, 
1986
2170
                           display_values, grid, rounded_corners, stack, three_dimension, 
1987
 
                           x_labels, y_labels, x_bounds, y_bounds, colors)
 
2171
                           series_labels, x_labels, y_labels, x_bounds, y_bounds, colors)
1988
2172
    plot.render()
1989
2173
    plot.commit()
1990
2174
 
1994
2178
                       height, 
1995
2179
                       background = "white light_gray", 
1996
2180
                       border = 0,
1997
 
                       series_labels = None,
1998
2181
                       display_values = False,
1999
2182
                       grid = False,
2000
2183
                       rounded_corners = False,
2001
2184
                       stack = False,
2002
2185
                       three_dimension = False,
 
2186
                       series_labels = None,
2003
2187
                       x_labels = None, 
2004
2188
                       y_labels = None, 
2005
2189
                       x_bounds = None, 
2034
2218
        CairoPlot.bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False)
2035
2219
    '''
2036
2220
    
2037
 
    plot = HorizontalBarPlot(name, data, width, height, background, border, series_labels,
 
2221
    plot = HorizontalBarPlot(name, data, width, height, background, border, 
2038
2222
                             display_values, grid, rounded_corners, stack, three_dimension, 
2039
 
                             x_labels, y_labels, x_bounds, y_bounds, colors)
2040
 
    plot.render()
2041
 
    plot.commit()
2042
 
 
 
2223
                             series_labels, x_labels, y_labels, x_bounds, y_bounds, colors)
 
2224
    plot.render()
 
2225
    plot.commit()
 
2226
 
 
2227
def stream_chart(name, 
 
2228
                 data, 
 
2229
                 width, 
 
2230
                 height, 
 
2231
                 background = "white light_gray", 
 
2232
                 border = 0,
 
2233
                 grid = False,
 
2234
                 series_legend = None,
 
2235
                 x_labels = None, 
 
2236
                 x_bounds = None, 
 
2237
                 y_bounds = None,
 
2238
                 colors = None):
 
2239
 
 
2240
    #TODO: Fix docstring for horizontal_bar_plot
 
2241
    plot = StreamChart(name, data, width, height, background, border, 
 
2242
                       grid, series_legend, x_labels, x_bounds, y_bounds, colors)
 
2243
    plot.render()
 
2244
    plot.commit()