megadetector 5.0.28__py3-none-any.whl → 10.0.0__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 (197) hide show
  1. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  2. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  3. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  4. megadetector/classification/aggregate_classifier_probs.py +3 -3
  5. megadetector/classification/analyze_failed_images.py +5 -5
  6. megadetector/classification/cache_batchapi_outputs.py +5 -5
  7. megadetector/classification/create_classification_dataset.py +11 -12
  8. megadetector/classification/crop_detections.py +10 -10
  9. megadetector/classification/csv_to_json.py +8 -8
  10. megadetector/classification/detect_and_crop.py +13 -15
  11. megadetector/classification/efficientnet/model.py +8 -8
  12. megadetector/classification/efficientnet/utils.py +6 -5
  13. megadetector/classification/evaluate_model.py +7 -7
  14. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  15. megadetector/classification/json_to_azcopy_list.py +1 -1
  16. megadetector/classification/json_validator.py +29 -32
  17. megadetector/classification/map_classification_categories.py +9 -9
  18. megadetector/classification/merge_classification_detection_output.py +12 -9
  19. megadetector/classification/prepare_classification_script.py +19 -19
  20. megadetector/classification/prepare_classification_script_mc.py +26 -26
  21. megadetector/classification/run_classifier.py +4 -4
  22. megadetector/classification/save_mislabeled.py +6 -6
  23. megadetector/classification/train_classifier.py +1 -1
  24. megadetector/classification/train_classifier_tf.py +9 -9
  25. megadetector/classification/train_utils.py +10 -10
  26. megadetector/data_management/annotations/annotation_constants.py +1 -2
  27. megadetector/data_management/camtrap_dp_to_coco.py +79 -46
  28. megadetector/data_management/cct_json_utils.py +103 -103
  29. megadetector/data_management/cct_to_md.py +49 -49
  30. megadetector/data_management/cct_to_wi.py +33 -33
  31. megadetector/data_management/coco_to_labelme.py +75 -75
  32. megadetector/data_management/coco_to_yolo.py +210 -193
  33. megadetector/data_management/databases/add_width_and_height_to_db.py +86 -12
  34. megadetector/data_management/databases/combine_coco_camera_traps_files.py +40 -40
  35. megadetector/data_management/databases/integrity_check_json_db.py +228 -200
  36. megadetector/data_management/databases/subset_json_db.py +33 -33
  37. megadetector/data_management/generate_crops_from_cct.py +88 -39
  38. megadetector/data_management/get_image_sizes.py +54 -49
  39. megadetector/data_management/labelme_to_coco.py +133 -125
  40. megadetector/data_management/labelme_to_yolo.py +159 -73
  41. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  42. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  43. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  44. megadetector/data_management/lila/download_lila_subset.py +21 -24
  45. megadetector/data_management/lila/generate_lila_per_image_labels.py +365 -107
  46. megadetector/data_management/lila/get_lila_annotation_counts.py +35 -33
  47. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  48. megadetector/data_management/lila/lila_common.py +73 -70
  49. megadetector/data_management/lila/test_lila_metadata_urls.py +28 -19
  50. megadetector/data_management/mewc_to_md.py +344 -340
  51. megadetector/data_management/ocr_tools.py +262 -255
  52. megadetector/data_management/read_exif.py +249 -227
  53. megadetector/data_management/remap_coco_categories.py +90 -28
  54. megadetector/data_management/remove_exif.py +81 -21
  55. megadetector/data_management/rename_images.py +187 -187
  56. megadetector/data_management/resize_coco_dataset.py +588 -120
  57. megadetector/data_management/speciesnet_to_md.py +41 -41
  58. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  59. megadetector/data_management/yolo_output_to_md_output.py +248 -122
  60. megadetector/data_management/yolo_to_coco.py +333 -191
  61. megadetector/detection/change_detection.py +832 -0
  62. megadetector/detection/process_video.py +340 -337
  63. megadetector/detection/pytorch_detector.py +358 -278
  64. megadetector/detection/run_detector.py +399 -186
  65. megadetector/detection/run_detector_batch.py +404 -377
  66. megadetector/detection/run_inference_with_yolov5_val.py +340 -327
  67. megadetector/detection/run_tiled_inference.py +257 -249
  68. megadetector/detection/tf_detector.py +24 -24
  69. megadetector/detection/video_utils.py +332 -295
  70. megadetector/postprocessing/add_max_conf.py +19 -11
  71. megadetector/postprocessing/categorize_detections_by_size.py +45 -45
  72. megadetector/postprocessing/classification_postprocessing.py +468 -433
  73. megadetector/postprocessing/combine_batch_outputs.py +23 -23
  74. megadetector/postprocessing/compare_batch_results.py +590 -525
  75. megadetector/postprocessing/convert_output_format.py +106 -102
  76. megadetector/postprocessing/create_crop_folder.py +347 -147
  77. megadetector/postprocessing/detector_calibration.py +173 -168
  78. megadetector/postprocessing/generate_csv_report.py +508 -499
  79. megadetector/postprocessing/load_api_results.py +48 -27
  80. megadetector/postprocessing/md_to_coco.py +133 -102
  81. megadetector/postprocessing/md_to_labelme.py +107 -90
  82. megadetector/postprocessing/md_to_wi.py +40 -40
  83. megadetector/postprocessing/merge_detections.py +92 -114
  84. megadetector/postprocessing/postprocess_batch_results.py +319 -301
  85. megadetector/postprocessing/remap_detection_categories.py +91 -38
  86. megadetector/postprocessing/render_detection_confusion_matrix.py +214 -205
  87. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  88. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  89. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +704 -679
  90. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  91. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  92. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  93. megadetector/postprocessing/validate_batch_results.py +70 -70
  94. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  95. megadetector/taxonomy_mapping/map_new_lila_datasets.py +18 -19
  96. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +54 -33
  97. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +67 -67
  98. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  99. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  100. megadetector/taxonomy_mapping/species_lookup.py +156 -74
  101. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  102. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  103. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  104. megadetector/utils/ct_utils.py +1049 -211
  105. megadetector/utils/directory_listing.py +21 -77
  106. megadetector/utils/gpu_test.py +22 -22
  107. megadetector/utils/md_tests.py +632 -529
  108. megadetector/utils/path_utils.py +1520 -431
  109. megadetector/utils/process_utils.py +41 -41
  110. megadetector/utils/split_locations_into_train_val.py +62 -62
  111. megadetector/utils/string_utils.py +148 -27
  112. megadetector/utils/url_utils.py +489 -176
  113. megadetector/utils/wi_utils.py +2658 -2526
  114. megadetector/utils/write_html_image_list.py +137 -137
  115. megadetector/visualization/plot_utils.py +34 -30
  116. megadetector/visualization/render_images_with_thumbnails.py +39 -74
  117. megadetector/visualization/visualization_utils.py +487 -435
  118. megadetector/visualization/visualize_db.py +232 -198
  119. megadetector/visualization/visualize_detector_output.py +82 -76
  120. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/METADATA +5 -2
  121. megadetector-10.0.0.dist-info/RECORD +139 -0
  122. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/WHEEL +1 -1
  123. megadetector/api/batch_processing/api_core/__init__.py +0 -0
  124. megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
  125. megadetector/api/batch_processing/api_core/batch_service/score.py +0 -439
  126. megadetector/api/batch_processing/api_core/server.py +0 -294
  127. megadetector/api/batch_processing/api_core/server_api_config.py +0 -97
  128. megadetector/api/batch_processing/api_core/server_app_config.py +0 -55
  129. megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -220
  130. megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -149
  131. megadetector/api/batch_processing/api_core/server_orchestration.py +0 -360
  132. megadetector/api/batch_processing/api_core/server_utils.py +0 -88
  133. megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
  134. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
  135. megadetector/api/batch_processing/api_support/__init__.py +0 -0
  136. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +0 -152
  137. megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
  138. megadetector/api/synchronous/__init__.py +0 -0
  139. megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  140. megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -151
  141. megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -263
  142. megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -35
  143. megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
  144. megadetector/api/synchronous/api_core/tests/load_test.py +0 -110
  145. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  146. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  147. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  148. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  149. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  150. megadetector/data_management/importers/awc_to_json.py +0 -191
  151. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  152. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  153. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  154. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  155. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  156. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  157. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  158. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  159. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  160. megadetector/data_management/importers/ena24_to_json.py +0 -276
  161. megadetector/data_management/importers/filenames_to_json.py +0 -386
  162. megadetector/data_management/importers/helena_to_cct.py +0 -283
  163. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  164. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  165. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  166. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  167. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  168. megadetector/data_management/importers/missouri_to_json.py +0 -490
  169. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  170. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  171. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  172. megadetector/data_management/importers/pc_to_json.py +0 -365
  173. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  174. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  175. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  176. megadetector/data_management/importers/rspb_to_json.py +0 -356
  177. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  178. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  179. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  180. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  181. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  182. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  183. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  184. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  185. megadetector/data_management/importers/ubc_to_json.py +0 -399
  186. megadetector/data_management/importers/umn_to_json.py +0 -507
  187. megadetector/data_management/importers/wellington_to_json.py +0 -263
  188. megadetector/data_management/importers/wi_to_json.py +0 -442
  189. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  190. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  191. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  192. megadetector/utils/azure_utils.py +0 -178
  193. megadetector/utils/sas_blob_utils.py +0 -509
  194. megadetector-5.0.28.dist-info/RECORD +0 -209
  195. /megadetector/{api/batch_processing/__init__.py → __init__.py} +0 -0
  196. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/licenses/LICENSE +0 -0
  197. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/top_level.txt +0 -0
