| Conditions | 28 |
| Total Lines | 112 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like _compare_per_class_metrics() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | import logging |
||
| 79 | def _compare_per_class_metrics(methods, classes, class_colors, metric_arrays, |
||
| 80 | group_by='methods', filename=None, background_class=None, |
||
| 81 | as_percent=True, metric_name='recall'): |
||
| 82 | """Compare per-class metrics between methods using bar-graph |
||
| 83 | """ |
||
| 84 | metric_labels, metric_indices = _get_metric_label_dict(metric_name=metric_name) |
||
| 85 | bg_class_id = _get_bg_class_id(classes, background_class) |
||
| 86 | plot_metric_arrays = _gether_per_class_metrics(methods, classes, metric_arrays, as_percent, |
||
| 87 | metric_labels, metric_indices) |
||
| 88 | # Prepare Data and x-label |
||
| 89 | xtick_labels = [] |
||
| 90 | bar_colors = [] |
||
| 91 | if bg_class_id < 0: |
||
| 92 | plot_data = np.empty((len(methods) * len(classes), len(metric_labels))) |
||
| 93 | else: |
||
| 94 | plot_data = np.empty((len(methods) * (len(classes) - 1), len(metric_labels))) |
||
| 95 | # Fill plot data with values |
||
| 96 | if group_by == 'methods': |
||
| 97 | num_base_axis = len(methods) |
||
| 98 | if bg_class_id < 0: |
||
| 99 | num_sec_axis = len(classes) |
||
| 100 | else: |
||
| 101 | num_sec_axis = len(classes) - 1 |
||
| 102 | for j in range(len(classes)): |
||
| 103 | if bg_class_id < 0 or j < bg_class_id: |
||
| 104 | for i in range(len(methods)): |
||
| 105 | bar_colors.append(class_colors[j]) |
||
| 106 | xtick_labels.append(methods[i]) |
||
| 107 | plot_data[j * num_base_axis + i, :] = plot_metric_arrays[i][j, :] |
||
| 108 | elif j > bg_class_id: |
||
| 109 | for i in range(len(methods)): |
||
| 110 | bar_colors.append(class_colors[j]) |
||
| 111 | xtick_labels.append(methods[i]) |
||
| 112 | plot_data[(j-1) * num_base_axis + i, :] = plot_metric_arrays[i][j, :] |
||
| 113 | else: |
||
| 114 | if bg_class_id < 0: |
||
| 115 | num_base_axis = len(classes) |
||
| 116 | else: |
||
| 117 | num_base_axis = len(classes) - 1 |
||
| 118 | num_sec_axis = len(methods) |
||
| 119 | for j in range(len(methods)): |
||
| 120 | xtick_labels.append(methods[j]) |
||
| 121 | for i in range(len(classes)): |
||
| 122 | if bg_class_id < 0 or i < bg_class_id: |
||
| 123 | bar_colors.append(class_colors[i]) |
||
| 124 | plot_data[j * num_base_axis + i, :] = plot_metric_arrays[j][i, :] |
||
| 125 | elif i > bg_class_id: |
||
| 126 | bar_colors.append(class_colors[i]) |
||
| 127 | plot_data[j * num_base_axis + i - 1, :] = plot_metric_arrays[j][i, :] |
||
| 128 | # Calculate width and bar location |
||
| 129 | width = 1/(num_base_axis + 1) |
||
| 130 | ind = [] |
||
| 131 | for i in range(num_sec_axis): |
||
| 132 | for j in range(num_base_axis): |
||
| 133 | ind.append(i + j * width + width) |
||
| 134 | bottom = np.zeros((num_base_axis * num_sec_axis,)) |
||
| 135 | # Set major and minor lines for y_axis |
||
| 136 | if as_percent: |
||
| 137 | minor_locator_value = 0.05 |
||
| 138 | major_locator_value = 0.2 |
||
| 139 | else: |
||
| 140 | max_value = np.max(plot_data.sum(axis=1)) + 20 |
||
| 141 | minor_locator_value = int(max_value/20) |
||
| 142 | major_locator_value = int(max_value/5) |
||
| 143 | # Set up x_label location |
||
| 144 | xlabel_ind = [] |
||
| 145 | if group_by == 'methods': |
||
| 146 | xlabel_ind = [x + width/2 for x in ind] |
||
| 147 | xlabel_rotation = 'vertical' |
||
| 148 | else: |
||
| 149 | xlabel_ind = [x + 0.5 for x in range(len(methods))] |
||
| 150 | xlabel_rotation = 'horizontal' |
||
| 151 | # Setup Figure |
||
| 152 | fig, ax = plt.subplots() |
||
| 153 | # Y-Axis |
||
| 154 | minor_locator = MultipleLocator(minor_locator_value) |
||
| 155 | major_locator = MultipleLocator(major_locator_value) |
||
| 156 | ax.yaxis.set_minor_locator(minor_locator) |
||
| 157 | ax.yaxis.set_major_locator(major_locator) |
||
| 158 | ax.yaxis.grid(which="major", color='0.65', linestyle='-', linewidth=1) |
||
| 159 | ax.yaxis.grid(which="minor", color='0.45', linestyle=' ', linewidth=1) |
||
| 160 | # Plot Bar |
||
| 161 | for i in range(len(metric_labels)): |
||
| 162 | ax.bar(ind, plot_data[:, i], width, |
||
| 163 | alpha=(1-1/len(metric_labels) * i), |
||
| 164 | color=bar_colors, bottom=bottom) |
||
| 165 | bottom += plot_data[:, i] |
||
| 166 | if as_percent: |
||
| 167 | plt.ylabel('Percentage') |
||
| 168 | else: |
||
| 169 | plt.ylabel('Count') |
||
| 170 | plt.xlabel('Classes') |
||
| 171 | plt.xticks(xlabel_ind, xtick_labels, rotation=xlabel_rotation, fontsize=6) |
||
| 172 | # Prepare Legends |
||
| 173 | patches = [] |
||
| 174 | legend_labels = [] |
||
| 175 | for i in range(len(metric_labels)): |
||
| 176 | patches.append(Rectangle((0, 0), 0, 0, color='0.3', alpha=(1-1/len(metric_labels) * i))) |
||
| 177 | legend_labels.append(metric_labels[i]) |
||
| 178 | for i in range(len(classes)): |
||
| 179 | if i == bg_class_id: |
||
| 180 | continue |
||
| 181 | patches.append(Rectangle((0, 0), 0, 0, color=class_colors[i])) |
||
| 182 | legend_labels.append(classes[i]) |
||
| 183 | plt.legend(patches, legend_labels, loc='center left', borderaxespad=0, bbox_to_anchor=(1.05, 0.5), |
||
| 184 | prop={'size': 8}) |
||
| 185 | plt.tight_layout() |
||
| 186 | plt.title('Event-based Activity Analysis - %s' % metric_name) |
||
| 187 | if filename is None: |
||
| 188 | plt.show() |
||
| 189 | else: |
||
| 190 | plt.savefig(filename, bbox_inches='tight') |
||
| 191 | |||
| 328 |