Now you can have sublabels for every bar using the self.xsubticklabels parameter.
authorLisa Hsu <hsul@eecs.umich.edu>
Sat, 18 Feb 2006 22:24:23 +0000 (17:24 -0500)
committerLisa Hsu <hsul@eecs.umich.edu>
Sat, 18 Feb 2006 22:24:23 +0000 (17:24 -0500)
--HG--
extra : convert_revision : a6bdf3a972e81c84947b7d6ae76f828494a125c8

util/stats/barchart.py

index 19cccb58a78966a055774d01506336500c16e492..99f9b8f35d2105c2b6590924ca5dd832f3ac2b52 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -76,12 +76,14 @@ class BarChart(ChartOptions):
         # bars.
         if dim == 2:
             self.chartdata = transpose([data], axes=(2,0,1))
+            print shape(self.chartdata)
 
         # If the input data is a 3d matrix, then it describes an array
         # of groups of bars with each bar being an array of stacked
         # values.
         if dim == 3:
             self.chartdata = transpose(data, axes=(1,2,0))
+            print shape(self.chartdata)
 
     def get_data(self):
         return self.inputdata
@@ -120,14 +122,15 @@ class BarChart(ChartOptions):
         if self.chartdata is None:
             raise AttributeError, "Data not set for bar chart!"
 
-        self.figure = pylab.figure(figsize=self.chart_size)
-        self.axes = self.figure.add_axes(self.figure_size)
+        need_subticks = True
 
         dim = len(shape(self.inputdata))
         cshape = shape(self.chartdata)
+        print cshape
         if dim == 1:
             colors = self.gen_colors(cshape[2])
             colors = [ [ colors ] * cshape[1] ] * cshape[0]
+            need_subticks = False
 
         if dim == 2:
             colors = self.gen_colors(cshape[0])
@@ -139,6 +142,27 @@ class BarChart(ChartOptions):
 
         colors = array(colors)
 
+        self.figure = pylab.figure(figsize=self.chart_size)
+
+        outer_axes = None
+        inner_axes = None
+        if need_subticks:
+            self.metaaxes = self.figure.add_axes(self.figure_size)
+            self.metaaxes.set_yticklabels([])
+            self.metaaxes.set_yticks([])
+            size = [0] * 4
+            size[0] = self.figure_size[0]
+            size[1] = self.figure_size[1] + .075
+            size[2] = self.figure_size[2]
+            size[3] = self.figure_size[3] - .075
+            self.axes = self.figure.add_axes(size)
+            outer_axes = self.metaaxes
+            inner_axes = self.axes
+        else:
+            self.axes = self.figure.add_axes(self.figure_size)
+            outer_axes = self.axes
+            inner_axes = self.axes
+
         bars_in_group = len(self.chartdata)
         if bars_in_group < 5:
             width = 1.0 / ( bars_in_group + 1)
@@ -156,29 +180,34 @@ class BarChart(ChartOptions):
                 ind = arange(len(bardata)) + i * width + center
                 bar = self.axes.bar(ind, bardata, width, bottom=bottom,
                                     color=colors[i][j])
+                if dim != 1:
+                    self.metaaxes.bar(ind, [0] * len(bardata), width)
                 stack.append(bar)
                 bottom += bardata
             bars.append(stack)
 
         if self.xlabel is not None:
-            self.axes.set_xlabel(self.xlabel)
+            outer_axes.set_xlabel(self.xlabel)
 
         if self.ylabel is not None:
-            self.axes.set_ylabel(self.ylabel)
+            inner_axes.set_ylabel(self.ylabel)
 
         if self.yticks is not None:
             ymin, ymax = self.axes.get_ylim()
             nticks = float(len(self.yticks))
             ticks = arange(nticks) / (nticks - 1) * (ymax - ymin)  + ymin
-            self.axes.set_yticks(ticks)
-            self.axes.set_yticklabels(self.yticks)
+            inner_axes.set_yticks(ticks)
+            inner_axes.set_yticklabels(self.yticks)
         elif self.ylim is not None:
-            self.axes.set_ylim(self.ylim)
+            self.inner_axes.set_ylim(self.ylim)
 
         if self.xticks is not None:
-            self.axes.set_xticks(arange(cshape[2]) + .5)
-            self.axes.set_xticklabels(self.xticks)
-
+            outer_axes.set_xticks(arange(cshape[2]) + .5)
+            outer_axes.set_xticklabels(self.xticks)
+        if self.xsubticks is not None:
+            inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center)
+            self.xsubticks.append('')
+            inner_axes.set_xticklabels(self.xsubticks * cshape[0], fontsize=8)
         if self.legend is not None:
             if dim == 1:
                 lbars = bars[0][0]
@@ -220,7 +249,6 @@ class BarChart(ChartOptions):
 
         f.close()
 
-
 if __name__ == '__main__':
     from random import randrange
     import random, sys
@@ -252,6 +280,8 @@ if __name__ == '__main__':
         chart1.legend = [ 'x%d' % x for x in xrange(myshape[-1]) ]
         chart1.xticks = [ 'xtick%d' % x for x in xrange(myshape[0]) ]
         chart1.title = 'this is the title'
+        chart1.figure_size = [0.1, 0.2, 0.7, 0.85 ]
+        chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ]
         chart1.graph()
         chart1.savefig('/tmp/test1.png')
         chart1.savefig('/tmp/test1.ps')
@@ -266,4 +296,4 @@ if __name__ == '__main__':
         chart2.savefig('/tmp/test2.png')
         chart2.savefig('/tmp/test2.ps')
 
-    #pylab.show()
+    pylab.myshow()