fimeval 0.1.55__py3-none-any.whl → 0.1.56__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.
@@ -8,6 +8,7 @@ from plotly.subplots import make_subplots
8
8
  import plotly.graph_objects as go
9
9
  import seaborn as sns
10
10
  import matplotlib.pyplot as plt
11
+ import matplotlib.gridspec as gridspec
11
12
 
12
13
 
13
14
  def Changeintogpkg(input_path, output_dir, layer_name):
@@ -21,8 +22,8 @@ def Changeintogpkg(input_path, output_dir, layer_name):
21
22
  output_gpkg = os.path.join(output_dir, f"{layer_name}.gpkg")
22
23
  gdf.to_file(output_gpkg, driver="GPKG")
23
24
  return output_gpkg
24
-
25
-
25
+
26
+
26
27
  def GetFloodedBuildingCountInfo(
27
28
  building_fp_path,
28
29
  study_area_path,
@@ -76,8 +77,12 @@ def GetFloodedBuildingCountInfo(
76
77
 
77
78
  count_centroids_in_contingency(contingency_map)
78
79
 
79
- centroid_counts["Candidate"] = centroid_counts["True Positive"] + centroid_counts["False Positive"]
80
- centroid_counts["Benchmark"] = centroid_counts["True Positive"] + centroid_counts["False Negative"]
80
+ centroid_counts["Candidate"] = (
81
+ centroid_counts["True Positive"] + centroid_counts["False Positive"]
82
+ )
83
+ centroid_counts["Benchmark"] = (
84
+ centroid_counts["True Positive"] + centroid_counts["False Negative"]
85
+ )
81
86
 
82
87
  total_buildings = len(clipped_buildings)
83
88
  percentages = {
@@ -93,7 +98,9 @@ def GetFloodedBuildingCountInfo(
93
98
  FAR = FP / (TP + FP) if (TP + FP) > 0 else 0
94
99
  POD = TP / (TP + FN) if (TP + FN) > 0 else 0
95
100
  if centroid_counts["Benchmark"] > 0:
96
- BDR = (centroid_counts["Candidate"] - centroid_counts["Benchmark"]) / centroid_counts["Benchmark"]
101
+ BDR = (
102
+ centroid_counts["Candidate"] - centroid_counts["Benchmark"]
103
+ ) / centroid_counts["Benchmark"]
97
104
  else:
98
105
  BDR = 0
99
106
 
@@ -122,7 +129,9 @@ def GetFloodedBuildingCountInfo(
122
129
  ],
123
130
  }
124
131
  counts_df = pd.DataFrame(counts_data)
125
- csv_file_path = os.path.join(save_dir, "EvaluationMetrics", f"BuildingCounts_{basename}.csv")
132
+ csv_file_path = os.path.join(
133
+ save_dir, "EvaluationMetrics", f"BuildingCounts_{basename}.csv"
134
+ )
126
135
  os.makedirs(os.path.dirname(csv_file_path), exist_ok=True)
127
136
  counts_df.to_csv(csv_file_path, index=False)
128
137
 
@@ -135,98 +144,146 @@ def GetFloodedBuildingCountInfo(
135
144
  ]
136
145
 
137
146
  fig = make_subplots(
138
- rows=1, cols=2,
139
- subplot_titles=("Building Counts on Different FIMs", "Contingency Flooded Building Counts"),
147
+ rows=1,
148
+ cols=2,
149
+ subplot_titles=(
150
+ "Building Counts on Different FIMs",
151
+ "Contingency Flooded Building Counts",
152
+ ),
140
153
  )
141
154
 
142
155
  fig.add_trace(
143
156
  go.Bar(
144
- x=["Candidate"], y=[centroid_counts["Candidate"]],
145
- text=[f"{centroid_counts['Candidate']}"], textposition="auto",
146
- marker_color="#1c83eb", marker_line_color="black", marker_line_width=1,
157
+ x=["Candidate"],
158
+ y=[centroid_counts["Candidate"]],
159
+ text=[f"{centroid_counts['Candidate']}"],
160
+ textposition="auto",
161
+ marker_color="#1c83eb",
162
+ marker_line_color="black",
163
+ marker_line_width=1,
147
164
  name=f"Candidate ({percentages['Candidate']:.2f}%)",
148
165
  ),
149
- row=1, col=1,
166
+ row=1,
167
+ col=1,
150
168
  )
151
169
  fig.add_trace(
152
170
  go.Bar(
153
- x=["Benchmark"], y=[centroid_counts["Benchmark"]],
154
- text=[f"{centroid_counts['Benchmark']}"], textposition="auto",
155
- marker_color="#a4490e", marker_line_color="black", marker_line_width=1,
171
+ x=["Benchmark"],
172
+ y=[centroid_counts["Benchmark"]],
173
+ text=[f"{centroid_counts['Benchmark']}"],
174
+ textposition="auto",
175
+ marker_color="#a4490e",
176
+ marker_line_color="black",
177
+ marker_line_width=1,
156
178
  name=f"Benchmark ({percentages['Benchmark']:.2f}%)",
157
179
  ),
158
- row=1, col=1,
180
+ row=1,
181
+ col=1,
159
182
  )
160
183
 
161
184
  for i, label in enumerate(third_raster_labels):
162
185
  fig.add_trace(
163
186
  go.Bar(
164
- x=[label], y=[third_raster_counts[i]],
165
- text=[f"{third_raster_counts[i]}"], textposition="auto",
187
+ x=[label],
188
+ y=[third_raster_counts[i]],
189
+ text=[f"{third_raster_counts[i]}"],
190
+ textposition="auto",
166
191
  marker_color=["#ff5733", "#ffc300", "#28a745"][i],
167
- marker_line_color="black", marker_line_width=1,
192
+ marker_line_color="black",
193
+ marker_line_width=1,
168
194
  name=f"{label} ({percentages[label]:.2f}%)",
169
195
  ),
170
- row=1, col=2,
196
+ row=1,
197
+ col=2,
171
198
  )
172
199
 
173
200
  fig.update_layout(
174
201
  title="Flooded Building Counts",
175
202
  xaxis_title="Inundation Surface",
176
203
  yaxis_title="Flooded Building Counts",
177
- width=1100, height=400,
178
- plot_bgcolor="rgba(0,0,0,0)", paper_bgcolor="rgba(0,0,0,0)",
179
- showlegend=True, font=dict(family="Arial", size=18, color="black"),
204
+ width=1100,
205
+ height=400,
206
+ plot_bgcolor="rgba(0,0,0,0)",
207
+ paper_bgcolor="rgba(0,0,0,0)",
208
+ showlegend=True,
209
+ font=dict(family="Arial", size=18, color="black"),
180
210
  )
181
211
  fig.show()
182
212
 
183
- # Seaborn for static PNG saving only
184
- df_left = pd.DataFrame({
185
- "Category": ["Candidate", "Benchmark"],
186
- "Count": [centroid_counts["Candidate"], centroid_counts["Benchmark"]],
187
- })
188
- df_right = pd.DataFrame({
189
- "Category": third_raster_labels,
190
- "Count": third_raster_counts,
191
- })
213
+ # Seaborn for static PNG
214
+ df_left = pd.DataFrame(
215
+ {
216
+ "Category": ["Candidate", "Benchmark"],
217
+ "Count": [centroid_counts["Candidate"], centroid_counts["Benchmark"]],
218
+ }
219
+ )
220
+ df_right = pd.DataFrame(
221
+ {
222
+ "Category": third_raster_labels,
223
+ "Count": third_raster_counts,
224
+ }
225
+ )
192
226
 
193
227
  sns.set_theme(style="whitegrid")
194
- fig_sb, axes = plt.subplots(1, 2, figsize=(8, 3), constrained_layout=True)
228
+
229
+ fig_sb = plt.figure(figsize=(10, 3), constrained_layout=True)
230
+ gs = gridspec.GridSpec(1, 3, figure=fig_sb, width_ratios=[1, 1, 0.4])
231
+
232
+ ax0 = fig_sb.add_subplot(gs[0, 0])
233
+ ax1 = fig_sb.add_subplot(gs[0, 1])
234
+ ax_leg = fig_sb.add_subplot(gs[0, 2])
235
+ ax_leg.axis("off")
195
236
 
196
237
  def style_axes(ax, title_text, xlab, show_ylabel: bool):
197
- # Adding a bit of padding so bar labels don’t overlap with the title
198
- ax.set_title(title_text, fontsize=16, pad=20)
199
- ax.set_xlabel(xlab, fontsize=14, color="black")
238
+ ax.set_title(title_text, fontsize=14, pad=15)
239
+ ax.set_xlabel(xlab, fontsize=13, color="black")
200
240
  if show_ylabel:
201
- ax.set_ylabel("Flooded Building Counts", fontsize=14, color="black")
241
+ ax.set_ylabel("Flooded Building Counts", fontsize=13, color="black")
202
242
  else:
203
243
  ax.set_ylabel("")
204
244
 
205
- # Thicker black left/bottom spines
206
245
  for spine in ("left", "bottom"):
207
246
  ax.spines[spine].set_linewidth(1.5)
208
247
  ax.spines[spine].set_color("black")
209
248
 
210
249
  sns.despine(ax=ax, right=True, top=True)
211
- ax.tick_params(axis="x", labelsize=12, colors="black")
212
- ax.tick_params(axis="y", labelsize=12, colors="black")
250
+ ax.tick_params(axis="x", labelsize=11, colors="black")
251
+ ax.tick_params(axis="y", labelsize=11, colors="black")
213
252
 
214
253
  # Left panel
215
- ax0 = axes[0]
216
- sns.barplot(data=df_left, x="Category", y="Count", ax=ax0,
217
- palette=["#1c83eb", "#a4490e"])
218
- style_axes(ax0, "Building Counts on Different FIMs", "Inundation Surface", show_ylabel=True)
254
+ colors_left = ["#1c83eb", "#a4490e"]
255
+ sns.barplot(data=df_left, x="Category", y="Count", ax=ax0, palette=colors_left)
256
+ style_axes(ax0, "Building Counts on Different FIMs", "Inundation Surface", True)
219
257
  for c in ax0.containers:
220
- ax0.bar_label(c, fmt="%.0f", label_type="edge", padding=3, fontsize=14, color="black")
258
+ ax0.bar_label(
259
+ c, fmt="%.0f", label_type="edge", padding=3, fontsize=12, color="black"
260
+ )
221
261
 
222
262
  # Right panel
223
- ax1 = axes[1]
224
- sns.barplot(data=df_right, x="Category", y="Count", ax=ax1,
225
- palette=["#ff5733", "#ffc300", "#28a745"])
226
- style_axes(ax1, "Contingency Flooded Building Counts", "Category", show_ylabel=False)
263
+ colors_right = ["#ff5733", "#ffc300", "#28a745"]
264
+ sns.barplot(data=df_right, x="Category", y="Count", ax=ax1, palette=colors_right)
265
+ style_axes(ax1, "Contingency Flooded Building Counts", "Category", False)
227
266
  for c in ax1.containers:
228
- ax1.bar_label(c, fmt="%.0f", label_type="edge", padding=3, fontsize=14, color="black")
267
+ ax1.bar_label(
268
+ c, fmt="%.0f", label_type="edge", padding=3, fontsize=12, color="black"
269
+ )
229
270
 
271
+ # Combined legend
272
+ all_labels = ["Candidate", "Benchmark"] + third_raster_labels
273
+ all_colors = colors_left + colors_right
274
+ legend_handles = [
275
+ plt.Line2D(
276
+ [0],
277
+ [0],
278
+ marker="s",
279
+ color="w",
280
+ markerfacecolor=all_colors[i],
281
+ markersize=12,
282
+ label=f"{all_labels[i]} ({percentages[all_labels[i]]:.2f}%)",
283
+ )
284
+ for i in range(len(all_labels))
285
+ ]
286
+ ax_leg.legend(handles=legend_handles, fontsize=12, loc="center left", frameon=True)
230
287
  plot_dir = os.path.join(save_dir, "FinalPlots")
231
288
  os.makedirs(plot_dir, exist_ok=True)
232
289
  output_path = os.path.join(plot_dir, f"BuildingCounts_{basename}.png")
@@ -236,8 +293,6 @@ def GetFloodedBuildingCountInfo(
236
293
  print(f"PNG were saved in : {output_path}")
237
294
 
238
295
 
239
-
240
-
241
296
  def process_TIFF(
242
297
  tif_files, contingency_files, building_footprint, boundary, method_path
243
298
  ):
@@ -277,7 +277,8 @@ def evaluateFIM(
277
277
  out_transform1,
278
278
  )
279
279
  merged = out_image1 + out_image2_resized
280
-
280
+ merged[merged==7] = 5
281
+
281
282
  # Get Evaluation Metrics
282
283
  (
283
284
  unique_values,
@@ -12,19 +12,21 @@ def PlotMetrics(csv_path, method_path):
12
12
 
13
13
  # Keep only the desired metrics
14
14
  metrics = metrics_df.loc[
15
- metrics_df["Metrics"].isin([
16
- "CSI_values", "POD_values", "Acc_values", "Prec_values", "F1_values"
17
- ])
15
+ metrics_df["Metrics"].isin(
16
+ ["CSI_values", "POD_values", "Acc_values", "Prec_values", "F1_values"]
17
+ )
18
18
  ].copy()
19
19
 
20
20
  # Rename for presentation
21
- metrics["Metrics"] = metrics["Metrics"].replace({
22
- "CSI_values": "CSI",
23
- "POD_values": "POD",
24
- "Acc_values": "Accuracy",
25
- "Prec_values": "Precision",
26
- "F1_values": "F1 Score",
27
- })
21
+ metrics["Metrics"] = metrics["Metrics"].replace(
22
+ {
23
+ "CSI_values": "CSI",
24
+ "POD_values": "POD",
25
+ "Acc_values": "Accuracy",
26
+ "Prec_values": "Precision",
27
+ "F1_values": "F1 Score",
28
+ }
29
+ )
28
30
 
29
31
  value_columns = metrics.select_dtypes(include="number").columns
30
32
 
@@ -44,7 +46,7 @@ def PlotMetrics(csv_path, method_path):
44
46
  color="Metrics",
45
47
  orientation="h",
46
48
  color_discrete_sequence=px.colors.qualitative.Set2,
47
- title=f"Performance Metrics"
49
+ title=f"Performance Metrics",
48
50
  )
49
51
  fig_plotly.update_traces(texttemplate="%{text:.2f}", textposition="outside")
50
52
  fig_plotly.update_layout(
@@ -67,34 +69,36 @@ def PlotMetrics(csv_path, method_path):
67
69
  data=metrics,
68
70
  x=value_column,
69
71
  y="Metrics",
70
- hue="Metrics",
72
+ hue="Metrics",
71
73
  palette="Set2",
72
74
  ax=ax,
73
75
  dodge=False,
74
- legend=False
76
+ legend=False,
75
77
  )
76
78
 
77
79
  # Annotate bars
78
80
  for container in ax.containers:
79
- ax.bar_label(container, fmt='%.2f', label_type='edge', fontsize=14)
81
+ ax.bar_label(container, fmt="%.2f", label_type="edge", fontsize=14)
80
82
 
81
83
  # Styling
82
84
  ax.set_title("Performance Metrics", fontsize=16)
83
- ax.set_xlabel("Score", fontsize=16, color="black") # just bigger, not bold
85
+ ax.set_xlabel("Score", fontsize=16, color="black") # just bigger, not bold
84
86
  ax.set_ylabel("Metrics", fontsize=16, color="black")
85
87
 
86
- ax.set_xticks([i/10 for i in range(0, 11, 2)])
87
- ax.set_xticklabels([f"{i/10:.1f}" for i in range(0, 11, 2)], fontsize=14, color="black")
88
+ ax.set_xticks([i / 10 for i in range(0, 11, 2)])
89
+ ax.set_xticklabels(
90
+ [f"{i/10:.1f}" for i in range(0, 11, 2)], fontsize=14, color="black"
91
+ )
88
92
 
89
93
  # Increase y-tick label font size
90
94
  ax.tick_params(axis="y", labelsize=12, colors="black")
91
95
  ax.tick_params(axis="x", labelsize=14, colors="black")
92
96
 
93
97
  # Force spines black + thicker
94
- ax.spines['left'].set_linewidth(1.5)
95
- ax.spines['bottom'].set_linewidth(1.5)
96
- ax.spines['left'].set_color("black")
97
- ax.spines['bottom'].set_color("black")
98
+ ax.spines["left"].set_linewidth(1.5)
99
+ ax.spines["bottom"].set_linewidth(1.5)
100
+ ax.spines["left"].set_color("black")
101
+ ax.spines["bottom"].set_color("black")
98
102
 
99
103
  sns.despine(right=True, top=True)
100
104
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fimeval
3
- Version: 0.1.55
3
+ Version: 0.1.56
4
4
  Summary: A Framework for Automatic Evaluation of Flood Inundation Mapping Predictions Evaluation
5
5
  Author: Surface Dynamics Modeling Lab
6
6
  Author-email: Supath Dhital <sdhital@crimson.ua.edu>, Dipshika Devi <ddevi@ua.edu>
@@ -1,17 +1,17 @@
1
1
  fimeval/__init__.py,sha256=HZJKq7XEhL6TnwFkhpf8NcEQ5h7zPQ3XJh3z5gF0gQ8,603
2
2
  fimeval/utilis.py,sha256=KdU6pSMS8dPf1zFyS-SOUdDSJr87IQ28uSG3ZuVfq1A,6782
3
3
  fimeval/BuildingFootprint/__init__.py,sha256=oP9YWLdo6ANzSQFxYLv7Ku_26AY5NkLNhZLK28ICMLo,109
4
- fimeval/BuildingFootprint/evaluationwithBF.py,sha256=84s6y-S3GAuclgAEXQ4DmBAtnnZ3t0LFhIPjeSMtzPw,17224
4
+ fimeval/BuildingFootprint/evaluationwithBF.py,sha256=3v5dZk7xL9h6emf36Cxlsq5DJ1mYA5FgWpX4i97VPFg,18238
5
5
  fimeval/BuildingFootprint/microsoftBF.py,sha256=73M_e_n_3lsejsnP9eX06hou0sr2-yaWdjuoUwZ8O2Y,4063
6
6
  fimeval/ContingencyMap/PWBs3.py,sha256=UFICxO58c2fA9mIffH4ooqphv3ZXe6yX8QzpRjtI6fs,1275
7
7
  fimeval/ContingencyMap/__init__.py,sha256=ckps2dyg6aci3TA-3P7oTMcCAcSTz9AA6sndHtZEwdE,259
8
- fimeval/ContingencyMap/evaluationFIM.py,sha256=MTh9W5M-g43uzgW8ci0GJ65KKCEsepbqiE8o8Ox0Pj4,17270
8
+ fimeval/ContingencyMap/evaluationFIM.py,sha256=zdr55Vc0FzmI4p-8xlWmm92agGdimpWPCVzcCtu4qzU,17349
9
9
  fimeval/ContingencyMap/methods.py,sha256=kbutfo9FUH-yjvnOXxwLpdErUuebMJ8NjCroNWIYCjo,3299
10
10
  fimeval/ContingencyMap/metrics.py,sha256=jwOia0Nl7aU7AuGJFAcQ4fVENnp2G_5W6JSJBzo1-_4,1094
11
- fimeval/ContingencyMap/plotevaluationmetrics.py,sha256=CLw3y3XB3XhGm_X2_U3JSlPq0DYKxATNSW7lKPvMkMA,4838
11
+ fimeval/ContingencyMap/plotevaluationmetrics.py,sha256=AbR43fnz0mbs5a7o3-ccAj-fa5RRWG4rS3xav58_M-k,4900
12
12
  fimeval/ContingencyMap/printcontingency.py,sha256=-1H_Ze2TbRSER7vy7bd0HvxnziNzPPOIPOm2YhB7r4A,5422
13
- fimeval-0.1.55.dist-info/licenses/LICENSE.txt,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
14
- fimeval-0.1.55.dist-info/METADATA,sha256=A_OiFx3NhXA_t9P0mW3qYGFchKw6UlGKuOwXFv7YzYk,56113
15
- fimeval-0.1.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- fimeval-0.1.55.dist-info/top_level.txt,sha256=F4QW50msI8sRrX_DK3NQ-s3swQ4-2_5Ty3mfm9ZMc6k,8
17
- fimeval-0.1.55.dist-info/RECORD,,
13
+ fimeval-0.1.56.dist-info/licenses/LICENSE.txt,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
14
+ fimeval-0.1.56.dist-info/METADATA,sha256=2u8hha99stJgzPpGzrU6A4rbgYmD2DRT2lmEuRWchas,56113
15
+ fimeval-0.1.56.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ fimeval-0.1.56.dist-info/top_level.txt,sha256=F4QW50msI8sRrX_DK3NQ-s3swQ4-2_5Ty3mfm9ZMc6k,8
17
+ fimeval-0.1.56.dist-info/RECORD,,