megadetector 5.0.28__py3-none-any.whl → 5.0.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of megadetector might be problematic. Click here for more details.

Files changed (176) hide show
  1. megadetector/api/batch_processing/api_core/batch_service/score.py +4 -5
  2. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +1 -1
  3. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +1 -1
  4. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  5. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  6. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  7. megadetector/api/synchronous/api_core/tests/load_test.py +2 -3
  8. megadetector/classification/aggregate_classifier_probs.py +3 -3
  9. megadetector/classification/analyze_failed_images.py +5 -5
  10. megadetector/classification/cache_batchapi_outputs.py +5 -5
  11. megadetector/classification/create_classification_dataset.py +11 -12
  12. megadetector/classification/crop_detections.py +10 -10
  13. megadetector/classification/csv_to_json.py +8 -8
  14. megadetector/classification/detect_and_crop.py +13 -15
  15. megadetector/classification/evaluate_model.py +7 -7
  16. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  17. megadetector/classification/json_to_azcopy_list.py +1 -1
  18. megadetector/classification/json_validator.py +29 -32
  19. megadetector/classification/map_classification_categories.py +9 -9
  20. megadetector/classification/merge_classification_detection_output.py +12 -9
  21. megadetector/classification/prepare_classification_script.py +19 -19
  22. megadetector/classification/prepare_classification_script_mc.py +23 -23
  23. megadetector/classification/run_classifier.py +4 -4
  24. megadetector/classification/save_mislabeled.py +6 -6
  25. megadetector/classification/train_classifier.py +1 -1
  26. megadetector/classification/train_classifier_tf.py +9 -9
  27. megadetector/classification/train_utils.py +10 -10
  28. megadetector/data_management/annotations/annotation_constants.py +1 -1
  29. megadetector/data_management/camtrap_dp_to_coco.py +45 -45
  30. megadetector/data_management/cct_json_utils.py +101 -101
  31. megadetector/data_management/cct_to_md.py +49 -49
  32. megadetector/data_management/cct_to_wi.py +33 -33
  33. megadetector/data_management/coco_to_labelme.py +75 -75
  34. megadetector/data_management/coco_to_yolo.py +189 -189
  35. megadetector/data_management/databases/add_width_and_height_to_db.py +3 -2
  36. megadetector/data_management/databases/combine_coco_camera_traps_files.py +38 -38
  37. megadetector/data_management/databases/integrity_check_json_db.py +202 -188
  38. megadetector/data_management/databases/subset_json_db.py +33 -33
  39. megadetector/data_management/generate_crops_from_cct.py +38 -38
  40. megadetector/data_management/get_image_sizes.py +54 -49
  41. megadetector/data_management/labelme_to_coco.py +130 -124
  42. megadetector/data_management/labelme_to_yolo.py +78 -72
  43. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  44. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  45. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  46. megadetector/data_management/lila/download_lila_subset.py +21 -24
  47. megadetector/data_management/lila/generate_lila_per_image_labels.py +91 -91
  48. megadetector/data_management/lila/get_lila_annotation_counts.py +30 -30
  49. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  50. megadetector/data_management/lila/lila_common.py +70 -70
  51. megadetector/data_management/lila/test_lila_metadata_urls.py +13 -14
  52. megadetector/data_management/mewc_to_md.py +339 -340
  53. megadetector/data_management/ocr_tools.py +258 -252
  54. megadetector/data_management/read_exif.py +231 -224
  55. megadetector/data_management/remap_coco_categories.py +26 -26
  56. megadetector/data_management/remove_exif.py +31 -20
  57. megadetector/data_management/rename_images.py +187 -187
  58. megadetector/data_management/resize_coco_dataset.py +41 -41
  59. megadetector/data_management/speciesnet_to_md.py +41 -41
  60. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  61. megadetector/data_management/yolo_output_to_md_output.py +117 -120
  62. megadetector/data_management/yolo_to_coco.py +195 -188
  63. megadetector/detection/change_detection.py +831 -0
  64. megadetector/detection/process_video.py +340 -337
  65. megadetector/detection/pytorch_detector.py +304 -262
  66. megadetector/detection/run_detector.py +177 -164
  67. megadetector/detection/run_detector_batch.py +364 -363
  68. megadetector/detection/run_inference_with_yolov5_val.py +328 -325
  69. megadetector/detection/run_tiled_inference.py +256 -249
  70. megadetector/detection/tf_detector.py +24 -24
  71. megadetector/detection/video_utils.py +290 -282
  72. megadetector/postprocessing/add_max_conf.py +15 -11
  73. megadetector/postprocessing/categorize_detections_by_size.py +44 -44
  74. megadetector/postprocessing/classification_postprocessing.py +415 -415
  75. megadetector/postprocessing/combine_batch_outputs.py +20 -21
  76. megadetector/postprocessing/compare_batch_results.py +528 -517
  77. megadetector/postprocessing/convert_output_format.py +97 -97
  78. megadetector/postprocessing/create_crop_folder.py +219 -146
  79. megadetector/postprocessing/detector_calibration.py +173 -168
  80. megadetector/postprocessing/generate_csv_report.py +508 -499
  81. megadetector/postprocessing/load_api_results.py +23 -20
  82. megadetector/postprocessing/md_to_coco.py +129 -98
  83. megadetector/postprocessing/md_to_labelme.py +89 -83
  84. megadetector/postprocessing/md_to_wi.py +40 -40
  85. megadetector/postprocessing/merge_detections.py +87 -114
  86. megadetector/postprocessing/postprocess_batch_results.py +313 -298
  87. megadetector/postprocessing/remap_detection_categories.py +36 -36
  88. megadetector/postprocessing/render_detection_confusion_matrix.py +205 -199
  89. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  90. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  91. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +702 -677
  92. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  93. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  94. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  95. megadetector/postprocessing/validate_batch_results.py +70 -70
  96. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  97. megadetector/taxonomy_mapping/map_new_lila_datasets.py +15 -15
  98. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +14 -14
  99. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +66 -66
  100. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  101. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  102. megadetector/taxonomy_mapping/species_lookup.py +33 -33
  103. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  104. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  105. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  106. megadetector/utils/azure_utils.py +22 -22
  107. megadetector/utils/ct_utils.py +1018 -200
  108. megadetector/utils/directory_listing.py +21 -77
  109. megadetector/utils/gpu_test.py +22 -22
  110. megadetector/utils/md_tests.py +541 -518
  111. megadetector/utils/path_utils.py +1457 -398
  112. megadetector/utils/process_utils.py +41 -41
  113. megadetector/utils/sas_blob_utils.py +53 -49
  114. megadetector/utils/split_locations_into_train_val.py +61 -61
  115. megadetector/utils/string_utils.py +147 -26
  116. megadetector/utils/url_utils.py +463 -173
  117. megadetector/utils/wi_utils.py +2629 -2526
  118. megadetector/utils/write_html_image_list.py +137 -137
  119. megadetector/visualization/plot_utils.py +21 -21
  120. megadetector/visualization/render_images_with_thumbnails.py +37 -73
  121. megadetector/visualization/visualization_utils.py +401 -397
  122. megadetector/visualization/visualize_db.py +197 -190
  123. megadetector/visualization/visualize_detector_output.py +79 -73
  124. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/METADATA +135 -132
  125. megadetector-5.0.29.dist-info/RECORD +163 -0
  126. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/WHEEL +1 -1
  127. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/licenses/LICENSE +0 -0
  128. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/top_level.txt +0 -0
  129. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  130. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  131. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  132. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  133. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  134. megadetector/data_management/importers/awc_to_json.py +0 -191
  135. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  136. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  137. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  138. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  139. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  140. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  141. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  142. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  143. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  144. megadetector/data_management/importers/ena24_to_json.py +0 -276
  145. megadetector/data_management/importers/filenames_to_json.py +0 -386
  146. megadetector/data_management/importers/helena_to_cct.py +0 -283
  147. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  148. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  149. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  150. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  151. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  152. megadetector/data_management/importers/missouri_to_json.py +0 -490
  153. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  154. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  155. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  156. megadetector/data_management/importers/pc_to_json.py +0 -365
  157. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  158. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  159. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  160. megadetector/data_management/importers/rspb_to_json.py +0 -356
  161. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  162. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  163. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  164. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  165. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  166. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  167. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  168. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  169. megadetector/data_management/importers/ubc_to_json.py +0 -399
  170. megadetector/data_management/importers/umn_to_json.py +0 -507
  171. megadetector/data_management/importers/wellington_to_json.py +0 -263
  172. megadetector/data_management/importers/wi_to_json.py +0 -442
  173. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  174. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  175. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  176. megadetector-5.0.28.dist-info/RECORD +0 -209
