-
Notifications
You must be signed in to change notification settings - Fork 194
Expand file tree
/
Copy patho2dpg_release_validation_plot.py
More file actions
executable file
·221 lines (179 loc) · 8.32 KB
/
o2dpg_release_validation_plot.py
File metadata and controls
executable file
·221 lines (179 loc) · 8.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#!/usr/bin/env python3
#
# Definition common functionality
import sys
from os.path import join
from os import environ
import importlib.util
from itertools import product
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import seaborn
from scipy.stats import iqr
O2DPG_ROOT = environ.get("O2DPG_ROOT")
spec = importlib.util.spec_from_file_location("o2dpg_release_validation_utils", join(O2DPG_ROOT, "RelVal", "utils", '.', 'o2dpg_release_validation_utils.py'))
o2dpg_release_validation_utils = importlib.util.module_from_spec(spec)
spec.loader.exec_module(o2dpg_release_validation_utils)
sys.modules["o2dpg_release_validation_utils"] = o2dpg_release_validation_utils
from o2dpg_release_validation_utils import count_interpretations
spec = importlib.util.spec_from_file_location("o2dpg_release_validation_plot_root", join(O2DPG_ROOT, "RelVal", "utils", '.', 'o2dpg_release_validation_plot_root.py'))
o2dpg_release_validation_plot_root = importlib.util.module_from_spec(spec)
spec.loader.exec_module(o2dpg_release_validation_plot_root)
sys.modules["o2dpg_release_validation_plot_root"] = o2dpg_release_validation_plot_root
from o2dpg_release_validation_plot_root import plot_overlays_root, plot_overlays_root_no_rel_val
def plot_pie_charts(rel_val, interpretations, interpretation_colors, out_dir, title="", get_figure=False):
"""
Plot pie charts per metric and test
Each pie chart shows the ratio of given interpretations
"""
print("==> Plot pie charts <==")
for metric_name, test_name in product(rel_val.known_metrics, rel_val.known_test_names):
figure, ax = plt.subplots(figsize=(20, 20))
# collect counts of interpretations, their colours and labels
counts = []
colors = []
labels = []
object_names, results = rel_val.get_result_per_metric_and_test(metric_name, test_name)
if not len(object_names):
continue
for interpretation in interpretations:
n_objects = len(object_names[count_interpretations(results, interpretation)])
if not n_objects:
continue
counts.append(n_objects)
colors.append(interpretation_colors[interpretation])
labels.append(interpretation)
ax.pie(counts, explode=[0.05 for _ in counts], labels=labels, autopct="%1.1f%%", startangle=90, textprops={"fontsize": 30}, colors=colors)
ax.axis("equal")
ax.axis("equal")
figure.suptitle(f"{title} (metric: {metric_name}, test: {test_name})", fontsize=40)
save_path = join(out_dir, f"pie_chart_{metric_name}_{test_name}.png")
figure.savefig(save_path)
if get_figure:
return figure
plt.close(figure)
def plot_value_histograms(rel_val, out_dir, title="values histogram", get_figure=False):
"""
Plot a histogram of metric values
"""
print("==> Plot value histograms <==")
for metric_name in rel_val.known_metrics:
figure, ax = plt.subplots(figsize=(20, 20))
values = []
for _, _, metric in zip(*rel_val.get_metrics(metric_name=metric_name)):
if not metric.comparable:
continue
values.append(metric.value)
if not values:
continue
ax.set_xlabel(metric_name, fontsize=20)
ax.set_ylabel("counts", fontsize=20)
ax.hist(values, bins=100)
ax.tick_params("both", labelsize=20)
figure.tight_layout()
figure.suptitle(f"{title} (metric: {metric_name})", fontsize=40)
save_path = join(out_dir, f"histogram_values_{metric_name}.png")
figure.savefig(save_path)
if get_figure:
return figure
plt.close(figure)
def plot_summary_grid(rel_val, interpretations, interpretation_colors, output_dir, get_figure=False):
"""
Plot a summary grid per test.
horizontal axis: metric names
vertical axis: object names
Each cell is coloured according to an interpretation.
In addition, the cells contain the computed metric values
"""
print("==> Plot summary grid <==")
interpretation_name_to_number = {v: i for i, v in enumerate(interpretations)}
colors = [None] * len(interpretation_name_to_number)
for name, color in interpretation_colors.items():
colors[interpretation_name_to_number[name]] = color
cmap = LinearSegmentedColormap.from_list("Custom", colors, len(colors))
figures = []
for nt in range(rel_val.number_of_tests):
metric_names, object_names, results_matrix = rel_val.get_result_matrix_objects_metrics(nt)
# make an array where each interpretation is mapped to a numerical value
arr_interpretation = np.full(results_matrix.shape, 0, dtype=int)
# collect annotations for each cell
arr_annot = np.full(results_matrix.shape, "", dtype=object)
# iterate over the cells and set values and annotations
it = np.nditer(results_matrix, flags=['multi_index', "refs_ok"])
for _ in it:
result = results_matrix[it.multi_index]
arr_interpretation[it.multi_index] = interpretation_name_to_number[result.interpretation]
if result.value is not None:
annot = f"{result.value:.3f} (mean: {result.mean:.3f})"
if result.n_sigmas is not None:
annot += f" (n_sigma: {result.n_sigmas:.3f})"
else:
annot = result.non_comparable_note
arr_annot[it.multi_index] = annot
#now comes the plotting
figure, ax = plt.subplots(figsize=(20, 20))
seaborn.heatmap(arr_interpretation, ax=ax, cmap=cmap, vmin=-0.5, vmax=len(interpretations) - 0.5, yticklabels=object_names, xticklabels=metric_names, linewidths=0.5, annot=arr_annot, fmt="")
cbar = ax.collections[0].colorbar
cbar.set_ticks(range(len(colors)))
cbar.set_ticklabels(interpretations)
ax.set_title("Test summary [value (mean), (n_sigmas)]", fontsize=30)
figure.tight_layout()
if get_figure:
figures.append(figure)
continue
output_path = join(output_dir, f"summary_{rel_val.get_test_name(nt)}.png")
figure.savefig(output_path)
plt.close(figure)
if get_figure:
return figures
def plot_compare_summaries(rel_vals, out_dir, *, labels=None, get_figure=False):
"""
Plot the metric values for each object.
"""
print("==> Plot metric values <==")
figures = []
if not labels:
labels = [f"summary_{i}" for i, _ in enumerate(rel_vals)]
test_names = list(rel_vals[0].known_test_names)
metric_names = list(rel_vals[0].known_metrics)
for rel_val in rel_vals[1:]:
test_names = list(set(test_names + list(rel_val.known_test_names)))
metric_names = list(set(metric_names + list(rel_val.known_metrics)))
for metric_name, test_name in product(metric_names, test_names):
figure, ax = plt.subplots(figsize=(20, 20))
plot_this = False
for rel_val, label in zip(rel_vals, labels):
object_names, results = rel_val.get_result_per_metric_and_test(metric_name, test_name)
values = [result.value for result in results]
means = [result.mean for result in results]
if not values:
continue
plot_this = True
ax.plot(object_names, values, label=f"values_{label}")
ax.plot(object_names, means, label=f"test_means_{label}")
if not plot_this:
continue
ax.legend(loc="best", fontsize=20)
ax.tick_params("both", labelsize=20)
ax.tick_params("x", rotation=90)
figure.tight_layout()
figure.savefig(join(out_dir, f"values_thresholds_{metric_name}_{test_name}.png"))
if get_figure:
figures.append(figure)
continue
plt.close(figure)
if get_figure:
return figures
def plot_overlays(rel_val, file_config_map1, file_config_map2, out_dir, plot_regex=None):
"""
Wrapper around ROOT overlay plotting
"""
print("==> Plot overlays <==")
plot_overlays_root(rel_val, file_config_map1, file_config_map2, out_dir, plot_regex)
def plot_overlays_no_rel_val(file_configs, out_dir):
"""
Wrapper around ROOT plotting when no RelVal object is given
"""
print("==> Plot overlays <==")
plot_overlays_root_no_rel_val(file_configs, out_dir)