| Conditions | 11 |
| Total Lines | 78 |
| Code Lines | 70 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 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 savu.plugins.stats.stats_utils.StatsUtils.generate_figures() 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 matplotlib.pyplot as plt |
||
| 12 | def generate_figures(self, filepath, savepath): |
||
| 13 | f = h5.File(filepath, 'r') |
||
| 14 | stats_dict, index_dict = self._get_dicts_for_graphs(f) |
||
| 15 | f.close() |
||
| 16 | p_stats = pd.DataFrame(stats_dict["projection"], index_dict["projection"]["max"]) |
||
| 17 | r_stats = pd.DataFrame(stats_dict["reconstruction"], index_dict["reconstruction"]["max"]) |
||
| 18 | all_stats = pd.concat([p_stats, r_stats], keys=["Projection", "Reconstruction"]) |
||
| 19 | all_stats.to_html(f"{savepath}/stats_table.html") # create table of all stats for all plugins |
||
| 20 | |||
| 21 | stats_dict, array_plugins = self._remove_arrays(stats_dict, index_dict) |
||
| 22 | |||
| 23 | p_stats_new = pd.DataFrame(stats_dict["projection"], index_dict["projection"]["max"]) |
||
| 24 | r_stats_new = pd.DataFrame(stats_dict["reconstruction"], index_dict["reconstruction"]["max"]) |
||
| 25 | |||
| 26 | colours = ["red", "blue", "green", "black", "purple", "brown"] |
||
| 27 | # creating projection stats figure |
||
| 28 | new_p_index = [] |
||
| 29 | p_legend = "" |
||
| 30 | for ind in p_stats_new.index: |
||
| 31 | new_p_index.append(ind[0]) # change x ticks to only be plugin numbers rather than names (for space) |
||
| 32 | p_legend += f"{ind}\n" |
||
| 33 | p_stats_new.index = new_p_index |
||
| 34 | fig, ax = plt.subplots(3, 2, figsize=(11, 9), dpi=320, facecolor="azure") |
||
| 35 | i = 0 |
||
| 36 | for row in ax: |
||
| 37 | for axis in row: |
||
| 38 | stat = self._stats_list[i] |
||
| 39 | axis.plot(p_stats_new[stat], "x-", color=colours[i]) |
||
| 40 | for plugin in array_plugins["projection"]: # adding 'error' bars for plugins with different values due to parameter changes |
||
| 41 | my_max = max(p_stats[stat][plugin]) |
||
| 42 | my_min = min(p_stats[stat][plugin]) |
||
| 43 | middle = (my_max + my_min) / 2 |
||
| 44 | my_range = my_max - my_min |
||
| 45 | axis.errorbar(int(plugin[0]) - len(p_stats_new) + 1, middle, yerr=[my_range], capsize=5) |
||
| 46 | if i == 1: |
||
| 47 | maxx = len(p_stats_new[stat]) * 1.08 - 1 |
||
| 48 | maxy = max(p_stats_new[stat]) |
||
| 49 | axis.text(maxx, maxy, p_legend, ha="left", va="top", |
||
| 50 | bbox=dict(boxstyle="round", facecolor="red", alpha=0.4)) |
||
| 51 | stat.replace("_", " ") |
||
| 52 | axis.set_title(stat) |
||
| 53 | axis.grid(True) |
||
| 54 | i += 1 |
||
| 55 | fig.suptitle("Projection Stats", fontsize="x-large") |
||
| 56 | plt.savefig(f"{savepath}/projection_stats.png", bbox_inches="tight") |
||
| 57 | |||
| 58 | # creating reconstruction stats figure |
||
| 59 | new_r_index = [] |
||
| 60 | r_legend = "" |
||
| 61 | for ind in r_stats_new.index: |
||
| 62 | new_r_index.append(ind[0]) # change x ticks to only be plugin numbers rather than names (for space) |
||
| 63 | r_legend += f"{ind}\n" |
||
| 64 | r_stats_new.index = new_r_index |
||
| 65 | |||
| 66 | fig, ax = plt.subplots(3, 2, figsize=(11, 9), dpi=320, facecolor="lavender") |
||
| 67 | i = 0 |
||
| 68 | for row in ax: |
||
| 69 | for axis in row: |
||
| 70 | stat = self._stats_list[i] |
||
| 71 | axis.plot(r_stats_new[stat], "x-", color=colours[i]) |
||
| 72 | for plugin in array_plugins["reconstruction"]: # adding 'error' bars for plugins with different values due to parameter changes |
||
| 73 | my_max = max(r_stats[stat][plugin]) |
||
| 74 | my_min = min(r_stats[stat][plugin]) |
||
| 75 | middle = (my_max + my_min) / 2 |
||
| 76 | my_range = my_max - my_min |
||
| 77 | axis.errorbar(int(plugin[0]) - len(r_stats_new) + 1, middle, yerr=[my_range], capsize=5) |
||
| 78 | if i == 1: |
||
| 79 | maxx = len(r_stats_new[stat]) * 1.08 - 1 |
||
| 80 | maxy = max(r_stats_new[stat]) |
||
| 81 | axis.text(maxx, maxy, r_legend, ha="left", va="top", |
||
| 82 | bbox=dict(boxstyle="round", facecolor="red", alpha=0.4)) |
||
| 83 | stat = stat.replace("_", " ") |
||
| 84 | axis.set_title(stat) |
||
| 85 | axis.grid(True) |
||
| 86 | i += 1 |
||
| 87 | |||
| 88 | fig.suptitle("Reconstruction Stats", fontsize="x-large") |
||
| 89 | plt.savefig(f"{savepath}/reconstruction_stats.png", bbox_inches="tight") |
||
| 90 | |||
| 135 |