@@ -23,25 +23,25 @@ from megadetector.utils import path_utils
23
23
 
24
24
  def write_html_image_list(filename=None,images=None,options=None):
25
25
  """
26
- Given a list of image file names, writes an HTML file that shows all those images,
26
+ Given a list of image file names, writes an HTML file that shows all those images,
27
27
  with optional one-line headers above each.
28
28
 
29
29
  Args:
30
- filename (str, optional): the .html output file; if None, just returns a valid
30
+ filename (str, optional): the .html output file; if None, just returns a valid
31
31
  options dict
32
- images (list, optional): the images to write to the .html file; if None, just returns
32
+ images (list, optional): the images to write to the .html file; if None, just returns
33
33
  a valid options dict. This can be a flat list of image filenames, or this can
34
34
  be a list of dictionaries with one or more of the following fields:
35
-
35
+
36
36
  - filename (image filename) (required, all other fields are optional)
37
37
  - imageStyle (css style for this image)
38
38
  - textStyle (css style for the title associated with this image)
39
39
  - title (text label for this image)
40
40
  - linkTarget (URL to which this image should link on click)
41
-
42
- options (dict, optional): a dict with one or more of the following fields:
43
-
44
- - fHtml (file pointer to write to, used for splitting write operations over multiple calls)
41
+
42
+ options (dict, optional): a dict with one or more of the following fields:
43
+
44
+ - f_html (file pointer to write to, used for splitting write operations over multiple calls)
45
45
  - pageTitle (HTML page title)
46
46
  - headerHtml (html text to include before the image list)
47
47
  - subPageHeaderHtml (html text to include before the images when images are broken into pages)
@@ -52,28 +52,28 @@ def write_html_image_list(filename=None,images=None,options=None):
52
52
  multiple files and a TOC with links)
53
53
  - urlEncodeFilenames (default True, e.g. '#' will be replaced by '%23')
54
54
  - urlEncodeLinkTargets (default True, e.g. '#' will be replaced by '%23')
55
-
55
+
56
56
  """
