1# Copyright (c) 2005-2006 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution; 11# neither the name of the copyright holders nor the names of its 12# contributors may be used to endorse or promote products derived from 13# this software without specific prior written permission. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27# Authors: Nathan Binkert 28# Lisa Hsu 29 30import matplotlib, pylab 31from matplotlib.font_manager import FontProperties 32from matplotlib.numerix import array, arange, reshape, shape, transpose, zeros 33from matplotlib.numerix import Float 34from matplotlib.ticker import NullLocator 35 36matplotlib.interactive(False) 37 38from chart import ChartOptions 39 40class BarChart(ChartOptions): 41 def __init__(self, default=None, **kwargs): 42 super(BarChart, self).__init__(default, **kwargs) 43 self.inputdata = None 44 self.chartdata = None 45 self.inputerr = None 46 self.charterr = None 47 48 def gen_colors(self, count): 49 cmap = matplotlib.cm.get_cmap(self.colormap) 50 if count == 1: 51 return cmap([ 0.5 ]) 52 53 if count < 5: 54 return cmap(arange(5) / float(4))[:count] 55 56 return cmap(arange(count) / float(count - 1)) 57 58 # The input data format does not match the data format that the 59 # graph function takes because it is intuitive. The conversion 60 # from input data format to chart data format depends on the 61 # dimensionality of the input data. Check here for the 62 # dimensionality and correctness of the input data 63 def set_data(self, data): 64 if data is None: 65 self.inputdata = None 66 self.chartdata = None 67 return 68 69 data = array(data) 70 dim = len(shape(data)) 71 if dim not in (1, 2, 3): 72 raise AttributeError, "Input data must be a 1, 2, or 3d matrix" 73 self.inputdata = data 74 75 # If the input data is a 1d matrix, then it describes a 76 # standard bar chart. 77 if dim == 1: 78 self.chartdata = array([[data]]) 79 80 # If the input data is a 2d matrix, then it describes a bar 81 # chart with groups. The matrix being an array of groups of 82 # bars. 83 if dim == 2: 84 self.chartdata = transpose([data], axes=(2,0,1)) 85 86 # If the input data is a 3d matrix, then it describes an array 87 # of groups of bars with each bar being an array of stacked 88 # values. 89 if dim == 3: 90 self.chartdata = transpose(data, axes=(1,2,0)) 91 92 def get_data(self): 93 return self.inputdata 94 95 data = property(get_data, set_data) 96 97 def set_err(self, err): 98 if err is None: 99 self.inputerr = None 100 self.charterr = None 101 return 102 103 err = array(err) 104 dim = len(shape(err)) 105 if dim not in (1, 2, 3): 106 raise AttributeError, "Input err must be a 1, 2, or 3d matrix" 107 self.inputerr = err 108 109 if dim == 1: 110 self.charterr = array([[err]]) 111 112 if dim == 2: 113 self.charterr = transpose([err], axes=(2,0,1)) 114 115 if dim == 3: 116 self.charterr = transpose(err, axes=(1,2,0)) 117 118 def get_err(self): 119 return self.inputerr 120 121 err = property(get_err, set_err) 122 123 # Graph the chart data. 124 # Input is a 3d matrix that describes a plot that has multiple 125 # groups, multiple bars in each group, and multiple values stacked 126 # in each bar. The underlying bar() function expects a sequence of 127 # bars in the same stack location and same group location, so the 128 # organization of the matrix is that the inner most sequence 129 # represents one of these bar groups, then those are grouped 130 # together to make one full stack of bars in each group, and then 131 # the outer most layer describes the groups. Here is an example 132 # data set and how it gets plotted as a result. 133 # 134 # e.g. data = [[[10,11,12], [13,14,15], [16,17,18], [19,20,21]], 135 # [[22,23,24], [25,26,27], [28,29,30], [31,32,33]]] 136 # 137 # will plot like this: 138 # 139 # 19 31 20 32 21 33 140 # 16 28 17 29 18 30 141 # 13 25 14 26 15 27 142 # 10 22 11 23 12 24 143 # 144 # Because this arrangement is rather conterintuitive, the rearrange 145 # function takes various matricies and arranges them to fit this 146 # profile. 147 # 148 # This code deals with one of the dimensions in the matrix being 149 # one wide. 150 # 151 def graph(self): 152 if self.chartdata is None: 153 raise AttributeError, "Data not set for bar chart!" 154 155 dim = len(shape(self.inputdata)) 156 cshape = shape(self.chartdata) 157 if self.charterr is not None and shape(self.charterr) != cshape: 158 raise AttributeError, 'Dimensions of error and data do not match' 159 160 if dim == 1: 161 colors = self.gen_colors(cshape[2]) 162 colors = [ [ colors ] * cshape[1] ] * cshape[0] 163 164 if dim == 2: 165 colors = self.gen_colors(cshape[0]) 166 colors = [ [ [ c ] * cshape[2] ] * cshape[1] for c in colors ] 167 168 if dim == 3: 169 colors = self.gen_colors(cshape[1]) 170 colors = [ [ [ c ] * cshape[2] for c in colors ] ] * cshape[0] 171 172 colors = array(colors) 173 174 self.figure = pylab.figure(figsize=self.chart_size) 175 176 outer_axes = None 177 inner_axes = None 178 if self.xsubticks is not None: 179 color = self.figure.get_facecolor()
| 1# Copyright (c) 2005-2006 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution; 11# neither the name of the copyright holders nor the names of its 12# contributors may be used to endorse or promote products derived from 13# this software without specific prior written permission. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27# Authors: Nathan Binkert 28# Lisa Hsu 29 30import matplotlib, pylab 31from matplotlib.font_manager import FontProperties 32from matplotlib.numerix import array, arange, reshape, shape, transpose, zeros 33from matplotlib.numerix import Float 34from matplotlib.ticker import NullLocator 35 36matplotlib.interactive(False) 37 38from chart import ChartOptions 39 40class BarChart(ChartOptions): 41 def __init__(self, default=None, **kwargs): 42 super(BarChart, self).__init__(default, **kwargs) 43 self.inputdata = None 44 self.chartdata = None 45 self.inputerr = None 46 self.charterr = None 47 48 def gen_colors(self, count): 49 cmap = matplotlib.cm.get_cmap(self.colormap) 50 if count == 1: 51 return cmap([ 0.5 ]) 52 53 if count < 5: 54 return cmap(arange(5) / float(4))[:count] 55 56 return cmap(arange(count) / float(count - 1)) 57 58 # The input data format does not match the data format that the 59 # graph function takes because it is intuitive. The conversion 60 # from input data format to chart data format depends on the 61 # dimensionality of the input data. Check here for the 62 # dimensionality and correctness of the input data 63 def set_data(self, data): 64 if data is None: 65 self.inputdata = None 66 self.chartdata = None 67 return 68 69 data = array(data) 70 dim = len(shape(data)) 71 if dim not in (1, 2, 3): 72 raise AttributeError, "Input data must be a 1, 2, or 3d matrix" 73 self.inputdata = data 74 75 # If the input data is a 1d matrix, then it describes a 76 # standard bar chart. 77 if dim == 1: 78 self.chartdata = array([[data]]) 79 80 # If the input data is a 2d matrix, then it describes a bar 81 # chart with groups. The matrix being an array of groups of 82 # bars. 83 if dim == 2: 84 self.chartdata = transpose([data], axes=(2,0,1)) 85 86 # If the input data is a 3d matrix, then it describes an array 87 # of groups of bars with each bar being an array of stacked 88 # values. 89 if dim == 3: 90 self.chartdata = transpose(data, axes=(1,2,0)) 91 92 def get_data(self): 93 return self.inputdata 94 95 data = property(get_data, set_data) 96 97 def set_err(self, err): 98 if err is None: 99 self.inputerr = None 100 self.charterr = None 101 return 102 103 err = array(err) 104 dim = len(shape(err)) 105 if dim not in (1, 2, 3): 106 raise AttributeError, "Input err must be a 1, 2, or 3d matrix" 107 self.inputerr = err 108 109 if dim == 1: 110 self.charterr = array([[err]]) 111 112 if dim == 2: 113 self.charterr = transpose([err], axes=(2,0,1)) 114 115 if dim == 3: 116 self.charterr = transpose(err, axes=(1,2,0)) 117 118 def get_err(self): 119 return self.inputerr 120 121 err = property(get_err, set_err) 122 123 # Graph the chart data. 124 # Input is a 3d matrix that describes a plot that has multiple 125 # groups, multiple bars in each group, and multiple values stacked 126 # in each bar. The underlying bar() function expects a sequence of 127 # bars in the same stack location and same group location, so the 128 # organization of the matrix is that the inner most sequence 129 # represents one of these bar groups, then those are grouped 130 # together to make one full stack of bars in each group, and then 131 # the outer most layer describes the groups. Here is an example 132 # data set and how it gets plotted as a result. 133 # 134 # e.g. data = [[[10,11,12], [13,14,15], [16,17,18], [19,20,21]], 135 # [[22,23,24], [25,26,27], [28,29,30], [31,32,33]]] 136 # 137 # will plot like this: 138 # 139 # 19 31 20 32 21 33 140 # 16 28 17 29 18 30 141 # 13 25 14 26 15 27 142 # 10 22 11 23 12 24 143 # 144 # Because this arrangement is rather conterintuitive, the rearrange 145 # function takes various matricies and arranges them to fit this 146 # profile. 147 # 148 # This code deals with one of the dimensions in the matrix being 149 # one wide. 150 # 151 def graph(self): 152 if self.chartdata is None: 153 raise AttributeError, "Data not set for bar chart!" 154 155 dim = len(shape(self.inputdata)) 156 cshape = shape(self.chartdata) 157 if self.charterr is not None and shape(self.charterr) != cshape: 158 raise AttributeError, 'Dimensions of error and data do not match' 159 160 if dim == 1: 161 colors = self.gen_colors(cshape[2]) 162 colors = [ [ colors ] * cshape[1] ] * cshape[0] 163 164 if dim == 2: 165 colors = self.gen_colors(cshape[0]) 166 colors = [ [ [ c ] * cshape[2] ] * cshape[1] for c in colors ] 167 168 if dim == 3: 169 colors = self.gen_colors(cshape[1]) 170 colors = [ [ [ c ] * cshape[2] for c in colors ] ] * cshape[0] 171 172 colors = array(colors) 173 174 self.figure = pylab.figure(figsize=self.chart_size) 175 176 outer_axes = None 177 inner_axes = None 178 if self.xsubticks is not None: 179 color = self.figure.get_facecolor()
|