@@ -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,22 +34,22 @@ 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
- cmap (matplotlib.colors.colormap): colormap for cell backgrounds
41
- vmax (float, optional), value corresponding to the largest value of the colormap;
40
+ cmap (matplotlib.colors.colormap, optional): colormap for cell backgrounds
41
+ vmax (float, optional): value corresponding to the largest value of the colormap;
42
42
  if None, the maximum value in [matrix] will be used
43
43
  use_colorbar (bool, optional): whether to show colorbar
44
44
  y_label (bool, optional): whether to show class names on the y axis
45
- fmt (str): format string for rendering numeric values
46
- fig (Figure): existing figure to which we should render, otherwise creates
47
- a new figure
48
-
49
- Returns:
45
+ fmt (str, optional): format string for rendering numeric values
46
+ fig (Figure, optional): existing figure to which we should render, otherwise
47
+ creates a new figure
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,23 +128,27 @@ 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
 
143
- def plot_stacked_bar_chart(data, series_labels=None, col_labels=None,
144
- x_label=None, y_label=None, log_scale=False):
143
+ def plot_stacked_bar_chart(data,
144
+ series_labels=None,
145
+ col_labels=None,
146
+ x_label=None,
147
+ y_label=None,
148
+ log_scale=False):
145
149
  """
146
150
  Plot a stacked bar chart, for plotting e.g. species distribution across locations.
147
-
151
+
148
152
  Reference: https://stackoverflow.com/q/44309507
149
153
 
150
154
  Args:
@@ -154,12 +158,12 @@ def plot_stacked_bar_chart(data, series_labels=None, col_labels=None,
154
158
  col_labels (list of str, optional): column labels, typically location names
155
159
  x_label (str, optional): x-axis label
156
160
  y_label (str, optional): y-axis label
157
- log_scale (bool, optional) whether to plot the y axis in log-scale
161
+ log_scale (bool, optional): whether to plot the y axis in log-scale
158
162
 
159
- Returns:
163
+ Returns:
160
164
  matplotlib.figure.Figure: the (new) figure
161
165
  """