57
-
57
+
58
58
  # returns an options struct
59
59
  if options is None:
60
60
  options = {}
61
-
62
- if 'fHtml' not in options:
63
- options['fHtml'] = -1
64
-
61
+
62
+ if 'f_html' not in options:
63
+ options['f_html'] = -1
64
+
65
65
  if 'pageTitle' not in options or options['pageTitle'] is None:
66
66
  options['pageTitle'] = ''
67
-
67
+
68
68
  if 'headerHtml' not in options or options['headerHtml'] is None:
69
69
  options['headerHtml'] = ''
70
-
70
+
71
71
  if 'subPageHeaderHtml' not in options or options['subPageHeaderHtml'] is None:
72
72
  options['subPageHeaderHtml'] = ''
73
-
73
+
74
74
  if 'trailerHtml' not in options or options['trailerHtml'] is None:
75
75
  options['trailerHtml'] = ''
76
-
76
+
77
77
  if 'defaultTextStyle' not in options or options['defaultTextStyle'] is None:
78
78
  options['defaultTextStyle'] = \
79
79
  "font-family:calibri,verdana,arial;font-weight:bold;font-size:150%;text-align:left;margin:0px;"
@@ -81,160 +81,160 @@ def write_html_image_list(filename=None,images=None,options=None):
81
81
  if 'defaultImageStyle' not in options or options['defaultImageStyle'] is None:
82
82
  options['defaultImageStyle'] = \
83
83
  "margin:0px;margin-top:5px;margin-bottom:5px;"
84
-
84
+
85
85
  if 'urlEncodeFilenames' not in options or options['urlEncodeFilenames'] is None:
86
86
  options['urlEncodeFilenames'] = True
87
-
87
+
88
88
  if 'urlEncodeLinkTargets' not in options or options['urlEncodeLinkTargets'] is None:
89
89
  options['urlEncodeLinkTargets'] = True
90
-
90
+
91
91
  # Possibly split the html output for figures into multiple files; Chrome gets sad with
92
- # thousands of images in a single tab.
92
+ # thousands of images in a single tab.
93
93
  if 'maxFiguresPerHtmlFile' not in options or options['maxFiguresPerHtmlFile'] is None:
