|
| 1 | +""" |
| 2 | + Spatial Bloom Filter Python Library (libSBF-python) |
| 3 | + Copyright (C) 2017 Luca Calderoni, Dario Maio, |
| 4 | + University of Bologna |
| 5 | + Copyright (C) 2017 Paolo Palmieri, |
| 6 | + University College Cork |
| 7 | +
|
| 8 | + This program is free software: you can redistribute it and/or modify |
| 9 | + it under the terms of the GNU Lesser General Public License as published by |
| 10 | + the Free Software Foundation, either version 3 of the License, or |
| 11 | + (at your option) any later version. |
| 12 | +
|
| 13 | + This program is distributed in the hope that it will be useful, |
| 14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + GNU Lesser General Public License for more details. |
| 17 | +
|
| 18 | + You should have received a copy of the GNU Lesser General Public License |
| 19 | + along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | + """ |
| 21 | + |
| 22 | + |
| 23 | +import sbf |
| 24 | +import matplotlib.pyplot as plt |
| 25 | +import numpy as np |
| 26 | +from datetime import datetime |
| 27 | + |
| 28 | +PLOT_PRECISION = 255 |
| 29 | + |
| 30 | + |
| 31 | +def sbfplot_areas_barchart(filter, title = 'Elements per set', show = True, save = True, format = 'pdf', filename = ''): |
| 32 | + """Plots the bar chart of the number of elements per area for a given filter. |
| 33 | +
|
| 34 | + Plots the bar chart of the number of elements for each set of dataset the filter |
| 35 | + has been built on. |
| 36 | +
|
| 37 | + Attributes: |
| 38 | + filter: the SBF filter to plot |
| 39 | + title: the plot title (default: 'Elements per set') |
| 40 | + show: display the plot (default: True) |
| 41 | + save: save the plot (default: True) |
| 42 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 43 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 44 | + to sbfplot-elements-DATETIME.FORMAT in the function) |
| 45 | + """ |
| 46 | + |
| 47 | + __sbfplot_check_args(filter, format) |
| 48 | + if (filename == ''): |
| 49 | + filename = 'sbfplot-elements-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 50 | + filename = filename + '.' + format |
| 51 | + |
| 52 | + x = list(range(1, filter.num_areas+1)) |
| 53 | + y = [filter.area_members[i] for i in x] |
| 54 | + plt.bar(x, y) |
| 55 | + |
| 56 | + if not (filter.insert_file_list[0] == ''): |
| 57 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 58 | + plt.title(title) |
| 59 | + plt.xlabel('Set') |
| 60 | + plt.ylabel('Members') |
| 61 | + plt.tight_layout() |
| 62 | + plt.grid(False) |
| 63 | + if (save): |
| 64 | + plt.savefig(filename) |
| 65 | + print('Plot saved as ' + filename) |
| 66 | + if (show): |
| 67 | + plt.show() |
| 68 | + plt.clf() |
| 69 | + |
| 70 | + |
| 71 | +def sbfplot_cells(filter, expected = True, title = 'Cells', legend = 'upper left', show = True, save = True, format = 'pdf', filename = ''): |
| 72 | + """Plots the number of cells for the sets of a given filter. |
| 73 | +
|
| 74 | + Plots the number of cells for the sets of the filter given as argument. If the |
| 75 | + respective arguments are true, also plots the a priori isep, the iser and the expected ise. |
| 76 | +
|
| 77 | + Attributes: |
| 78 | + filter: the SBF filter to plot |
| 79 | + expected: plot the expected number of cells as well (default: True) |
| 80 | + potential: plot the potential number of cells as well (default: True) |
| 81 | + title: the plot title (default: 'Cells') |
| 82 | + show: display the plot (default: True) |
| 83 | + save: save the plot (default: True) |
| 84 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 85 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 86 | + to sbfplot-cells-DATETIME.FORMAT in the function) |
| 87 | + """ |
| 88 | + |
| 89 | + __sbfplot_check_args(filter, format) |
| 90 | + if (filename == ''): |
| 91 | + filename = 'sbfplot-cells-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 92 | + filename = filename + '.' + format |
| 93 | + |
| 94 | + x = list(range(1, filter.num_areas+1)) |
| 95 | + #x = np.arange(1, filter.num_areas+1, round(filter.num_areas/PLOT_PRECISION)) |
| 96 | + y = [filter.area_cells[i] for i in x] |
| 97 | + plt.bar(x, y, label='Cells') |
| 98 | + |
| 99 | + if (expected): |
| 100 | + if not hasattr(filter, 'area_expected_cells'): |
| 101 | + filter.expected_area_cells() |
| 102 | + y_exp = [filter.area_expected_cells[i] for i in x] |
| 103 | + plt.plot(x, y_exp, linewidth='0.8', color='red', label='Expected cells') |
| 104 | + |
| 105 | + legend = plt.legend(loc=legend) |
| 106 | + |
| 107 | + if not (filter.insert_file_list[0] == ''): |
| 108 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 109 | + plt.title(title) |
| 110 | + plt.xlabel('Set') |
| 111 | + plt.ylabel('Cells') |
| 112 | + plt.tight_layout() |
| 113 | + plt.grid(False) |
| 114 | + if (save): |
| 115 | + plt.savefig(filename) |
| 116 | + print('Plot saved as ' + filename) |
| 117 | + if (show): |
| 118 | + plt.show() |
| 119 | + plt.clf() |
| 120 | + |
| 121 | + |
| 122 | +def sbfplot_emersion(filter, expected = True, title = 'Emersion', legend = 'upper left', show = True, save = True, format = 'pdf', filename = ''): |
| 123 | + """Plots the emersion for a given filter. |
| 124 | +
|
| 125 | + Plots the emersion value for the filter given as argument, over the number |
| 126 | + of sets the filter has been built on. If the respective argument is true, |
| 127 | + also plots the expected emersion. |
| 128 | +
|
| 129 | + Attributes: |
| 130 | + filter: the SBF filter to plot |
| 131 | + expected: plot the expected emersion as well as the actual emersion |
| 132 | + (default: True) |
| 133 | + title: the plot title (default: 'Emersion') |
| 134 | + show: display the plot (default: True) |
| 135 | + save: save the plot (default: True) |
| 136 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 137 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 138 | + to sbfplot-emersion-DATETIME.FORMAT in the function) |
| 139 | + """ |
| 140 | + |
| 141 | + __sbfplot_check_args(filter, format) |
| 142 | + if (filename == ''): |
| 143 | + filename = 'sbfplot-emersion-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 144 | + filename = filename + '.' + format |
| 145 | + |
| 146 | + x = np.arange(1, filter.num_areas+1, round(filter.num_areas/PLOT_PRECISION)) |
| 147 | + |
| 148 | + if (expected): |
| 149 | + y_exp = [filter.expected_area_emersion(i) for i in x] |
| 150 | + plt.plot(x, y_exp, color='red', label='Expected emersion') |
| 151 | + |
| 152 | + y = [filter.area_emersion(i) for i in x] |
| 153 | + plt.plot(x, y, label='Emersion') |
| 154 | + |
| 155 | + legend = plt.legend(loc=legend) |
| 156 | + |
| 157 | + if not (filter.insert_file_list[0] == ''): |
| 158 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 159 | + plt.title(title) |
| 160 | + plt.xlabel('Set') |
| 161 | + plt.ylabel('Emersion') |
| 162 | + plt.tight_layout() |
| 163 | + plt.grid(True) |
| 164 | + if (save): |
| 165 | + plt.savefig(filename) |
| 166 | + print('Plot saved as ' + filename) |
| 167 | + if (show): |
| 168 | + plt.show() |
| 169 | + plt.clf() |
| 170 | + |
| 171 | + |
| 172 | +def sbfplot_fpp(filter, apriori = True, non_elements_path = '', title = 'False positive probability', legend = 'upper right', show = True, save = True, format = 'pdf', filename = ''): |
| 173 | + """Plots the fpp for a given filter. |
| 174 | +
|
| 175 | + Plots the false positive probability value for the filter given as argument, |
| 176 | + over the number of sets the filter has been built on. If the respective argument |
| 177 | + is true, also plots the a priori fpp. If a test file containing elements that |
| 178 | + are not part of the filter originating sets (non-elements) is given, the false |
| 179 | + positive rate is also calculated and plotted. |
| 180 | +
|
| 181 | + Attributes: |
| 182 | + filter: the SBF filter to plot |
| 183 | + apriori: plot the a priori fpp as well as the actual isep (default: True) |
| 184 | + non_elements_path: plot the false positive rate calculated on the given |
| 185 | + file (which must contain only elements that have not been |
| 186 | + inserted in the filter) (default: '') |
| 187 | + title: the plot title (default: 'False positive probability') |
| 188 | + show: display the plot (default: True) |
| 189 | + save: save the plot (default: True) |
| 190 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 191 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 192 | + to sbfplot-fpp-DATETIME.FORMAT in the function) |
| 193 | + """ |
| 194 | + |
| 195 | + __sbfplot_check_args(filter, format) |
| 196 | + if (filename == ''): |
| 197 | + filename = 'sbfplot-fpp-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 198 | + filename = filename + '.' + format |
| 199 | + |
| 200 | + x = np.arange(1, filter.num_areas+1, round(filter.num_areas/PLOT_PRECISION)) |
| 201 | + |
| 202 | + if (apriori): |
| 203 | + if not hasattr(filter, 'area_apriori_fpp'): |
| 204 | + filter.compute_apriori_area_fpp() |
| 205 | + y_apriori = [filter.area_apriori_fpp[i] for i in x] |
| 206 | + plt.plot(x, y_apriori, color='red', label='A priori FPP') |
| 207 | + |
| 208 | + if not hasattr(filter, 'area_fpp'): |
| 209 | + filter.compute_area_fpp() |
| 210 | + y = [filter.area_fpp[i] for i in x] |
| 211 | + plt.plot(x, y, label='FPP') |
| 212 | + |
| 213 | + if not (non_elements_path == ''): |
| 214 | + filter.check_from_file(non_elements_path) |
| 215 | + area_results = [0]*(filter.num_areas + 1) |
| 216 | + for j in range(1, filter.num_areas + 1): |
| 217 | + area_results[j] = filter.check_results.count(j) |
| 218 | + y_iser = [area_results[i]/len(filter.check_results) for i in x] |
| 219 | + plt.plot(x, y_iser, color='C2', label='FPR') |
| 220 | + |
| 221 | + legend = plt.legend(loc=legend) |
| 222 | + |
| 223 | + if not (filter.insert_file_list[0] == ''): |
| 224 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 225 | + plt.title(title) |
| 226 | + plt.xlabel('Set') |
| 227 | + plt.ylabel('FPP') |
| 228 | + plt.tight_layout() |
| 229 | + plt.grid(True) |
| 230 | + if (save): |
| 231 | + plt.savefig(filename) |
| 232 | + print('Plot saved as ' + filename) |
| 233 | + if (show): |
| 234 | + plt.show() |
| 235 | + plt.clf() |
| 236 | + |
| 237 | + |
| 238 | +def sbfplot_isep(filter, apriori = True, iser = True, expected_ise = False, title = 'Inter-set errors', legend = 'upper right', show = True, save = True, format = 'pdf', filename = ''): |
| 239 | + """Plots the isep for a given filter. |
| 240 | +
|
| 241 | + Plots the isep value for the filter given as argument, over the number |
| 242 | + of sets the filter has been built on. If the respective arguments are true, |
| 243 | + also plots the a priori isep, the iser and the expected ise. |
| 244 | +
|
| 245 | + Attributes: |
| 246 | + filter: the SBF filter to plot |
| 247 | + apriori: plot the a priori isep as well as the actual isep (default: True) |
| 248 | + iser: plot the iser (the actual error rate) (default: True) |
| 249 | + expected_ise: plot the expected ise as well (default: False) |
| 250 | + title: the plot title (default: 'Inter-set errors') |
| 251 | + show: display the plot (default: True) |
| 252 | + save: save the plot (default: True) |
| 253 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 254 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 255 | + to sbfplot-isep-DATETIME.FORMAT in the function) |
| 256 | + """ |
| 257 | + |
| 258 | + __sbfplot_check_args(filter, format) |
| 259 | + if (filename == ''): |
| 260 | + filename = 'sbfplot-isep-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 261 | + filename = filename + '.' + format |
| 262 | + |
| 263 | + x = np.arange(1, filter.num_areas+1, round(filter.num_areas/PLOT_PRECISION)) |
| 264 | + |
| 265 | + if (apriori): |
| 266 | + if not hasattr(filter, 'area_apriori_isep'): |
| 267 | + filter.compute_apriori_area_isep() |
| 268 | + y_apriori = [filter.area_apriori_isep[i] for i in x] |
| 269 | + plt.plot(x, y_apriori, color='red', label='A priori ISEP') |
| 270 | + |
| 271 | + if not hasattr(filter, 'area_isep'): |
| 272 | + filter.compute_area_isep() |
| 273 | + y = [filter.area_isep[i] for i in x] |
| 274 | + plt.plot(x, y, label='ISEP') |
| 275 | + |
| 276 | + if (iser): |
| 277 | + if (not hasattr(filter, 'check_results')) or (not (isinstance(filter.check_results[0], str))): |
| 278 | + if (len(filter.insert_file_list) == 1): |
| 279 | + filter.check_from_file(filter.insert_file_list[0]) |
| 280 | + else: |
| 281 | + raise ValueError("The current implementation of libsbfplot only works with filters built on a single insert file.") |
| 282 | + area_results = [0]*(filter.num_areas + 1) |
| 283 | + for j in range(0, len(filter.check_results)): |
| 284 | + if not (filter.check_results[j][0]): |
| 285 | + area_results[int(filter.check_results[j][1])] += 1 |
| 286 | + y_iser = [area_results[i]/filter.area_members[i] for i in x] |
| 287 | + plt.plot(x, y_iser, color='C2', label='ISER') |
| 288 | + |
| 289 | + if (expected_ise): |
| 290 | + y_exp = [(filter.area_apriori_isep[i] * filter.area_members[i]) for i in x] |
| 291 | + plt.plot(x, y_exp, label='Expected ISE') |
| 292 | + |
| 293 | + legend = plt.legend(loc=legend) |
| 294 | + |
| 295 | + if not (filter.insert_file_list[0] == ''): |
| 296 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 297 | + plt.title(title) |
| 298 | + plt.xlabel('Set') |
| 299 | + plt.ylabel('ISEP') |
| 300 | + plt.tight_layout() |
| 301 | + plt.grid(True) |
| 302 | + if (save): |
| 303 | + plt.savefig(filename) |
| 304 | + print('Plot saved as ' + filename) |
| 305 | + if (show): |
| 306 | + plt.show() |
| 307 | + plt.clf() |
| 308 | + |
| 309 | +def sbfplot_safep(filter, title = 'A priori safeness probability', legend = 'upper left', show = True, save = True, format = 'pdf', filename = ''): |
| 310 | + """Plots the area safep for a given filter. |
| 311 | +
|
| 312 | + Plots the area-specific a priori safeness probability value for the filter |
| 313 | + given as argument, over the number of sets the filter has been built on. |
| 314 | +
|
| 315 | + Attributes: |
| 316 | + filter: the SBF filter to plot |
| 317 | + title: the plot title (default: 'A priori safeness probability') |
| 318 | + show: display the plot (default: True) |
| 319 | + save: save the plot (default: True) |
| 320 | + format: format of the plot: png, pdf, ps, eps or svg (default: 'pdf') |
| 321 | + filename: the filname the plot should be saved as (default: '', but assigned |
| 322 | + to sbfplot-safep-DATETIME.FORMAT in the function) |
| 323 | + """ |
| 324 | + |
| 325 | + __sbfplot_check_args(filter, format) |
| 326 | + if (filename == ''): |
| 327 | + filename = 'sbfplot-safep-' + datetime.now().strftime("%Y%m%d-%H%M%S") |
| 328 | + filename = filename + '.' + format |
| 329 | + |
| 330 | + x = np.arange(1, filter.num_areas+1, round(filter.num_areas/PLOT_PRECISION)) |
| 331 | + |
| 332 | + if not hasattr(filter, 'area_apriori_safep'): |
| 333 | + filter.compute_apriori_area_isep() |
| 334 | + y = [filter.area_apriori_safep[i] for i in x] |
| 335 | + plt.plot(x, y, label='SAFEP') |
| 336 | + |
| 337 | + legend = plt.legend(loc=legend) |
| 338 | + |
| 339 | + if not (filter.insert_file_list[0] == ''): |
| 340 | + title = title + ' (' + filter.insert_file_list[0] + ')' |
| 341 | + plt.title(title) |
| 342 | + plt.xlabel('Set') |
| 343 | + plt.ylabel('SAFEP') |
| 344 | + plt.tight_layout() |
| 345 | + plt.grid(True) |
| 346 | + if (save): |
| 347 | + plt.savefig(filename) |
| 348 | + print('Plot saved as ' + filename) |
| 349 | + if (show): |
| 350 | + plt.show() |
| 351 | + plt.clf() |
| 352 | + |
| 353 | + |
| 354 | +def __sbfplot_check_args(filter, format): |
| 355 | + """ [Internal] Check the format and filename arguments |
| 356 | +
|
| 357 | + [Internal] Check the format and filename arguments. This function is called |
| 358 | + by other library functions. |
| 359 | +
|
| 360 | + Raises: |
| 361 | + AttributeError: The format argument is invalid. |
| 362 | + AttributeError: The filter argument is not an sbf object. |
| 363 | + """ |
| 364 | + |
| 365 | + if (format not in ['png', 'pdf', 'ps', 'eps', 'svg']): |
| 366 | + raise AttributeError("Invalid format (it should be png, pdf, ps, eps or svg).") |
| 367 | + |
| 368 | + if (not isinstance(filter, sbf.sbf)): |
| 369 | + raise AttributeError("The filter passed as argument is not an SBF.") |
| 370 | + |
| 371 | + if (filter.members == 0): |
| 372 | + raise AttributeError("The filter passed as argument is empty.") |
0 commit comments