162
-
166
+
163
167
  data = np.asarray(data)
164
168
  num_series, num_columns = data.shape
165
169
  ind = np.arange(num_columns)
@@ -206,24 +210,24 @@ def calibration_ece(true_scores, pred_scores, num_bins):
206
210
 
207
211
  Implementation modified from sklearn.calibration.calibration_curve()
208
212
  in order to implement ECE calculation. See:
209
-
213
+
210
214
  https://github.com/scikit-learn/scikit-learn/issues/18268
211
215
 
212
216
  Args:
213
217
  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
218
+ pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
215
219
  predicted confidence that example i is positive
216
220
  num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
217
221
 
218
222
  Returns:
219
223
  tuple: a length-three tuple containing:
220
224
  - accs: np.ndarray, shape [M], type float64, accuracy in each bin,
221
- M <= num_bins because bins with no samples are not returned
225
+ M <= num_bins because bins with no samples are not returned
222
226
  - confs: np.ndarray, shape [M], type float64, mean model confidence in
223
227
  each bin
224
228
  - ece: float, expected calibration error
225
229
  """
226
-
230
+
227
231
  assert len(true_scores) == len(pred_scores)
228
232
 
229
233
  bins = np.linspace(0., 1. + 1e-8, num=num_bins + 1)
@@ -250,19 +254,19 @@ def plot_calibration_curve(true_scores, pred_scores, num_bins,
250
254
 
251
255
  Args:
252
256
  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
257
+ pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
254
258
  predicted confidence that example i is positive
255
259
  num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
256
260
  name (str, optional): label in legend for the calibration curve
257
261
  plot_perf (bool, optional): whether to plot y=x line indicating perfect calibration
258
262
  plot_hist (bool, optional): whether to plot histogram of counts
259
263
  ax (Axes, optional): if given then no legend is drawn, and fig_kwargs are ignored
260
- fig_kwargs (dict, optional): only used if [ax] is None
264
+ fig_kwargs (dict): only used if [ax] is None
261
265
 
262
266
  Returns:
263
267
  matplotlib.figure.Figure: the (new) figure
264
268
  """
265
-
269
+
266
270
  accs, confs, ece = calibration_ece(true_scores, pred_scores, num_bins)
267
271
 
268
272
  created_fig = False