94
- options['maxFiguresPerHtmlFile'] = math.inf
95
-
94
+ options['maxFiguresPerHtmlFile'] = math.inf
95
+
96
96
  if filename is None or images is None:
97
97
  return options
98
-
99
- # images may be a list of images or a list of image/style/title dictionaries,
98
+
99
+ # images may be a list of images or a list of image/style/title dictionaries,
100
100
  # enforce that it's the latter to simplify downstream code
101
- for iImage,imageInfo in enumerate(images):
102
- if isinstance(imageInfo,str):
103
- imageInfo = {'filename':imageInfo}
104
- if 'filename' not in imageInfo:
105
- imageInfo['filename'] = ''
106
- if 'imageStyle' not in imageInfo:
107
- imageInfo['imageStyle'] = options['defaultImageStyle']
108
- if 'title' not in imageInfo:
109
- imageInfo['title'] = ''
110
- if 'linkTarget' not in imageInfo:
111
- imageInfo['linkTarget'] = ''
112
- if 'textStyle' not in imageInfo:
113
- textStyle = options['defaultTextStyle']
114
- imageInfo['textStyle'] = options['defaultTextStyle']
115
- images[iImage] = imageInfo
116
-
117
- nImages = len(images)
118
-
101
+ for i_image,image_info in enumerate(images):
102
+ if isinstance(image_info,str):
103
+ image_info = {'filename':image_info}
104
+ if 'filename' not in image_info:
105
+ image_info['filename'] = ''
106
+ if 'imageStyle' not in image_info:
107
+ image_info['imageStyle'] = options['defaultImageStyle']
108
+ if 'title' not in image_info:
109
+ image_info['title'] = ''
110
+ if 'linkTarget' not in image_info:
111
+ image_info['linkTarget'] = ''
112
+ if 'textStyle' not in image_info:
113
+ text_style = options['defaultTextStyle']
114
+ image_info['textStyle'] = options['defaultTextStyle']
115
+ images[i_image] = image_info
116
+
117
+ n_images = len(images)
118
+
119
119
  # If we need to break this up into multiple files...
120
- if nImages > options['maxFiguresPerHtmlFile']:
121
-
120
+ if n_images > options['maxFiguresPerHtmlFile']:
121
+
122
122
  # You can't supply your own file handle in this case
123
- if options['fHtml'] != -1:
123
+ if options['f_html'] != -1:
124
124
  raise ValueError(
125
125
  "You can't supply your own file handle if we have to page the image set")
126
-
127
- figureFileStartingIndices = list(range(0,nImages,options['maxFiguresPerHtmlFile']))
128
126
 
129
- assert len(figureFileStartingIndices) > 1
130
-
127
+ figure_file_starting_indices = list(range(0,n_images,options['maxFiguresPerHtmlFile']))
128
+
129
+ assert len(figure_file_starting_indices) > 1
130
+
131
131
  # Open the meta-output file
132
- fMeta = open(filename,'w')
133
-
132
+ f_meta = open(filename,'w')
133
+
134
134
  # Write header stuff
135
- titleString = '<title>Index page</title>'
135
+ title_string = '<title>Index page</title>'
136
136
  if len(options['pageTitle']) > 0:
137
- titleString = '<title>Index page for: {}</title>'.format(options['pageTitle'])
138
- fMeta.write('<html><head>{}</head><body>\n'.format(titleString))
139
- fMeta.write(options['headerHtml'])
140
- fMeta.write('<table border = 0 cellpadding = 2>\n')
141
-
142
- for startingIndex in figureFileStartingIndices:
143
-
144
- iStart = startingIndex
145
- iEnd = startingIndex+options['maxFiguresPerHtmlFile']-1;
146
- if iEnd >= nImages:
147
- iEnd = nImages-1
148
-
149
- trailer = 'image_{:05d}_{:05d}'.format(iStart,iEnd)
150
- localFiguresHtmlFilename = path_utils.insert_before_extension(filename,trailer)
151
- fMeta.write('<tr><td>\n')
152
- fMeta.write('<p style="padding-bottom:0px;margin-bottom:0px;text-align:left;font-family:''segoe ui'',calibri,arial;font-size:100%;text-decoration:none;font-weight:bold;">')
153
- fMeta.write('<a href="{}">Figures for images {} through {}</a></p></td></tr>\n'.format(
154
- os.path.basename(localFiguresHtmlFilename),iStart,iEnd))
155
-
156
- localImages = images[iStart:iEnd+1]
157
-
158
- localOptions = options.copy();
159
- localOptions['headerHtml'] = options['subPageHeaderHtml'];
160
- localOptions['trailerHtml'] = '';
161
-
137
+ title_string = '<title>Index page for: {}</title>'.format(options['pageTitle'])
138
+ f_meta.write('<html><head>{}</head><body>\n'.format(title_string))
139
+ f_meta.write(options['headerHtml'])
140
+ f_meta.write('<table border = 0 cellpadding = 2>\n')
141
+
142
+ for starting_index in figure_file_starting_indices:
143
+
144
+ i_start = starting_index
145
+ i_end = starting_index + options['maxFiguresPerHtmlFile'] - 1
146
+ if i_end >= n_images:
147
+ i_end = n_images-1
148
+
149
+ trailer = 'image_{:05d}_{:05d}'.format(i_start,i_end)
150
+ local_figures_html_filename = path_utils.insert_before_extension(filename,trailer)
151
+ f_meta.write('<tr><td>\n')
152
+ f_meta.write('<p style="padding-bottom:0px;margin-bottom:0px;text-align:left;font-family:''segoe ui'',calibri,arial;font-size:100%;text-decoration:none;font-weight:bold;">') # noqa
153
+ f_meta.write('<a href="{}">Figures for images {} through {}</a></p></td></tr>\n'.format(
154
+ os.path.basename(local_figures_html_filename),i_start,i_end))
155
+
156
+ local_images = images[i_start:i_end+1]
157
+
158
+ local_options = options.copy()
159
+ local_options['headerHtml'] = options['subPageHeaderHtml']
160
+ local_options['trailerHtml'] = ''
161
+
162
162
  # Make a recursive call for this image set
163
- write_html_image_list(localFiguresHtmlFilename,localImages,localOptions)
164
-
163
+ write_html_image_list(local_figures_html_filename,local_images,local_options)
164
+
165
165
  # ...for each page of images
166
-
167
- fMeta.write('</table></body>\n')
168
- fMeta.write(options['trailerHtml'])
169
- fMeta.write('</html>\n')
170
- fMeta.close()
171
-
166
+
167
+ f_meta.write('</table></body>\n')
168
+ f_meta.write(options['trailerHtml'])
169
+ f_meta.write('</html>\n')
170
+ f_meta.close()
171
+
172
172
  return options
173
-
173
+
174
174
  # ...if we have to make multiple sub-pages
175
-
176
- bCleanupFile = False
177
-
178
- if options['fHtml'] == -1:
179
- bCleanupFile = True;
180
- fHtml = open(filename,'w')
175
+
176
+ b_clean_up_file = False
177
+
178
+ if options['f_html'] == -1:
179
+ b_clean_up_file = True
180
+ f_html = open(filename,'w')
181
181
  else:
182
- fHtml = options['fHtml']
183
-
184
- titleString = ''
182
+ f_html = options['f_html']
183
+
184
+ title_string = ''
185
185
  if len(options['pageTitle']) > 0:
186
- titleString = '<title>{}</title>'.format(options['pageTitle'])
187
-
188
- fHtml.write('<html>{}<body>\n'.format(titleString))
189
-
190
- fHtml.write(options['headerHtml'])
191
-
186
+ title_string = '<title>{}</title>'.format(options['pageTitle'])
187
+
188
+ f_html.write('<html>{}<body>\n'.format(title_string))
189
+
190
+ f_html.write(options['headerHtml'])
191
+
192
192
  # Write out images
193
- for iImage,image in enumerate(images):
194
-
193
+ for i_image,image in enumerate(images):
194
+
195
195
  title = image['title']
196
- imageStyle = image['imageStyle']
197
- textStyle = image['textStyle']
196
+ image_style = image['imageStyle']
197
+ text_style = image['textStyle']
198
198
  filename = image['filename']
199
- linkTarget = image['linkTarget']
200
-
199
+ link_target = image['linkTarget']
200
+
201
201
  # Remove unicode characters
202
202
  title = title.encode('ascii','ignore').decode('ascii')
203
203
  filename = filename.encode('ascii','ignore').decode('ascii')
204
-
204
+
205
205
  filename = filename.replace('\\','/')
206
- if options['urlEncodeFilenames']:
206
+ if options['urlEncodeFilenames']:
207
207
  filename = urllib.parse.quote(filename)
208
-
209
- if len(title) > 0:
210
- fHtml.write(
208
+
209
+ if len(title) > 0:
210
+ f_html.write(
211
211
  '<p style="{}">{}</p>\n'\
212
- .format(textStyle,title))
212
+ .format(text_style,title))
213
213
 
214
- linkTarget = linkTarget.replace('\\','/')
214
+ link_target = link_target.replace('\\','/')
215
215
  if options['urlEncodeLinkTargets']:
216
216
  # These are typically absolute paths, so we only want to mess with certain characters
217
- linkTarget = urllib.parse.quote(linkTarget,safe=':/')
218
-
219
- if len(linkTarget) > 0:
220
- fHtml.write('<a href="{}">'.format(linkTarget))
221
- # imageStyle.append(';border:0px;')
222
-
223
- fHtml.write('<img src="{}" style="{}">\n'.format(filename,imageStyle))
224
-
225
- if len(linkTarget) > 0:
226
- fHtml.write('</a>')
227
-
228
- if iImage != len(images)-1:
229
- fHtml.write('<br/>')
230
-
217
+ link_target = urllib.parse.quote(link_target,safe=':/')
218
+
219
+ if len(link_target) > 0:
220
+ f_html.write('<a href="{}">'.format(link_target))
221
+ # image_style.append(';border:0px;')
222
+
223
+ f_html.write('<img src="{}" style="{}">\n'.format(filename,image_style))
224
+
225
+ if len(link_target) > 0:
226
+ f_html.write('</a>')
227
+
228
+ if i_image != len(images)-1:
229
+ f_html.write('<br/>')
230
+
231
231
  # ...for each image we need to write
232
-
233
- fHtml.write(options['trailerHtml'])
234
-
235
- fHtml.write('</body></html>\n')
236
-
237
- if bCleanupFile:
238
- fHtml.close()
232
+
233
+ f_html.write(options['trailerHtml'])
234
+
235
+ f_html.write('</body></html>\n')
236
+
237
+ if b_clean_up_file:
238
+ f_html.close()
239
239
 
240
240
  # ...function
@@ -34,7 +34,7 @@ def plot_confusion_matrix(matrix,
34
34
  matrix (np.ndarray): shape [num_classes, num_classes], confusion matrix
35
35
  where rows are ground-truth classes and columns are predicted classes
36
36
  classes (list of str): class names for each row/column
37
- normalize (bool, optional): whether to perform row-wise normalization;
37
+ normalize (bool, optional): whether to perform row-wise normalization;
38
38
  by default, assumes values in the confusion matrix are percentages
39
39
  title (str, optional): figure title
40
40
  cmap (matplotlib.colors.colormap): colormap for cell backgrounds
@@ -45,11 +45,11 @@ def plot_confusion_matrix(matrix,
45
45
  fmt (str): format string for rendering numeric values
46
46
  fig (Figure): existing figure to which we should render, otherwise creates
47
47
  a new figure
48
-
49
- Returns:
48
+
49
+ Returns:
50
50
  matplotlib.figure.Figure: the figure we rendered to or created
51
51
  """
52
-
52
+
53
53
  num_classes = matrix.shape[0]
54
54
  assert matrix.shape[1] == num_classes
55
55
  assert len(classes) == num_classes
@@ -86,7 +86,7 @@ def plot_confusion_matrix(matrix,
86
86
  ax.set_ylabel('Ground-truth class')
87
87
 
88
88
  for i, j in np.ndindex(matrix.shape):
89
- v = matrix[i, j]
89
+ v = matrix[i, j]
90
90
  ax.text(j, i, fmt.format(v),
91
91
  horizontalalignment='center',
92
92
  verticalalignment='center',
@@ -97,8 +97,8 @@ def plot_confusion_matrix(matrix,
97
97
  # ...def plot_confusion_matrix(...)
98
98
 
99
99
 
100
- def plot_precision_recall_curve(precisions,
101
- recalls,
100
+ def plot_precision_recall_curve(precisions,
101
+ recalls,
102
102
  title='Precision/recall curve',
103
103
  xlim=(0.0,1.05),
104
104
  ylim=(0.0,1.05)):
@@ -115,10 +115,10 @@ def plot_precision_recall_curve(precisions,
115
115
  xlim (tuple, optional): x-axis limits as a length-2 tuple
116
116
  ylim (tuple, optional): y-axis limits as a length-2 tuple
117
117
 
118
- Returns:
118
+ Returns:
119
119
  matplotlib.figure.Figure: the (new) figure
120
120
  """
121
-
121
+
122
122
  assert len(precisions) == len(recalls)
123
123
 
124
124
  fig = matplotlib.figure.Figure(tight_layout=True)
@@ -128,15 +128,15 @@ def plot_precision_recall_curve(precisions,
128
128
 
129
129
  try:
130
130
  ax.set(x_label='Recall', y_label='Precision', title=title)
131
- ax.set(x_lim=xlim, y_lim=ylim)
132
- #
131
+ ax.set(x_lim=xlim, y_lim=ylim)
132
+ #
133
133
  except Exception:
134
134
  ax.set_xlabel('Recall')
135
135
  ax.set_ylabel('Precision')
136
136
  ax.set_title(title)
137
137
  ax.set_xlim(xlim[0],xlim[1])
138
138
  ax.set_ylim(ylim[0],ylim[1])
139
-
139
+
140
140
  return fig
141
141
 
142
142
 
@@ -144,7 +144,7 @@ def plot_stacked_bar_chart(data, series_labels=None, col_labels=None,
144
144
  x_label=None, y_label=None, log_scale=False):
145
145
  """
146
146
  Plot a stacked bar chart, for plotting e.g. species distribution across locations.
147
-
147
+
148
148
  Reference: https://stackoverflow.com/q/44309507
149
149
 
150
150
  Args:
@@ -156,10 +156,10 @@ def plot_stacked_bar_chart(data, series_labels=None, col_labels=None,
156
156
  y_label (str, optional): y-axis label
157
157
  log_scale (bool, optional) whether to plot the y axis in log-scale
158
158
 
159
- Returns:
159
+ Returns:
160
160
  matplotlib.figure.Figure: the (new) figure
161
161
  """
162
-
162
+
163
163
  data = np.asarray(data)
164
164
  num_series, num_columns = data.shape
165
165
  ind = np.arange(num_columns)
@@ -206,24 +206,24 @@ def calibration_ece(true_scores, pred_scores, num_bins):
206
206
 
207
207
  Implementation modified from sklearn.calibration.calibration_curve()
208
208
  in order to implement ECE calculation. See:
209
-
209
+
210
210
  https://github.com/scikit-learn/scikit-learn/issues/18268
211
211
 
212
212
  Args:
213
213
  true_scores (list of int): true values, length N, binary-valued (0 = neg, 1 = pos)
214
- pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
214
+ pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
215
215
  predicted confidence that example i is positive
216
216
  num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
217
217
 
218
218
  Returns:
219
219
  tuple: a length-three tuple containing:
220
220
  - accs: np.ndarray, shape [M], type float64, accuracy in each bin,
221
- M <= num_bins because bins with no samples are not returned
221
+ M <= num_bins because bins with no samples are not returned
222
222
  - confs: np.ndarray, shape [M], type float64, mean model confidence in
223
223
  each bin
224
224
  - ece: float, expected calibration error
225
225
  """
226
-
226
+
227
227
  assert len(true_scores) == len(pred_scores)
228
228
 
229
229
  bins = np.linspace(0., 1. + 1e-8, num=num_bins + 1)
@@ -250,7 +250,7 @@ def plot_calibration_curve(true_scores, pred_scores, num_bins,
250
250
 
251
251
  Args:
252
252
  true_scores (list of int): true values, length N, binary-valued (0 = neg, 1 = pos)
253
- pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
253
+ pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
254
254
  predicted confidence that example i is positive
255
255
  num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
256
256
  name (str, optional): label in legend for the calibration curve
@@ -262,7 +262,7 @@ def plot_calibration_curve(true_scores, pred_scores, num_bins,
262
262
  Returns:
263
263
  matplotlib.figure.Figure: the (new) figure
264
264
  """
265
-
265
+
266
266
  accs, confs, ece = calibration_ece(true_scores, pred_scores, num_bins)
267
267
 
268
268
  created_fig = False