chrisli124 commited on
Commit
6570159
·
verified ·
1 Parent(s): fbf75f6

Upload 20 files

Browse files
IWI_by_admin2.geojson ADDED
The diff for this file is too large to render. See raw diff
 
app.cpython-311.pyc ADDED
Binary file (21.5 kB). View file
 
app.py CHANGED
@@ -1,98 +1,557 @@
1
- from shiny import App, ui, render, reactive
2
- from shinywidgets import render_widget
3
- from ipyleaflet import Map, TileLayer, GeoJSON, LayersControl
4
  import pandas as pd
5
  import numpy as np
6
- import plotly.express as px
7
- import plotly.graph_objects as go
8
- from plotly.subplots import make_subplots
9
  import matplotlib.pyplot as plt
10
- from ipywidgets import Output
11
  import rasterio
 
 
 
 
 
 
 
 
 
 
12
  import json
 
 
 
13
 
14
- # ---- 1. Load Data ----
15
- # Example file paths (replace with actual paths or S3 calls)
16
- wealth_tif_path = "data/wealth_map.tif"
17
- improvement_csv_path = "data/poverty_improvement_by_state.csv"
18
 
19
- # Read CSV
20
- improvement_data = pd.read_csv(improvement_csv_path)
 
21
 
22
- # Load raster stack
23
- wealth_stack = rasterio.open(wealth_tif_path)
 
24
 
25
- # Time periods corresponding to bands
26
- time_periods = [
27
- "1990–1992", "1993–1995", "1996–1998", "1999–2001", "2002–2004",
28
- "2005–2007", "2008–2010", "2011–2013", "2014–2016", "2017–2019"
29
- ]
30
 
31
- # ---- 2. UI ----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  app_ui = ui.page_fluid(
33
- ui.h2("Africa Wealth Map Dashboard (Python Version)"),
34
- ui.layout_sidebar(
35
- ui.panel_sidebar(
36
- ui.input_slider("time_index", "Select Time Period (Years):", 1, 10, 1),
37
- ui.input_select("color_palette", "Select Color Palette:", {
38
- "viridis": "Viridis", "plasma": "Plasma", "magma": "Magma",
39
- "inferno": "Inferno", "Spectral": "Spectral (Brewer)"
40
- }),
41
- ui.input_slider("opacity", "Map Opacity:", 0.2, 1.0, 0.8, step=0.1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  ),
43
- ui.panel_main(
44
- ui.output_text("current_year_range"),
45
- ui.output_plot("iwi_histogram"),
46
- ui.output_plot("trend_plot"),
47
- ui.output_plot("clicked_ts_plot")
48
- )
49
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  )
51
 
52
- # ---- 3. Server ----
 
 
53
  def server(input, output, session):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- selected_band = reactive.Calc(lambda: input.time_index())
 
 
 
 
 
56
 
 
 
 
 
 
 
 
 
 
 
57
  @output
58
  @render.text
59
  def current_year_range():
60
- return time_periods[input.time_index() - 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- @output
63
- @render.plot
64
- def iwi_histogram():
65
- band_index = input.time_index() - 1
66
- band_data = wealth_stack.read(band_index + 1).flatten()
67
- band_data = band_data[(band_data > 0) & (band_data <= 1)]
68
- plt.figure(figsize=(6, 4))
69
- plt.hist(band_data, bins=20, color="skyblue", edgecolor="white")
70
- plt.title("IWI Histogram")
71
- plt.xlabel("IWI")
72
- plt.ylabel("Frequency")
73
- return plt.gcf()
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  @output
76
  @render.plot
77
  def trend_plot():
78
- mean_iwi = []
79
- for i in range(1, 11):
80
- band_data = wealth_stack.read(i).flatten()
81
- band_data = band_data[(band_data > 0) & (band_data <= 1)]
82
- mean_iwi.append(np.mean(band_data))
83
-
84
- fig = go.Figure()
85
- fig.add_trace(go.Scatter(x=time_periods, y=mean_iwi, mode='lines+markers'))
86
- fig.update_layout(title="Average IWI Over Time", xaxis_title="Period", yaxis_title="Mean IWI")
 
87
  return fig
88
-
 
 
 
 
 
 
 
 
 
89
  @output
90
  @render.plot
91
  def clicked_ts_plot():
92
- # Placeholder until integrated with map click logic
93
- fig = go.Figure()
94
- fig.update_layout(title="Click on map to load time series")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
- # ---- 4. App ----
98
- app = App(app_ui, server)
 
 
 
1
+ # app.py
2
+ from shiny import App, ui, reactive, render
 
3
  import pandas as pd
4
  import numpy as np
 
 
 
5
  import matplotlib.pyplot as plt
 
6
  import rasterio
7
+ from rasterio.plot import show
8
+ import geopandas as gpd
9
+ from ipyleaflet import Map, TileLayer, basemaps, ColorMap, RasterLayer, LegendControl, GeoJSON
10
+ from shinywidgets import output_widget, register_widget
11
+ import plotnine as p9
12
+ # from palettable.colorbrewer.diverging import Spectral_10
13
+ # from palettable.colorbrewer.sequential import Blues_9, OrRd_9, PuBuGn_9, Reds_9
14
+ import os
15
+ import base64
16
+ import tempfile
17
  import json
18
+ from datetime import datetime
19
+ from fetch_data import fetch_data
20
+ from residuals import get_residual_plot
21
 
22
+ # ------------------------------
23
+ # 1. Data & Config
24
+ # ------------------------------
 
25
 
26
+ # Define time periods corresponding to each band in the GeoTIFF
27
+ time_periods = ["1990–1992", "1993–1995", "1996–1998", "1999–2001", "2002–2004",
28
+ "2005–2007", "2008–2010", "2011–2013", "2014–2016", "2017–2019"]
29
 
30
+ # Load GeoTIFF data (multi-band)
31
+ # Note: In a real application, you'd need to adjust this path
32
+ wealth_stack = rasterio.open("wealth_map.tif")
33
 
34
+ with open('data/no_somaliland.geojson') as a:
35
+ country_json = json.load(a)
36
+
37
+ IWI_df = pd.read_csv('data/mean_IWI_by_country.csv')
 
38
 
39
+ residual_data = pd.read_csv('data/residual_by_country.csv')
40
+
41
+
42
+
43
+
44
+ # Function to clean up out-of-range values and get values
45
+ def get_clean_values(src, band_idx=1):
46
+ band_data = src.read(band_idx)
47
+ # Replace out-of-range values with NaN
48
+ band_data[(band_data <= 0) | (band_data > 1)] = np.nan
49
+ return band_data
50
+
51
+ # Get all values across all bands for quantiles
52
+ all_vals = []
53
+ for i in range(1, wealth_stack.count + 1):
54
+ vals = get_clean_values(wealth_stack, i).flatten()
55
+ all_vals.extend(vals[~np.isnan(vals)])
56
+
57
+ all_vals = np.array(all_vals)
58
+ q_breaks_legend = np.quantile(all_vals, np.linspace(0, 1, 6))
59
+ q_breaks = np.quantile(all_vals, np.linspace(0, 1, 11))
60
+
61
+ # Get raster bounds for proper positioning on the map
62
+ bounds = [[wealth_stack.bounds.bottom, wealth_stack.bounds.left],
63
+ [wealth_stack.bounds.top, wealth_stack.bounds.right]]
64
+
65
+ # Load improvement data (change in IWI by state/province)
66
+ # In real app, adjust path
67
+ improvement_data = pd.read_csv("data/poverty_improvement_by_state.csv")
68
+
69
+ # Pre-calculate the mean IWI for each band (for the "Trends Over Time" chart)
70
+ band_means = []
71
+ for i in range(1, wealth_stack.count + 1):
72
+ vals = get_clean_values(wealth_stack, i).flatten()
73
+ band_means.append(np.nanmean(vals))
74
+
75
+ # ------------------------------
76
+ # 2. UI
77
+ # ------------------------------
78
+
79
+ # Custom CSS for OCR A Std font and other styling
80
+ css = """
81
+ @import url('https://fonts.cdnfonts.com/css/ocr-a-std');
82
+
83
+ body {
84
+ font-family: 'OCR A Std', monospace !important;
85
+ }
86
+
87
+ .slider-animate-button {
88
+ background-color: #ffffff !important;
89
+ color: #000000 !important;
90
+ border: 2px solid #000000 !important;
91
+ border-radius: 5px !important;
92
+ padding: 5px 10px !important;
93
+ top: 10px !important;
94
+ }
95
+
96
+ .value-box {
97
+ margin-bottom: 15px;
98
+ padding: 15px;
99
+ border-radius: 5px;
100
+ color: white;
101
+ }
102
+
103
+ .green-box {
104
+ background-color: #00a65a;
105
+ }
106
+
107
+ .blue-box {
108
+ background-color: #0073b7;
109
+ }
110
+
111
+ .red-box {
112
+ background-color: #dd4b39;
113
+ }
114
+
115
+ .share-button {
116
+ display: inline-flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ gap: 8px;
120
+ padding: 5px 10px;
121
+ font-size: 16px;
122
+ font-weight: normal;
123
+ color: #000;
124
+ background-color: #fff;
125
+ border: 1px solid #ddd;
126
+ border-radius: 6px;
127
+ cursor: pointer;
128
+ box-shadow: 0 1.5px 0 #000;
129
+ }
130
+
131
+ .title-text {
132
+ font-family: 'OCR A Std', monospace;
133
+ font-size: 18px;
134
+ }
135
+
136
+ .subtitle-text {
137
+ font-family: 'OCR A Std', monospace;
138
+ font-size: 14px;
139
+ }
140
+ #improvement_table .shiny-data-grid {
141
+ width: 100% !important;
142
+ }
143
+ .nav-link {
144
+ color: white !important;
145
+ }
146
+ """
147
+
148
+ # Share button HTML
149
+ share_button_html = """
150
+ <button id="share-button" class="share-button">
151
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
152
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
153
+ <circle cx="18" cy="5" r="3"></circle>
154
+ <circle cx="6" cy="12" r="3"></circle>
155
+ <circle cx="18" cy="19" r="3"></circle>
156
+ <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
157
+ <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
158
+ </svg>
159
+ <strong>Share</strong>
160
+ </button>
161
+
162
+ <script>
163
+ (function() {
164
+ const shareBtn = document.getElementById('share-button');
165
+ // Reusable helper function to show a small "Copied!" message
166
+ function showCopyNotification() {
167
+ const notification = document.createElement('div');
168
+ notification.innerText = 'Copied to clipboard';
169
+ notification.style.position = 'fixed';
170
+ notification.style.bottom = '20px';
171
+ notification.style.right = '20px';
172
+ notification.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
173
+ notification.style.color = '#fff';
174
+ notification.style.padding = '8px 12px';
175
+ notification.style.borderRadius = '4px';
176
+ notification.style.zIndex = '9999';
177
+ document.body.appendChild(notification);
178
+ setTimeout(() => { notification.remove(); }, 2000);
179
+ }
180
+ shareBtn.addEventListener('click', function() {
181
+ const currentURL = window.location.href;
182
+ const pageTitle = document.title || 'Check this out!';
183
+ // If browser supports Web Share API
184
+ if (navigator.share) {
185
+ navigator.share({
186
+ title: pageTitle,
187
+ text: '',
188
+ url: currentURL
189
+ })
190
+ .catch((error) => {
191
+ console.log('Sharing failed', error);
192
+ });
193
+ } else {
194
+ // Fallback: Copy URL
195
+ if (navigator.clipboard && navigator.clipboard.writeText) {
196
+ navigator.clipboard.writeText(currentURL).then(() => {
197
+ showCopyNotification();
198
+ }, (err) => {
199
+ console.error('Could not copy text: ', err);
200
+ });
201
+ } else {
202
+ // Double fallback for older browsers
203
+ const textArea = document.createElement('textarea');
204
+ textArea.value = currentURL;
205
+ document.body.appendChild(textArea);
206
+ textArea.select();
207
+ try {
208
+ document.execCommand('copy');
209
+ showCopyNotification();
210
+ } catch (err) {
211
+ alert('Please copy this link:\\n' + currentURL);
212
+ }
213
+ document.body.removeChild(textArea);
214
+ }
215
+ }
216
+ });
217
+ })();
218
+ </script>
219
+ """
220
+
221
+ # Create the app UI with dashboard layout
222
  app_ui = ui.page_fluid(
223
+ ui.head_content(
224
+ ui.tags.style(css)
225
+ ),
226
+ ui.page_navbar(
227
+ ui.nav_panel("Wealth Map",
228
+ ui.layout_sidebar(
229
+ ui.sidebar(
230
+ ui.h4("Map Controls"),
231
+ ui.input_slider(
232
+ "time_index",
233
+ "Select Time Period (Years):",
234
+ min=1,
235
+ max=len(time_periods),
236
+ value=1,
237
+ step=1,
238
+ animate=True
239
+ ),
240
+ ui.strong("Currently Selected: "),
241
+ ui.output_text("current_year_range", inline=True),
242
+ ui.input_select(
243
+ "color_palette",
244
+ "Select Color Palette:",
245
+ {
246
+ "blue": "blue",
247
+ "red": "red",
248
+ "orange": "orange",
249
+ "purple": "purple",
250
+ "Spectral": "Spectral (Brewer)"
251
+ },
252
+ selected="red"
253
+ ),
254
+ ui.input_slider(
255
+ "opacity",
256
+ "Map Opacity:",
257
+ min=0.2,
258
+ max=1,
259
+ value=0.8,
260
+ step=0.1
261
+ ),
262
+ ui.HTML(share_button_html)
263
+ ),
264
+ ui.layout_column_wrap(
265
+ ui.value_box(
266
+ "Highest IWI",
267
+ ui.output_text("highest_iwi"),
268
+ showcase=ui.tags.i(class_="fa fa-arrow-up"),
269
+ theme="success"
270
+ ),
271
+ ui.value_box(
272
+ "Lowest IWI",
273
+ ui.output_text("lowest_iwi"),
274
+ showcase=ui.tags.i(class_="fa fa-arrow-down"),
275
+ theme="danger"
276
+ ),
277
+ ui.value_box(
278
+ "Average IWI",
279
+ ui.output_text("avg_iwi"),
280
+ showcase=ui.tags.i(class_="fa fa-balance-scale"),
281
+ theme="primary"
282
+ ),
283
+ width=1/3
284
+ ),
285
+ ui.layout_column_wrap(
286
+ ui.card(
287
+ ui.card_header(ui.h3("Wealth Map of Africa", class_="title-text")),
288
+ output_widget("map"),
289
+ ui.p("Click anywhere on the map to view the time-series of IWI for that specific location (shown below).")
290
+ ),
291
+ ui.card(
292
+ ui.card_header(ui.h3("Time Series at Clicked Location", class_="subtitle-text")),
293
+ ui.output_plot("clicked_ts_plot"),
294
+ ui.p("Click on the map to see the full IWI time-series (1990–2019) for that location.")
295
+ )
296
+ ),
297
+
298
+ ui.card(
299
+ ui.card_header(ui.h3("Ground Truth vs. Prediction Residual Distribution (Selected Country)", class_="subtitle-text")),
300
+ ui.output_plot("iwi_residuals"),
301
+ ui.p("This chart shows the distribution of residuals between ground truth and predicted IWI values based on the selected country."),
302
+ ui.strong("Note: wealth estimates for areas without human settlements have been excluded from the analysis."),
303
+ ui.HTML("<a href='https://doi.org/10.24963/ijcai.2023/684' target='_blank'>[Paper PDF]</a>")
304
+ ),
305
+ )
306
  ),
307
+ ui.nav_panel("Improvement Data",
308
+ ui.layout_columns(
309
+ ui.card(
310
+ ui.card_header(ui.h3("Poverty Improvement by State", class_="title-text")),
311
+ ui.p("This table shows the estimated improvement in mean IWI between 1990–1992 and 2017–2019 for each province in Africa. "
312
+ "The 'Improvement' column indicates the change in IWI over this period. You can sort or filter the table, "
313
+ "and use the download button to export the data."),
314
+ ui.download_button("download_data", "Download CSV", icon="download"),
315
+ ui.card(ui.output_data_frame("improvement_table")),
316
+
317
+ )
318
+ )
319
+ ),
320
+ ui.nav_panel("Trends Over Time",
321
+ ui.card(
322
+ ui.card_header(ui.h3("Average Wealth Index Across Africa Over Time", class_="title-text")),
323
+ ui.p("This chart aggregates the mean IWI across all of Africa in each of the ten time periods. "
324
+ "It provides a high-level view of how wealth (as measured by IWI) has changed over time."),
325
+ ui.output_plot("trend_plot")
326
+ )
327
+ ),
328
+ title=ui.HTML(
329
+ "<span style='font-weight: 600; font-size: 16px;'>"
330
+ "<a href='http://aidevlab.org' target='_blank' "
331
+ "style='font-family: \"OCR A Std\", monospace; color: white; text-decoration: underline;'>"
332
+ "aidevlab.org</a></span>"
333
+ ),
334
+ id="tabs",
335
+ bg="#337ab7"
336
+ ),
337
  )
338
 
339
+ # ------------------------------
340
+ # 3. Server logic
341
+ # ------------------------------
342
  def server(input, output, session):
343
+ # Initialize the map widget
344
+ m = Map(center=(0, 20), zoom=3)
345
+ geo_json = GeoJSON(
346
+ data=country_json,
347
+ style={
348
+ 'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.1, 'weight': 1
349
+ },
350
+ hover_style={
351
+ 'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5
352
+ }
353
+ )
354
+ m.add_layer(geo_json)
355
+
356
+
357
 
358
+ # Register the map widget with Shiny
359
+ map_widget = register_widget("map", m)
360
+
361
+ # Store clicked point values
362
+ clicked_point_vals = reactive.Value(None)
363
+ selected_country = reactive.Value(None)
364
 
365
+ admin_layer = reactive.Value(None)
366
+ selected_admin = reactive.Value(None)
367
+
368
+ # Get the currently selected raster layer
369
+ @reactive.Calc
370
+ def selected_raster():
371
+ band_idx = input.time_index()
372
+ return get_clean_values(wealth_stack, band_idx)
373
+
374
+ # Display selected time period
375
  @output
376
  @render.text
377
  def current_year_range():
378
+ return time_periods[input.time_index() - 1] # Adjust for 0-based indexing
379
+
380
+ # Function to get color palette based on user selection
381
+ # @reactive.Calc
382
+ # def get_palette():
383
+ # palette_name = input.color_palette()
384
+ # if palette_name == "blue":
385
+ # return Blues_9.hex_colors
386
+ # elif palette_name == "orange":
387
+ # return OrRd_9.hex_colors
388
+ # elif palette_name == "red":
389
+ # return Reds_9.hex_colors
390
+ # elif palette_name == "purple":
391
+ # return PuBuGn_9.hex_colors
392
+ # else: # Spectral
393
+ # return Spectral_10.hex_colors
394
+
395
+ # Create a RasterLayer for the map
396
+ # @reactive.effect
397
+ # @reactive.event(input.time_index, input.color_palette, input.opacity)
398
+ # def _():
399
+ # # Remove existing raster layers
400
+ # for layer in m.layers:
401
+ # if isinstance(layer, RasterLayer):
402
+ # m.remove_layer(layer)
403
+
404
+ # # Get current raster data
405
+ # raster_data = selected_raster()
406
+
407
+ # # Create a temporary GeoTIFF file
408
+ # with tempfile.NamedTemporaryFile(suffix='.tif', delete=False) as tmp:
409
+ # temp_path = tmp.name
410
+
411
+ # # Create a new GeoTIFF with the selected band
412
+ # with rasterio.open(
413
+ # temp_path,
414
+ # 'w',
415
+ # driver='GTiff',
416
+ # height=raster_data.shape[0],
417
+ # width=raster_data.shape[1],
418
+ # count=1,
419
+ # dtype=raster_data.dtype,
420
+ # crs=wealth_stack.crs,
421
+ # transform=wealth_stack.transform,
422
+ # ) as dst:
423
+ # dst.write(raster_data, 1)
424
+
425
+ # # Create a ColorMap for the raster
426
+ # colormap = ColorMap(
427
+ # vmin=q_breaks[0],
428
+ # vmax=q_breaks[-1]
429
+ # # palette=get_palette()
430
+ # )
431
+
432
+ # # Add the raster layer to the map
433
+ # raster_layer = RasterLayer(
434
+ # url=temp_path,
435
+ # bounds=bounds,
436
+ # colormap=colormap,
437
+ # opacity=input.opacity()
438
+ # )
439
+
440
+ # m.add_layer(raster_layer)
441
+
442
+ # # Add legend
443
+ # for ctrl in m.controls:
444
+ # if isinstance(ctrl, LegendControl):
445
+ # m.remove_control(ctrl)
446
+
447
+ # legend = LegendControl({"IWI": colormap}, position="bottomright")
448
+ # m.add_control(legend)
449
+
450
+ # Handle map clicks
451
+ @reactive.effect
452
+ def _():
453
+ # Set up click event handler
454
+ def handle_map_click(event = None, feature = None, **kwargs):
455
+ coords = feature['geometry']['coordinates'][0] #extract feature coordinates
456
+ latitudes = [coords[x][1] for x in range(len(coords))]
457
+ longitudes = [coords[y][0] for y in range(len(coords))]
458
+ country_name= feature['properties']['sovereignt'] #find country name
459
+ country_abbrev= feature['properties']['sov_a3'] #find country abbreviation
460
 
461
+ selected_country.set(country_name) #set the country name
 
 
 
 
 
 
 
 
 
 
 
462
 
463
+ centroid = (np.mean(latitudes),np.mean(longitudes)) #lock view position to the country's centroid
464
+ m.center = centroid
465
+ m.zoom = 5
466
+
467
+ # Register click handler
468
+ geo_json.on_click(handle_map_click)
469
+
470
+ # Display value boxes
471
+ @output
472
+ @render.text
473
+ def highest_iwi():
474
+ raster_data = selected_raster()
475
+ return f"{np.nanmax(raster_data):.3f}"
476
+
477
+ @output
478
+ @render.text
479
+ def lowest_iwi():
480
+ raster_data = selected_raster()
481
+ return f"{np.nanmin(raster_data):.3f}"
482
+
483
+ @output
484
+ @render.text
485
+ def avg_iwi():
486
+ raster_data = selected_raster()
487
+ return f"{np.nanmean(raster_data):.3f}"
488
+
489
+ # Generate trend plot for mean IWI across Africa
490
  @output
491
  @render.plot
492
  def trend_plot():
493
+ fig, ax = plt.subplots(figsize=(12, 8))
494
+ ax.plot(range(len(time_periods)), band_means, marker='o', color="darkorange", linewidth=2, markersize=6)
495
+ ax.set_xticks(range(len(time_periods)))
496
+ ax.set_xticklabels(time_periods, rotation=45, ha="right")
497
+ ax.set_ylabel("Mean IWI")
498
+ ax.set_ylim(0.1, 0.3)
499
+ ax.set_title("Average IWI Over Time (Africa)")
500
+ ax.grid(True, linestyle='--', alpha=0.7)
501
+
502
+ plt.tight_layout()
503
  return fig
504
+
505
+ # Generate histogram plot
506
+ @output
507
+ @render.plot
508
+ def iwi_residuals():
509
+ country_name = selected_country.get()
510
+ fig = get_residual_plot(country_name, residual_data)
511
+ return fig
512
+
513
+ # Plot time series at clicked location
514
  @output
515
  @render.plot
516
  def clicked_ts_plot():
517
+ country_name = selected_country.get()
518
+
519
+ fig, ax = plt.subplots(figsize=(10, 4))
520
+
521
+ if country_name is None:
522
+ ax.text(0.5, 0.5, "Click on the map to see the IWI time-series here.",
523
+ horizontalalignment='center', verticalalignment='center',
524
+ transform=ax.transAxes, fontsize=14)
525
+ else:
526
+ ax.plot(IWI_df['Band_Number'], IWI_df[country_name], marker='o', color="darkorange", linewidth=2, markersize=6)
527
+ ax.set_xticks(range(1,len(IWI_df['Band_Number'])+1))
528
+ ax.set_xticklabels(time_periods, rotation=45)
529
+ ax.set_ylabel("IWI (0 to 1)")
530
+ ax.set_ylim(0, 1)
531
+ ax.set_title(f"Time Series of IWI in {country_name}")
532
+ ax.grid(True, linestyle='--', alpha=0.7)
533
+
534
+ plt.tight_layout()
535
  return fig
536
+
537
+ # Display improvement data table
538
+ @output
539
+ @render.data_frame
540
+ def improvement_table():
541
+ return render.DataGrid(
542
+ improvement_data,
543
+ filters=True,
544
+ height="800px"
545
+ )
546
+
547
+ # Download CSV handler
548
+ @session.download(filename=lambda: f"poverty_improvement_{datetime.now().strftime('%Y-%m-%d')}.csv")
549
+ def download_data():
550
+ return improvement_data.to_csv(index=False)
551
+
552
+
553
 
554
+ # ------------------------------
555
+ # 4. Create and run the app
556
+ # ------------------------------
557
+ app = App(app_ui, server)
fetch_data.cpython-310.pyc ADDED
Binary file (840 Bytes). View file
 
fetch_data.cpython-311.pyc ADDED
Binary file (1.33 kB). View file
 
fetch_data.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import boto3
2
+ import dotenv
3
+ import os
4
+ import json
5
+ import pandas as pd
6
+ import keys #py file to store AWS access keys
7
+
8
+ def fetch_data(key_path):
9
+ access_key, secret_key = keys.return_keys()
10
+ bucket_name = "ai-and-global-development-lab"
11
+ s3_client = boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key)
12
+
13
+ response = s3_client.get_object(Bucket=bucket_name, Key=key_path)
14
+ if ".geojson" in key_path or ".json" in key_path:
15
+ file_content = response['Body'].read().decode('utf-8')
16
+ json_content = json.loads(file_content)
17
+ return json_content
18
+
19
+ elif ".csv" in key_path:
20
+ file_content = response['Body']
21
+ df_content = pd.read_csv(file_content)
22
+ return df_content
23
+
ground_truth.geojson ADDED
The diff for this file is too large to render. See raw diff
 
keys.cpython-310.pyc ADDED
Binary file (379 Bytes). View file
 
keys.cpython-311.pyc ADDED
Binary file (427 Bytes). View file
 
keys.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ def return_keys():
2
+ AWS_ACCESS_KEY = "AKIAWN26KCOURF7SVJN6"
3
+ AWS_SECRET_ACCESS_KEY = "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"
4
+ return AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY
mean_IWI_by_admin.geojson ADDED
The diff for this file is too large to render. See raw diff
 
mean_IWI_by_country.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ,Band_Number,Band_Number,Burundi,Benin,Burkina Faso,Ivory Coast,Democratic Republic of the Congo,Angola,Botswana,Cameroon,Republic of the Congo,Central African Republic,Djibouti,Algeria,Egypt,Gabon,Eritrea,Ghana,Ethiopia,Guinea,Gambia,Guinea Bissau,Morocco,Liberia,Lesotho,Equatorial Guinea,Libya,Madagascar,Kenya,Mozambique,Mauritania,Niger,Rwanda,Western Sahara,Nigeria,Sudan,Malawi,Namibia,Senegal,South Sudan,Mali,Somaliland,Swaziland,Chad,Somalia,Sierra Leone,Togo,Tunisia,Uganda,Tanzania,South Africa,Zambia,Zimbabwe,Band_Number
2
+ 0,1,1,0.14360115223361136,0.16667101351700164,0.14169287109375,0.15944810830118927,0.15579118064879316,0.13304439073699897,0.15976568993101728,0.2251729317821235,0.2149407343033257,0.179988328800645,0.15605265299479168,0.1879446593433318,0.30621697497865896,0.23697640692774052,0.13913037025765196,0.18456552827160036,0.12535191261504453,0.1442146243207168,0.15072375882056452,0.1435216769366197,0.16918169372546907,0.15575766325789037,0.13863247772522994,0.23850498015474275,0.22032781811048865,0.12924430993670374,0.1980744657306926,0.13254342155884324,0.14632754055958874,0.1659075971962749,0.1633630526267876,0.15814208984375,0.2155312967776489,0.15890416310481797,0.13762894821687416,0.15907970172762056,0.1581028611268348,0.14221467583427602,0.13762534073208724,0.14536932271132885,0.14422255910503926,0.1926965858730568,0.1530189777970479,0.14750959763833144,0.1675630162973873,0.1865914896446951,0.19975409450301204,0.14744970449356085,0.1801025231885972,0.1355538381189675,0.15433936319387617,1
3
+ 1,2,2,0.1474612810374648,0.17538637849242805,0.15132451409870656,0.16867915494125033,0.14502501869096457,0.1381968076385721,0.17182677818449918,0.20483722871104854,0.19155201269441738,0.14786758147422158,0.15419514973958334,0.20033907894935865,0.33685095475956717,0.21284356291608705,0.1409854529038915,0.18243739426575672,0.12952430719233402,0.15340635028859387,0.1588394802866258,0.14689141931668134,0.17962292877255617,0.1640296349158654,0.14507083322518688,0.21305338541666666,0.2357048823915679,0.13061961973073646,0.18355435721065813,0.13552007170311742,0.1569693943239608,0.15717802685811766,0.15533162175723195,0.174591064453125,0.20337946247394448,0.1694449736107546,0.14134635665789752,0.16886871732604025,0.1629524660647587,0.1411246045142817,0.14777531046791997,0.14780139568569936,0.1530974465312908,0.16777267068775778,0.1604410315186053,0.15922935883713119,0.17482543518990104,0.19953027900051787,0.17623209332888012,0.14945212333057578,0.19300752372205193,0.14051029828341188,0.16375006050325946,2
4
+ 2,3,3,0.14498378333623352,0.16542332463435513,0.15771883163319167,0.16823734352623837,0.14499539750077337,0.13394196517221843,0.1787939077280215,0.17598611590479465,0.1768323923887569,0.15076593685395273,0.15361056824525196,0.2112942114457978,0.37014612313389844,0.1852835464345712,0.14256399141474407,0.17436076970122333,0.13013945257273682,0.14600210837044345,0.1642523869679198,0.1427558432792274,0.18344935271728552,0.15423558371954996,0.14666271703099726,0.18477193148764767,0.2512897625565529,0.1285092591300508,0.1846365850776421,0.13567441674039782,0.162429600243223,0.1451237238033325,0.15645718472353518,0.1949666365981102,0.17808743864037616,0.17604242704303846,0.14185443615325455,0.1728693573489501,0.17061826064717026,0.14221596448130197,0.1543370008839419,0.15204623648430288,0.1555304665567051,0.1522003046602388,0.15956033821878718,0.15030850083235195,0.16295092033617425,0.2085708150594794,0.18111973266032608,0.14932319858521131,0.20015412389534012,0.14027369459817968,0.16463912777687845,3
5
+ 3,4,4,0.15318272526102855,0.16714075991981908,0.16641258489391086,0.17891783355384744,0.1445670268027988,0.14448802343920877,0.19144547822459643,0.16922256647104036,0.17115800443965148,0.1495269114360052,0.1535308837890625,0.22825348962898181,0.4052852773411389,0.1832772322527067,0.14708973610237852,0.18504480993713265,0.13659718899678389,0.1537697269140477,0.17124530423072076,0.1461832078836732,0.1988227332306054,0.1626557729482493,0.15365712111970514,0.17817198924529246,0.2743043440181861,0.13508863361281365,0.16525660679993018,0.14200616126039642,0.16788249920057605,0.1430702553759413,0.15735313962783493,0.2185821533203125,0.17852673012977177,0.19054928358356746,0.14927423348806085,0.18436017955055523,0.18347873246945268,0.14995398888221154,0.16226229099412037,0.15858994521103897,0.16907866795857748,0.15394466738157633,0.16656848211973413,0.15386972645102026,0.17137933833337887,0.2293103766206997,0.16747139289033458,0.1554807298717301,0.2130834968854433,0.1494664706035082,0.17366490748453245,4
6
+ 4,5,5,0.15626027981253496,0.1738954557551462,0.1722104062921883,0.1810752175357981,0.14559413449305036,0.1498814628645017,0.20616227073582594,0.17777188924382642,0.17933488226471803,0.14864499310989043,0.15906941766540209,0.24524354711506358,0.4390251870176997,0.1995118918146674,0.15421535539096348,0.19261031036612178,0.1377806995268675,0.15355952118200047,0.18237732578416346,0.15388238646194968,0.2150555624632273,0.1592653953056711,0.16187350808385995,0.19531343882091534,0.29644999043994597,0.13767045786257825,0.1701404511345079,0.14677760441181728,0.17723838685714455,0.14790183125181242,0.15918007322047886,0.2269287109375,0.18566822673810918,0.20380389635017032,0.15195513872754712,0.19641483647584104,0.19537029288243501,0.15575343383922835,0.16824281399134897,0.16515979665661565,0.17832984924704456,0.16105342837222458,0.17212422423640997,0.1517949245965459,0.17475802680286012,0.24449593592695296,0.17219863479284897,0.15861118434769683,0.22624138424632786,0.15533550653149586,0.1803679087956097,5
7
+ 5,6,6,0.15510750854104813,0.1791621603572752,0.180544332242929,0.18995065372947642,0.14608297780116142,0.15288577283073257,0.2174530963234554,0.18371138322664315,0.1868198239615175,0.14620676393356785,0.17403035486737886,0.2636778048520901,0.4645401599061865,0.21604991986995606,0.1647712812848287,0.20254796595790797,0.14357037374253742,0.15285098971269453,0.1925043334819113,0.16228917929488168,0.23100478862306026,0.16278005060496353,0.1667824779386536,0.21282876796351793,0.316242472680778,0.14026866332848661,0.17616876956919103,0.15294158051821213,0.1836515212490786,0.15031814160714815,0.1618641481213903,0.23957519233226776,0.19454539169419605,0.2192205141008414,0.15670192530486185,0.2033620594804516,0.20697273706061564,0.16525641377020744,0.17613290617036784,0.1730959749813425,0.18632847454864532,0.1672610971987172,0.1807569135494983,0.15004218377887385,0.17592207193027287,0.26089484484453623,0.1760213400675057,0.16303444741229597,0.23780704238400677,0.16425568626600312,0.18436713656157222,6
8
+ 6,7,7,0.16028250787491188,0.1907362270704556,0.19164785357753625,0.1994043046063316,0.15041300854816497,0.16195695175655941,0.22783480006337956,0.19324491027399157,0.2008908811126905,0.1513704288901621,0.17501220703125,0.2862842581950027,0.49887416602712625,0.23710178164985235,0.16924569864420294,0.217281407703554,0.14856844394827293,0.15930923965332586,0.20774021945965634,0.17414424917792196,0.24313912406244773,0.1644996051522894,0.17184356993615033,0.23987550001878005,0.3443522288881499,0.14296342206923343,0.1840075274419518,0.15887666930262617,0.18874510999843566,0.14861782177074537,0.16842529039342696,0.227783203125,0.20653116251072234,0.23661287641936166,0.162731162885056,0.204814033767804,0.2226238250732422,0.17992252677813914,0.18830449109990124,0.17808589650623835,0.19657352138748369,0.17414636045279908,0.1920832217727577,0.15579702039087495,0.18356950291377147,0.281051690970483,0.18359144857107115,0.16888550158460522,0.2467528439083615,0.17279310361052438,0.1887763142261287,7
9
+ 7,8,8,0.16541191479837694,0.19986812589548483,0.20119602832244432,0.20455159351012434,0.1527457024498158,0.17021070117457532,0.2404282596825764,0.19796815524281744,0.20131059468065926,0.15567407057678373,0.18084038669864336,0.30998429191664967,0.5212907541218701,0.24066629907277626,0.17556773122297983,0.226826579287237,0.15580737112028153,0.1639075041416473,0.21903587729217922,0.18329361719144902,0.2598543911232271,0.16004211036950686,0.18045091412961484,0.25967430071815417,0.36626729229364696,0.1485011643800056,0.19503154912245874,0.16811740407444561,0.1934325116104035,0.15729555606492848,0.17576150594569961,0.2409261092543602,0.2144002010177841,0.2521401892595103,0.17065389569339745,0.21365951581471632,0.2348675484049335,0.1929871520874175,0.1964402972367702,0.18837076030215438,0.21062621555969546,0.18136411241338224,0.20434876599796734,0.15825436926853298,0.18882254678517477,0.30107401029494113,0.1907624156728793,0.1777368577662003,0.26077405301116746,0.18661108775528243,0.19863733150925253,8
10
+ 8,9,9,0.1868448203566384,0.22534527949547367,0.23452960859982674,0.2341415804801294,0.17273932205560721,0.19510147798430202,0.27037729427514484,0.21857611392452797,0.22675326280978136,0.17468864589435382,0.20749715169270833,0.34771423576230875,0.5515830940414486,0.2581792876476378,0.20322083773678296,0.25704640134409484,0.1790083168196852,0.18645637761306472,0.25268968151461696,0.20883945960783015,0.2958282984585038,0.17869681198970075,0.2097137451171875,0.27842530866911175,0.4020729750544797,0.17132430052001774,0.22069611881482426,0.19153148037285034,0.22153825579949146,0.17900887601971088,0.19915385185917722,0.26837158203125,0.243159205904316,0.28412149730893865,0.19359288008316702,0.242360342920354,0.265945148825199,0.21942801497101244,0.22801310063272953,0.2136803312674581,0.24110658963521323,0.20714608737573273,0.22933482991874135,0.18158120925777677,0.2147425938319493,0.33538856249797916,0.20965286607396091,0.20102480614683402,0.29201238806847624,0.21378810342342647,0.22732181195474374,9
11
+ 9,10,10,0.20830976378242924,0.24617119534111723,0.2642609630162555,0.261458412480462,0.19183167358339512,0.2160684127406305,0.2953741195354056,0.23983234660985386,0.2424389133750573,0.19428157599226104,0.23563639322916666,0.373744598968944,0.5555806587837838,0.28429675177444796,0.22939822272336768,0.27868048575827087,0.20189345139723558,0.20884652973263493,0.28271680629521706,0.23708717411030453,0.32237467307767054,0.2017482866415063,0.23342479819871262,0.3074505145733173,0.42074334672886693,0.1930362357698832,0.24427010465992252,0.21472592483698627,0.24803867946665195,0.2033278084317234,0.2235377830795095,0.2978515625,0.2679682230911353,0.31152027661644577,0.21460742054543908,0.26938093270051194,0.2952720642089844,0.24408594191883484,0.25895545445575613,0.24221835919280552,0.26553894521050914,0.2319116241880545,0.25783156557748793,0.20182083380941498,0.23292810357715868,0.36211042438746116,0.22947299564284238,0.22473386808206106,0.31714853658791164,0.23898104906470669,0.2515060216919278,10
no_somaliland.geojson ADDED
The diff for this file is too large to render. See raw diff
 
poverty_improvement_by_state.csv ADDED
@@ -0,0 +1,856 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Country","Province","Rank","Improvement"
2
+ "Gambia","Banjul",1,0.31955
3
+ "Mali","Bamako",2,0.31376
4
+ "Botswana","Francistown",3,0.28345
5
+ "Egypt","Kafr ash Shaykh",4,0.27021
6
+ "Algeria","Boumerdès",5,0.26634
7
+ "Egypt","Ash Sharqiyah",6,0.26594
8
+ "Egypt","Bur Sa`id",7,0.26321
9
+ "Egypt","Ad Daqahliyah",8,0.26129
10
+ "Egypt","Luxor",9,0.25765
11
+ "Egypt","Dumyat",10,0.25121
12
+ "Botswana","Gaborone",11,0.24716
13
+ "Central African Republic","Bangui",12,0.24536
14
+ "Egypt","Al Gharbiyah",13,0.24513
15
+ "Egypt","Al Minufiyah",14,0.22851
16
+ "Morocco","Grand Casablanca",15,0.22812
17
+ "Botswana","Lobatse",16,0.22754
18
+ "Algeria","Tizi Ouzou",17,0.22517
19
+ "Libya","Tajura' wa an Nawahi al Arba",18,0.22499
20
+ "Mozambique","Maputo",19,0.22482
21
+ "Algeria","Sétif",20,0.22442
22
+ "Angola","Luanda",21,0.22147
23
+ "Tunisia","Ben Arous (Tunis Sud)",22,0.2203
24
+ "Egypt","Asyut",23,0.21946
25
+ "Algeria","Mila",24,0.21815
26
+ "Algeria","Jijel",25,0.21676
27
+ "Egypt","Qina",26,0.21588
28
+ "Libya","Al Jifarah",27,0.21512
29
+ "Egypt","Al Buhayrah",28,0.21469
30
+ "Algeria","Blida",29,0.21357
31
+ "Algeria","Constantine",30,0.20791
32
+ "Algeria","Tipaza",31,0.20667
33
+ "Algeria","Mostaganem",32,0.20647
34
+ "Tunisia","Manubah",33,0.20299
35
+ "Niger","Niamey",34,0.20255
36
+ "Egypt","Al Qalyubiyah",35,0.2005
37
+ "Tunisia","Monastir",36,0.19901
38
+ "Algeria","Bordj Bou Arréridj",37,0.19734
39
+ "Ethiopia","Addis Ababa",38,0.19314
40
+ "Algeria","Béjaïa",39,0.1923
41
+ "Algeria","Aïn Témouchent",40,0.19053
42
+ "Kenya","Nairobi",41,0.19051
43
+ "Tunisia","Mahdia",42,0.18971
44
+ "Zimbabwe","Harare",43,0.18842
45
+ "Egypt","Suhaj",44,0.18763
46
+ "Algeria","Annaba",45,0.18544
47
+ "Algeria","Mascara",46,0.18378
48
+ "Algeria","Bouira",47,0.18271
49
+ "Algeria","Oran",48,0.18269
50
+ "Algeria","Aïn Defla",49,0.18008
51
+ "Algeria","Chlef",50,0.17978
52
+ "Algeria","El Tarf",51,0.1785
53
+ "Tunisia","Zaghouan",52,0.17821
54
+ "Morocco","Gharb - Chrarda - Béni Hssen",53,0.17795
55
+ "Senegal","Thiès",54,0.17778
56
+ "Algeria","Skikda",55,0.17667
57
+ "Senegal","Dakar",56,0.17611
58
+ "Tunisia","Sousse",57,0.17483
59
+ "Algeria","Alger",58,0.17438
60
+ "Tunisia","Kairouan",59,0.17427
61
+ "Egypt","Al Qahirah",60,0.17394
62
+ "Algeria","Guelma",61,0.17316
63
+ "Algeria","Oum el Bouaghi",62,0.17177
64
+ "Algeria","Batna",63,0.17102
65
+ "Uganda","Kampala",64,0.17047
66
+ "Republic of the Congo","Pointe Noire",65,0.17029
67
+ "Tunisia","Jendouba",66,0.16717
68
+ "Tunisia","Nabeul",67,0.16704
69
+ "South Africa","Gauteng",68,0.16687
70
+ "Egypt","Al Iskandariyah",69,0.16506
71
+ "Burkina Faso","Kadiogo",70,0.16066
72
+ "Tunisia","Béja",71,0.16058
73
+ "Egypt","Al Isma`iliyah",72,0.15984
74
+ "United Republic of Tanzania","Dar-Es-Salaam",73,0.15948
75
+ "Tunisia","Tunis",74,0.15855
76
+ "Zimbabwe","Bulawayo",75,0.15845
77
+ "Botswana","Selebi-Phikwe",76,0.15845
78
+ "Algeria","Relizane",77,0.15655
79
+ "United Republic of Tanzania","Zanzibar West",78,0.15601
80
+ "Senegal","Kaolack",79,0.1557
81
+ "Tunisia","Bizerte",80,0.15402
82
+ "Algeria","Souk Ahras",81,0.15168
83
+ "Morocco","Chaouia - Ouardigha",82,0.14985
84
+ "Senegal","Diourbel",83,0.14867
85
+ "Libya","Az Zawiyah",84,0.14612
86
+ "Guinea Bissau","Bissau",85,0.14429
87
+ "Tunisia","Sfax",86,0.14233
88
+ "Benin","Ouémé",87,0.14005
89
+ "Tunisia","Siliana",88,0.13976
90
+ "Morocco","Doukkala - Abda",89,0.13972
91
+ "Algeria","Médéa",90,0.13814
92
+ "Ivory Coast","Fromager",91,0.13803
93
+ "Gambia","Central River",92,0.13574
94
+ "Morocco","Marrakech - Tensift - Al Haouz",93,0.13534
95
+ "Ivory Coast","Sud-Bandama",94,0.13477
96
+ "Egypt","Al Fayyum",95,0.13474
97
+ "Botswana","Jwaneng",96,0.13446
98
+ "Ivory Coast","Lacs",97,0.1341
99
+ "Gambia","Lower River",98,0.13397
100
+ "Gambia","Upper River",99,0.13338
101
+ "Mauritania","Nouakchott",100,0.13255
102
+ "Gambia","West Coast",101,0.13239
103
+ "Chad","Ville de N'Djamena",102,0.13192
104
+ "Tunisia","Le Kef",103,0.13012
105
+ "Rwanda","Kigali City",104,0.12999
106
+ "Tunisia","Sidi Bou Zid",105,0.12966
107
+ "Algeria","Tissemsilt",106,0.12949
108
+ "Ghana","Greater Accra",107,0.12897
109
+ "Burkina Faso","Oubritenga",108,0.12846
110
+ "Algeria","Tlemcen",109,0.12639
111
+ "Sudan","Gezira",110,0.12632
112
+ "Algeria","Sidi Bel Abbès",111,0.12507
113
+ "Ivory Coast","Lagunes",112,0.12452
114
+ "Botswana","South-East",113,0.12289
115
+ "Nigeria","Lagos",114,0.12281
116
+ "Burundi","Bujumbura Mairie",115,0.12195
117
+ "Burkina Faso","Kourwéogo",116,0.12043
118
+ "Burkina Faso","Boulkiemdé",117,0.11939
119
+ "Ghana","Central",118,0.11906
120
+ "Senegal","Fatick",119,0.11895
121
+ "Benin","Atlantique",120,0.1184
122
+ "Egypt","Bani Suwayf",121,0.11738
123
+ "Swaziland","Hhohho",122,0.11599
124
+ "Libya","Al Marqab",123,0.11548
125
+ "Ivory Coast","Agnéby",124,0.11455
126
+ "Morocco","Tanger - Tétouan",125,0.1144
127
+ "Uganda","Wakiso",126,0.11269
128
+ "Ivory Coast","Haut-Sassandra",127,0.11109
129
+ "Swaziland","Manzini",128,0.11051
130
+ "Ivory Coast","Marahoué",129,0.10905
131
+ "Nigeria","Imo",130,0.10903
132
+ "Ivory Coast","Comoe",131,0.10868
133
+ "Mali","Sikasso",132,0.10761
134
+ "Liberia","Montserrado",133,0.10637
135
+ "Swaziland","Shiselweni",134,0.10624
136
+ "South Africa","Mpumalanga",135,0.10558
137
+ "Ghana","Ashanti",136,0.10554
138
+ "Burkina Faso","Léraba",137,0.10516
139
+ "United Republic of Tanzania","Kaskazini-Pemba",138,0.10438
140
+ "Eritrea","Anseba",139,0.10418
141
+ "Burkina Faso","Passoré",140,0.10293
142
+ "Senegal","Ziguinchor",141,0.10192
143
+ "Algeria","M'Sila",142,0.10051
144
+ "South Africa","Limpopo",143,0.09866
145
+ "South Africa","North West",144,0.09866
146
+ "United Republic of Tanzania","Kaskazini-Unguja",145,0.09855
147
+ "Morocco","Taza - Al Hoceima - Taounate",146,0.09815
148
+ "Burkina Faso","Kénédougou",147,0.09774
149
+ "South Africa","KwaZulu-Natal",148,0.09651
150
+ "Senegal","Sédhiou",149,0.09603
151
+ "Benin","Mono",150,0.09475
152
+ "Sierra Leone","Western",151,0.09447
153
+ "Nigeria","Ekiti",152,0.09424
154
+ "Nigeria","Abia",153,0.09423
155
+ "Ivory Coast","Bas-Sassandra",154,0.09414
156
+ "Libya","An Nuqat al Khams",155,0.09382
157
+ "Tunisia","Médenine",156,0.09314
158
+ "Ivory Coast","N'zi-Comoé",157,0.09263
159
+ "Morocco","Rabat - Salé - Zemmour - Zaer",158,0.09249
160
+ "South Africa","Free State",159,0.09102
161
+ "Tunisia","Gabès",160,0.09005
162
+ "Nigeria","Osun",161,0.08957
163
+ "Gambia","North Bank",162,0.08956
164
+ "Ethiopia","Harari People",163,0.08895
165
+ "Tunisia","Kassérine",164,0.08787
166
+ "Burundi","Bubanza",165,0.0876
167
+ "Morocco","Tadla - Azilal",166,0.08631
168
+ "Ghana","Western",167,0.08617
169
+ "Guinea","Labé",168,0.08613
170
+ "Ivory Coast","Savanes",169,0.08534
171
+ "Burkina Faso","Balé",170,0.08523
172
+ "Guinea Bissau","Biombo",171,0.08512
173
+ "Ghana","Upper East",172,0.08394
174
+ "Lesotho","Berea",173,0.08332
175
+ "Burkina Faso","Mou Houn",174,0.08322
176
+ "Botswana","North-East",175,0.08284
177
+ "United Republic of Tanzania","Zanzibar South and Central",176,0.08265
178
+ "Tunisia","Gafsa",177,0.08257
179
+ "Burkina Faso","Bam",178,0.08232
180
+ "Morocco","Souss - Massa - Draâ",179,0.08226
181
+ "Burkina Faso","Ganzourgou",180,0.08222
182
+ "Nigeria","Anambra",181,0.08209
183
+ "Sudan","Khartoum",182,0.08203
184
+ "Malawi","Blantyre",183,0.08107
185
+ "Nigeria","Sokoto",184,0.08106
186
+ "Malawi","Lilongwe",185,0.081
187
+ "Ivory Coast","Sud-Comoé",186,0.08048
188
+ "Nigeria","Zamfara",187,0.08046
189
+ "Lesotho","Mafeteng",188,0.08033
190
+ "Botswana","Sowa",189,0.0802
191
+ "Guinea Bissau","Cacheu",190,0.07948
192
+ "Nigeria","Kebbi",191,0.07796
193
+ "Togo","Maritime",192,0.07777
194
+ "Burundi","Rutana",193,0.07749
195
+ "Swaziland","Lubombo",194,0.07749
196
+ "Equatorial Guinea","Kié-Ntem",195,0.07741
197
+ "Ghana","Eastern",196,0.07715
198
+ "Malawi","Dedza",197,0.07681
199
+ "Algeria","Khenchela",198,0.07654
200
+ "Burkina Faso","Bazéga",199,0.07622
201
+ "Burkina Faso","Boulgou",200,0.07617
202
+ "Malawi","Chiradzulu",201,0.07532
203
+ "Libya","Benghazi",202,0.07522
204
+ "Malawi","Mulanje",203,0.0748
205
+ "Somalia","Banaadir",204,0.07416
206
+ "Liberia","Margibi",205,0.07409
207
+ "Malawi","Thyolo",206,0.07357
208
+ "Burkina Faso","Yatenga",207,0.0735
209
+ "Burkina Faso","Zoundwéogo",208,0.07336
210
+ "Malawi","Dowa",209,0.07251
211
+ "Nigeria","Akwa Ibom",210,0.07242
212
+ "Uganda","Sheema",211,0.07236
213
+ "Ivory Coast","Worodougou",212,0.07228
214
+ "Ethiopia","Dire Dawa",213,0.07164
215
+ "Algeria","Saïda",214,0.0709
216
+ "Eritrea","Maekel",215,0.0702
217
+ "Burkina Faso","Sourou",216,0.07016
218
+ "Guinea","Conakry",217,0.07007
219
+ "Guinea","Coyah",218,0.06942
220
+ "Burundi","Bujumbura Rural",219,0.06896
221
+ "Malawi","Mchinji",220,0.06845
222
+ "Burkina Faso","Zondoma",221,0.06801
223
+ "Guinea","Lélouma",222,0.06774
224
+ "Nigeria","Ogun",223,0.06762
225
+ "Burundi","Mwaro",224,0.06752
226
+ "Algeria","Tébessa",225,0.06694
227
+ "Malawi","Ntchisi",226,0.06681
228
+ "Burundi","Bururi",227,0.06679
229
+ "Burundi","Karuzi",228,0.06661
230
+ "Senegal","Kaffrine",229,0.06633
231
+ "Liberia","Grand Bassa",230,0.06613
232
+ "Equatorial Guinea","Wele-Nzás",231,0.0661
233
+ "Uganda","Mukono",232,0.06603
234
+ "Burkina Faso","Houet",233,0.06596
235
+ "Burundi","Cibitoke",234,0.06564
236
+ "Uganda","Mayuge",235,0.06536
237
+ "Lesotho","Leribe",236,0.06512
238
+ "Malawi","Ntcheu",237,0.06472
239
+ "Burkina Faso","Sanguié",238,0.06444
240
+ "Burkina Faso","Kouritenga",239,0.06418
241
+ "Uganda","Bushenyi",240,0.06391
242
+ "Ghana","Upper West",241,0.06365
243
+ "Burundi","Makamba",242,0.06293
244
+ "Guinea","Mandiana",243,0.06283
245
+ "Algeria","Tiaret",244,0.06279
246
+ "Uganda","Mpigi",245,0.06259
247
+ "Burundi","Kayanza",246,0.0624
248
+ "Benin","Plateau",247,0.06238
249
+ "Burundi","Ngozi",248,0.06218
250
+ "Ivory Coast","Vallée du Bandama",249,0.06203
251
+ "Burundi","Muramvya",250,0.06167
252
+ "Burkina Faso","Banwa",251,0.06131
253
+ "Rwanda","Southern",252,0.06122
254
+ "Burundi","Muyinga",253,0.0612
255
+ "Ghana","Brong Ahafo",254,0.06116
256
+ "Guinea Bissau","Oio",255,0.0611
257
+ "Nigeria","Gombe",256,0.06094
258
+ "Malawi","Balaka",257,0.06085
259
+ "Guinea","Pita",258,0.06083
260
+ "United Republic of Tanzania","Kusini-Pemba",259,0.06069
261
+ "Egypt","As Suways",260,0.0605
262
+ "South Africa","Eastern Cape",261,0.06048
263
+ "Guinea","Dubréka",262,0.06007
264
+ "Guinea","Nzérékoré",263,0.06002
265
+ "Burundi","Gitega",264,0.05988
266
+ "Namibia","Ohangwena",265,0.05933
267
+ "Malawi","Phalombe",266,0.05891
268
+ "Madagascar","Itasy",267,0.05876
269
+ "Equatorial Guinea","Bioko Norte",268,0.05858
270
+ "Ivory Coast","Dix-Huit Montagnes",269,0.05819
271
+ "Angola","Cabinda",270,0.05815
272
+ "Malawi","Neno",271,0.0578
273
+ "Nigeria","Enugu",272,0.0575
274
+ "Nigeria","Ondo",273,0.05744
275
+ "Burundi","Ruyigi",274,0.0573
276
+ "Nigeria","Kano",275,0.05681
277
+ "Libya","Al Jabal al Akhdar",276,0.05667
278
+ "Uganda","Ntungamo",277,0.0566
279
+ "Algeria","Biskra",278,0.05659
280
+ "Guinea","Forécariah",279,0.05634
281
+ "Burkina Faso","Sanmatenga",280,0.05634
282
+ "Ivory Coast","Denguélé",281,0.05612
283
+ "Burundi","Kirundo",282,0.05584
284
+ "Uganda","Luweero",283,0.05576
285
+ "Malawi","Zomba",284,0.05502
286
+ "Ghana","Volta",285,0.0548
287
+ "Egypt","Al Minya",286,0.05452
288
+ "Rwanda","Eastern",287,0.05445
289
+ "Senegal","Louga",288,0.05424
290
+ "Lesotho","Maseru",289,0.05359
291
+ "Morocco","Meknès - Tafilalet",290,0.05346
292
+ "Burkina Faso","Tuy",291,0.05344
293
+ "Malawi","Salima",292,0.05334
294
+ "Liberia","Bong",293,0.05332
295
+ "Malawi","Mangochi",294,0.05248
296
+ "Uganda","Mitooma",295,0.05245
297
+ "Uganda","Mbarara",296,0.05206
298
+ "Guinea","Siguiri",297,0.05175
299
+ "Zambia","Copperbelt",298,0.0516
300
+ "South Africa","Western Cape",299,0.05143
301
+ "Zimbabwe","Mashonaland East",300,0.05101
302
+ "Guinea Bissau","Tombali",301,0.05091
303
+ "Libya","Al Marj",302,0.05076
304
+ "Malawi","Machinga",303,0.05043
305
+ "Guinea","Fria",304,0.04977
306
+ "Ivory Coast","Zanzan",305,0.04963
307
+ "Burkina Faso","Sissili",306,0.04958
308
+ "Burkina Faso","Koulpélogo",307,0.0494
309
+ "Benin","Kouffo",308,0.04903
310
+ "Mali","Ségou",309,0.04872
311
+ "Morocco","Fès - Boulemane",310,0.0487
312
+ "Mali","Koulikoro",311,0.04866
313
+ "Guinea","Boffa",312,0.04832
314
+ "Guinea","Yomou",313,0.04806
315
+ "Guinea","Macenta",314,0.04774
316
+ "Liberia","Nimba",315,0.04759
317
+ "Guinea","Beyla",316,0.04728
318
+ "Liberia","Bomi",317,0.04709
319
+ "Benin","Borgou",318,0.04708
320
+ "Uganda","Butambala",319,0.04696
321
+ "Malawi","Kasungu",320,0.04687
322
+ "Niger","Dosso",321,0.04668
323
+ "Guinea","Dalaba",322,0.04656
324
+ "Benin","Donga",323,0.04651
325
+ "Uganda","Busia",324,0.04636
326
+ "Uganda","Kabale",325,0.04616
327
+ "Burkina Faso","Nayala",326,0.04612
328
+ "Burkina Faso","Komoé",327,0.046
329
+ "Uganda","Bugiri",328,0.04589
330
+ "Uganda","Iganga",329,0.04587
331
+ "Burkina Faso","Nahouri",330,0.04507
332
+ "Madagascar","Analamanga",331,0.045
333
+ "Guinea Bissau","Quinara",332,0.04458
334
+ "Guinea","Guéckédou",333,0.04457
335
+ "Nigeria","Edo",334,0.04454
336
+ "Ivory Coast","Bafing",335,0.04434
337
+ "Guinea","Lola",336,0.04431
338
+ "Uganda","Jinja",337,0.04371
339
+ "Uganda","Kalungu",338,0.04362
340
+ "Malawi","Chikwawa",339,0.04338
341
+ "Togo","Kara",340,0.04331
342
+ "Rwanda","Northern",341,0.04328
343
+ "Kenya","Nyanza",342,0.04302
344
+ "Burkina Faso","Ioba",343,0.04293
345
+ "Malawi","Mzimba",344,0.0429
346
+ "Sierra Leone","Eastern",345,0.04257
347
+ "Burkina Faso","Loroum",346,0.04243
348
+ "Republic of the Congo","Kouilou",347,0.04224
349
+ "Uganda","Mityana",348,0.04217
350
+ "Ivory Coast","Cavally",349,0.04171
351
+ "Lesotho","Mohale's Hoek",350,0.04147
352
+ "Senegal","Kolda",351,0.04105
353
+ "Burkina Faso","Ziro",352,0.04104
354
+ "Rwanda","Western",353,0.04092
355
+ "Guinea","Kindia",354,0.04089
356
+ "Togo","Savanes",355,0.0408
357
+ "Somalia","Shabeellaha Hoose",356,0.04069
358
+ "Tunisia","Tozeur",357,0.04064
359
+ "Zimbabwe","Mashonaland Central",358,0.04056
360
+ "Sudan","White Nile",359,0.04054
361
+ "Benin","Zou",360,0.04041
362
+ "Ghana","Northern",361,0.0403
363
+ "Burkina Faso","Namentenga",362,0.03989
364
+ "Algeria","Djelfa",363,0.03967
365
+ "Sierra Leone","Southern",364,0.03911
366
+ "Somalia","Shabeellaha Dhexe",365,0.03903
367
+ "Uganda","Rukungiri",366,0.03893
368
+ "Uganda","Kanungu",367,0.03892
369
+ "Morocco","Oriental",368,0.03882
370
+ "Uganda","Isingiro",369,0.03849
371
+ "Benin","Alibori",370,0.03838
372
+ "Burundi","Cankuzo",371,0.03789
373
+ "Uganda","Kisoro",372,0.03765
374
+ "Namibia","Oshana",373,0.03745
375
+ "Uganda","Kamuli",374,0.03709
376
+ "Benin","Atakora",375,0.03703
377
+ "Cameroon","Ouest",376,0.03692
378
+ "Burkina Faso","Kossi",377,0.0363
379
+ "Uganda","Mbale",378,0.03614
380
+ "Uganda","Kabarole",379,0.03597
381
+ "Botswana","Kgatleng",380,0.03569
382
+ "Uganda","Ibanda",381,0.03555
383
+ "Kenya","Central",382,0.03547
384
+ "Mozambique","Maputo",383,0.03546
385
+ "Uganda","Bundibugyo",384,0.03534
386
+ "United Republic of Tanzania","Mtwara",385,0.03517
387
+ "Liberia","River Cess",386,0.03499
388
+ "Uganda","Luuka",387,0.03492
389
+ "Guinea Bissau","Bafatá",388,0.03448
390
+ "Nigeria","Adamawa",389,0.03443
391
+ "Democratic Republic of the Congo","Bas-Congo",390,0.03409
392
+ "Algeria","Laghouat",391,0.03403
393
+ "Mauritania","Guidimaka",392,0.03385
394
+ "Kenya","Western",393,0.0338
395
+ "Sudan","Sennar",394,0.03321
396
+ "Malawi","Nsanje",395,0.03313
397
+ "Togo","Plateaux",396,0.03294
398
+ "Nigeria","Rivers",397,0.03274
399
+ "Senegal","Saint-Louis",398,0.03272
400
+ "Equatorial Guinea","Centro Sur",399,0.03237
401
+ "Ethiopia","Tigray",400,0.03188
402
+ "Uganda","Kyenjojo",401,0.0317
403
+ "Zambia","Lusaka",402,0.03146
404
+ "Togo","Centre",403,0.03082
405
+ "Lesotho","Butha-Buthe",404,0.03072
406
+ "Sierra Leone","Northern",405,0.03063
407
+ "Mali","Kayes",406,0.03037
408
+ "Malawi","Likoma",407,0.03015
409
+ "Uganda","Buikwe",408,0.03009
410
+ "Nigeria","Kaduna",409,0.03004
411
+ "United Republic of Tanzania","Pwani",410,0.02998
412
+ "Uganda","Namayingo",411,0.02973
413
+ "Zimbabwe","Mashonaland West",412,0.0297
414
+ "Uganda","Sironko",413,0.02934
415
+ "Senegal","Tambacounda",414,0.02933
416
+ "Nigeria","Katsina",415,0.02931
417
+ "Zimbabwe","Manicaland",416,0.02905
418
+ "Lesotho","Quthing",417,0.02861
419
+ "Burkina Faso","Bougouriba",418,0.02854
420
+ "Uganda","Bukomansimbi",419,0.02818
421
+ "Guinea","Kérouané",420,0.02816
422
+ "Guinea","Télimélé",421,0.02814
423
+ "Egypt","Al Jizah",422,0.02811
424
+ "Guinea","Kissidougou",423,0.028
425
+ "Angola","Huambo",424,0.0279
426
+ "Malawi","Nkhotakota",425,0.02737
427
+ "Angola","Uíge",426,0.02726
428
+ "Nigeria","Niger",427,0.02724
429
+ "Uganda","Kayunga",428,0.02709
430
+ "Madagascar","Sava",429,0.02699
431
+ "United Republic of Tanzania","Geita",430,0.02591
432
+ "Guinea","Mali",431,0.0259
433
+ "Democratic Republic of the Congo","Kasaï-Occidental",432,0.02563
434
+ "Uganda","Masaka",433,0.02547
435
+ "Namibia","Omusati",434,0.02545
436
+ "Nigeria","Jigawa",435,0.02525
437
+ "Liberia","Sinoe",436,0.02517
438
+ "Uganda","Maracha",437,0.02498
439
+ "Burkina Faso","Noumbiel",438,0.02476
440
+ "Burkina Faso","Poni",439,0.02469
441
+ "Madagascar","Vakinankaratra",440,0.02448
442
+ "Uganda","Kyegegwa",441,0.02443
443
+ "Liberia","Grand Cape Mount",442,0.02432
444
+ "Egypt","Aswan",443,0.0241
445
+ "United Republic of Tanzania","Shinyanga",444,0.02396
446
+ "Burkina Faso","Yagha",445,0.02371
447
+ "Angola","Cuanza Norte",446,0.02369
448
+ "Malawi","Rumphi",447,0.02337
449
+ "Nigeria","Kwara",448,0.02323
450
+ "Nigeria","Borno",449,0.023
451
+ "United Republic of Tanzania","Mwanza",450,0.02295
452
+ "Guinea","Boke",451,0.02291
453
+ "Libya","Al Qubbah",452,0.02258
454
+ "Lesotho","Qacha's Nek",453,0.02245
455
+ "Ethiopia","Oromiya",454,0.02242
456
+ "Uganda","Buvuma",455,0.02228
457
+ "Ethiopia","Amhara",456,0.02213
458
+ "Burkina Faso","Gnagna",457,0.02208
459
+ "Ethiopia","Southern Nations, Nationalities and Peoples",458,0.02191
460
+ "Cameroon","Littoral",459,0.02129
461
+ "Namibia","Oshikoto",460,0.02129
462
+ "United Republic of Tanzania","Mbeya",461,0.02108
463
+ "Uganda","Mubende",462,0.02105
464
+ "Mauritania","Gorgol",463,0.02103
465
+ "Uganda","Kibale",464,0.02102
466
+ "Cameroon","Extrême-Nord",465,0.021
467
+ "Tunisia","Kebili",466,0.0209
468
+ "Uganda","Nakaseke",467,0.02083
469
+ "Uganda","Gomba",468,0.02082
470
+ "Madagascar","Bongolava",469,0.0208
471
+ "Mozambique","Cabo Delgado",470,0.02072
472
+ "Democratic Republic of the Congo","Kasaï-Oriental",471,0.02067
473
+ "Malawi","Mwanza",472,0.02062
474
+ "Malawi","Chitipa",473,0.02028
475
+ "Uganda","Kamwenge",474,0.02027
476
+ "Uganda","Rakai",475,0.02022
477
+ "United Republic of Tanzania","Rukwa",476,0.02017
478
+ "Angola","Cuanza Sul",477,0.02014
479
+ "Malawi","Nkhata Bay",478,0.02002
480
+ "Uganda","Buhweju",479,0.01997
481
+ "Nigeria","Bauchi",480,0.01976
482
+ "Nigeria","Delta",481,0.01976
483
+ "Uganda","Mbarara",482,0.0197
484
+ "Namibia","Caprivi",483,0.01959
485
+ "Uganda","Namutumba",484,0.01955
486
+ "Eritrea","Semenawi Keyih Bahri",485,0.01948
487
+ "Madagascar","Analanjirofo",486,0.01942
488
+ "Democratic Republic of the Congo","Bandundu",487,0.01926
489
+ "Madagascar","Sofia",488,0.01915
490
+ "Republic of the Congo","Brazzaville",489,0.0191
491
+ "United Republic of Tanzania","Kagera",490,0.01906
492
+ "Burkina Faso","Gourma",491,0.01902
493
+ "Malawi","Chitipa",492,0.0187
494
+ "Uganda","Kaliro",493,0.01857
495
+ "Nigeria","Kogi",494,0.0185
496
+ "Madagascar","Alaotra-Mangoro",495,0.01822
497
+ "Liberia","Maryland",496,0.01822
498
+ "Uganda","Lwengo",497,0.01795
499
+ "Eritrea","Gash Barka",498,0.0175
500
+ "Guinea","Faranah",499,0.01749
501
+ "Uganda","Moyo",500,0.01748
502
+ "Nigeria","Yobe",501,0.01747
503
+ "Morocco","Guelmim - Es-Semara",502,0.01739
504
+ "Somalia","Mudug",503,0.01737
505
+ "United Republic of Tanzania","Njombe",504,0.01733
506
+ "United Republic of Tanzania","Iringa",505,0.0173
507
+ "Guinea","Mamou",506,0.01726
508
+ "Zambia","Southern",507,0.01723
509
+ "Zambia","Central",508,0.01721
510
+ "Guinea","Koubia",509,0.01702
511
+ "Botswana","Southern",510,0.01693
512
+ "Senegal","Matam",511,0.01677
513
+ "Benin","Collines",512,0.01653
514
+ "United Republic of Tanzania","Tanga",513,0.01629
515
+ "Somalia","Galguduud",514,0.01625
516
+ "Uganda","Buyende",515,0.01621
517
+ "Mozambique","Nampula",516,0.0162
518
+ "Libya","Surt",517,0.01606
519
+ "Kenya","Coast",518,0.01596
520
+ "Uganda","Kiboga",519,0.01591
521
+ "Liberia","Lofa",520,0.01578
522
+ "Nigeria","Oyo",521,0.01578
523
+ "Guinea","Dabola",522,0.01578
524
+ "Liberia","Grand Gedeh",523,0.01568
525
+ "Uganda","Hoima",524,0.01567
526
+ "Somalia","Jubbada Dhexe",525,0.01564
527
+ "Uganda","Nebbi",526,0.01556
528
+ "Somalia","Hiiraan",527,0.01553
529
+ "Angola","Malanje",528,0.01551
530
+ "South Africa","Northern Cape",529,0.0155
531
+ "Lesotho","Mokhotlong",530,0.01548
532
+ "Uganda","Manafwa",531,0.01547
533
+ "Namibia","Kavango",532,0.01536
534
+ "Libya","Sabha",533,0.01518
535
+ "Nigeria","Federal Capital Territory",534,0.01515
536
+ "Liberia","River Gee",535,0.01514
537
+ "Algeria","El Oued",536,0.01469
538
+ "Democratic Republic of the Congo","Kinshasa City",537,0.01466
539
+ "Uganda","Kasese",538,0.01455
540
+ "United Republic of Tanzania","Dodoma",539,0.0145
541
+ "Uganda","Budaka",540,0.01449
542
+ "Somalia","Gedo",541,0.01436
543
+ "Madagascar","Haute Matsiatra",542,0.01434
544
+ "Guinea","Kouroussa",543,0.01424
545
+ "Lesotho","Thaba-Tseka",544,0.01416
546
+ "Nigeria","Nassarawa",545,0.01415
547
+ "United Republic of Tanzania","Kilimanjaro",546,0.01415
548
+ "Angola","Cunene",547,0.01403
549
+ "Zambia","Eastern",548,0.01402
550
+ "Guinea","Kankan",549,0.01393
551
+ "Nigeria","Plateau",550,0.01389
552
+ "Uganda","Kibuku",551,0.01385
553
+ "Nigeria","Ebonyi",552,0.01378
554
+ "United Republic of Tanzania","Kigoma",553,0.01373
555
+ "Zimbabwe","Midlands",554,0.01353
556
+ "Burkina Faso","Séno",555,0.01341
557
+ "Eritrea","Debub",556,0.01331
558
+ "Madagascar","Atsinanana",557,0.01298
559
+ "Democratic Republic of the Congo","Katanga",558,0.01286
560
+ "Libya","Misratah",559,0.01278
561
+ "Egypt","Janub Sina'",560,0.01272
562
+ "Burkina Faso","Soum",561,0.01265
563
+ "Angola","Bengo",562,0.01254
564
+ "Libya","Wadi al Hayaa",563,0.0125
565
+ "Sudan","River Nile",564,0.01231
566
+ "Madagascar","Diana",565,0.0123
567
+ "Madagascar","Amoron'i Mania",566,0.01228
568
+ "Uganda","Tororo",567,0.01227
569
+ "Nigeria","Cross River",568,0.01222
570
+ "Sudan","Gedarif",569,0.0122
571
+ "Uganda","Butaleja",570,0.012
572
+ "Djibouti","Arta",571,0.01187
573
+ "United Republic of Tanzania","Ruvuma",572,0.01185
574
+ "Gabon","Wouleu-Ntem",573,0.01177
575
+ "Sudan","Kassala",574,0.01174
576
+ "Uganda","Sembabule",575,0.01168
577
+ "Angola","Zaire",576,0.01164
578
+ "Uganda","Kumi",577,0.01154
579
+ "Uganda","Nakasongola",578,0.01152
580
+ "Libya","Mizdah",579,0.01144
581
+ "Botswana","Kweneng",580,0.01142
582
+ "Madagascar","Vatovavy-Fitovinany",581,0.01135
583
+ "Uganda","Zombo",582,0.01134
584
+ "Somalia","Bari",583,0.01127
585
+ "Niger","Tillabéri",584,0.01115
586
+ "Democratic Republic of the Congo","Sud-Kivu",585,0.01114
587
+ "Angola","Benguela",586,0.01113
588
+ "Tunisia","Tataouine",587,0.01113
589
+ "Liberia","Grand Kru",588,0.01107
590
+ "Burkina Faso","Komondjari",589,0.01102
591
+ "Madagascar","Anosy",590,0.01088
592
+ "Zimbabwe","Matabeleland South",591,0.01085
593
+ "Guinea Bissau","Gabú",592,0.01082
594
+ "Mali","Mopti",593,0.01077
595
+ "Uganda","Ntoroko",594,0.01055
596
+ "Algeria","Naâma",595,0.0103
597
+ "Djibouti","Ali Sabieh",596,0.01026
598
+ "Mauritania","Brakna",597,0.01025
599
+ "Uganda","Gulu",598,0.00999
600
+ "Niger","Tahoua",599,0.00998
601
+ "Namibia","Khomas",600,0.00995
602
+ "Botswana","Central",601,0.00987
603
+ "Burkina Faso","Oudalan",602,0.00985
604
+ "Uganda","Pallisa",603,0.00984
605
+ "Libya","Ghadamis",604,0.00981
606
+ "Gabon","Estuaire",605,0.00972
607
+ "Uganda","Kapchorwa",606,0.00958
608
+ "Uganda","Bulambuli",607,0.00953
609
+ "Guinea","Koundara",608,0.00953
610
+ "Cameroon","Centre",609,0.0095
611
+ "Cameroon","Nord-Ouest",610,0.00949
612
+ "Cameroon","Nord",611,0.00947
613
+ "Angola","Huíla",612,0.00932
614
+ "United Republic of Tanzania","Simiyu",613,0.00927
615
+ "Somalia","Bay",614,0.00925
616
+ "Angola","Bié",615,0.00917
617
+ "Djibouti","Tadjourah",616,0.00914
618
+ "Somalia","Nugaal",617,0.00912
619
+ "Burkina Faso","Tapoa",618,0.00906
620
+ "Chad","Logone Occidental",619,0.00904
621
+ "United Republic of Tanzania","Lindi",620,0.0089
622
+ "Democratic Republic of the Congo","Nord-Kivu",621,0.0088
623
+ "Namibia","Otjozondjupa",622,0.00873
624
+ "Burkina Faso","Kompienga",623,0.00859
625
+ "Mauritania","Trarza",624,0.00859
626
+ "Angola","Lunda Norte",625,0.00846
627
+ "Uganda","Lyantonde",626,0.00841
628
+ "United Republic of Tanzania","Tabora",627,0.00835
629
+ "Sudan","Blue Nile",628,0.00828
630
+ "Democratic Republic of the Congo","Maniema",629,0.00819
631
+ "United Republic of Tanzania","Morogoro",630,0.00817
632
+ "Uganda","Arua",631,0.008
633
+ "Libya","Al Butnan",632,0.00757
634
+ "Kenya","Rift Valley",633,0.00747
635
+ "Egypt","Matruh",634,0.00745
636
+ "United Republic of Tanzania","Mara",635,0.00743
637
+ "Mauritania","Assaba",636,0.00741
638
+ "Guinea Bissau","Bolama",637,0.00722
639
+ "Sudan","Southern Darfur",638,0.0072
640
+ "Madagascar","Atsimo-Andrefana",639,0.00711
641
+ "Nigeria","Taraba",640,0.00703
642
+ "Uganda","Bukedea",641,0.00696
643
+ "Zimbabwe","Matabeleland North",642,0.00683
644
+ "Madagascar","Ihorombe",643,0.00683
645
+ "Uganda","Kotido",644,0.00671
646
+ "Uganda","Bududa",645,0.00664
647
+ "Zambia","Luapula",646,0.00656
648
+ "Somalia","Bakool",647,0.00652
649
+ "Madagascar","Atsimo-Atsinanana",648,0.00645
650
+ "Central African Republic","Ombella-M'Poko",649,0.00642
651
+ "Algeria","El Bayadh",650,0.00641
652
+ "Uganda","Kyankwanzi",651,0.00641
653
+ "Algeria","Ghardaïa",652,0.00634
654
+ "Mozambique","Tete",653,0.00632
655
+ "Mozambique","Gaza",654,0.00631
656
+ "Uganda","Masindi",655,0.00626
657
+ "Egypt","Al Bahr al Ahmar",656,0.00626
658
+ "Gabon","Moyen-Ogooué",657,0.00618
659
+ "Guinea","Dinguiraye",658,0.00611
660
+ "Equatorial Guinea","Litoral",659,0.00602
661
+ "Ethiopia","Somali",660,0.00598
662
+ "Chad","Logone Oriental",661,0.00594
663
+ "Sudan","South Kordufan",662,0.00572
664
+ "Central African Republic","Ouham-Pendé",663,0.00566
665
+ "United Republic of Tanzania","Singida",664,0.00563
666
+ "Madagascar","Boeny",665,0.00562
667
+ "Nigeria","Benue",666,0.00558
668
+ "Guinea","Gaoual",667,0.00553
669
+ "Liberia","Gbapolu",668,0.00552
670
+ "Namibia","Omaheke",669,0.00549
671
+ "Zambia","North-Western",670,0.00539
672
+ "Namibia","Hardap",671,0.00533
673
+ "Madagascar","Androy",672,0.00528
674
+ "Central African Republic","Lobaye",673,0.00525
675
+ "Mozambique","Niassa",674,0.00522
676
+ "Namibia","Erongo",675,0.0051
677
+ "Uganda","Lamwo",676,0.00509
678
+ "Gabon","Haut-Ogooué",677,0.00508
679
+ "Sudan","North Kordufan",678,0.00504
680
+ "Ethiopia","Benshangul-Gumaz",679,0.00504
681
+ "Zimbabwe","Masvingo",680,0.00501
682
+ "Sudan","Eastern Darfur",681,0.00497
683
+ "Uganda","Amuru",682,0.00496
684
+ "Zambia","Western",683,0.00496
685
+ "Uganda","Buliisa",684,0.00494
686
+ "Mozambique","Zambezia",685,0.00492
687
+ "Uganda","Kiryandongo",686,0.00489
688
+ "Uganda","Rubirizi",687,0.00485
689
+ "Mozambique","Manica",688,0.00479
690
+ "Chad","Chari-Baguirmi",689,0.00477
691
+ "Equatorial Guinea","Bioko Sur",690,0.00469
692
+ "Mauritania","Tagant",691,0.00466
693
+ "Uganda","Adjumani",692,0.00445
694
+ "Sudan","Western Darfur",693,0.00442
695
+ "Republic of the Congo","Niari",694,0.00432
696
+ "Republic of the Congo","Cuvette",695,0.00431
697
+ "Uganda","Pader",696,0.00429
698
+ "Zambia","Northern",697,0.00428
699
+ "Uganda","Kaberamaido",698,0.00423
700
+ "Libya","Ajdabiya",699,0.0042
701
+ "Republic of the Congo","Plateaux",700,0.00417
702
+ "Algeria","Ouargla",701,0.00408
703
+ "Uganda","Napak",702,0.00406
704
+ "Uganda","Koboko",703,0.00403
705
+ "Uganda","Yumbe",704,0.00402
706
+ "Chad","Tandjilé",705,0.00402
707
+ "Algeria","Béchar",706,0.00401
708
+ "Sudan","Central Darfur",707,0.00395
709
+ "Republic of the Congo","Bouenza",708,0.00391
710
+ "Namibia","Karas",709,0.00391
711
+ "Uganda","Apac",710,0.00387
712
+ "Angola","Lunda Sul",711,0.00382
713
+ "Madagascar","Betsiboka",712,0.00377
714
+ "Botswana","North-West",713,0.00376
715
+ "Zambia","Muchinga",714,0.00367
716
+ "Kenya","Eastern",715,0.00357
717
+ "Libya","Ash Shati'",716,0.00356
718
+ "Mozambique","Inhambane",717,0.00354
719
+ "Mauritania","Hodh el Gharbi",718,0.00351
720
+ "Angola","Cuando Cubango",719,0.00348
721
+ "Egypt","Al Wadi at Jadid",720,0.00347
722
+ "United Republic of Tanzania","Manyara",721,0.00345
723
+ "Mozambique","Sofala",722,0.00343
724
+ "S. Sudan","Northern Bahr el Ghazal",723,0.00337
725
+ "United Republic of Tanzania","Arusha",724,0.00336
726
+ "Sudan","Northern",725,0.00328
727
+ "Ethiopia","Afar",726,0.00324
728
+ "Guinea","Tougué",727,0.00322
729
+ "Uganda","Kitgum",728,0.00312
730
+ "Sudan","Red Sea",729,0.00301
731
+ "S. Sudan","Upper Nile",730,0.00294
732
+ "Libya","Al Jufrah",731,0.00289
733
+ "S. Sudan","Central Equatoria",732,0.00285
734
+ "Chad","Hadjer-Lamis",733,0.00281
735
+ "Somalia","Jubbada Hoose",734,0.0028
736
+ "Uganda","Amolatar",735,0.00279
737
+ "Gabon","Ogooué-Maritime",736,0.00274
738
+ "Gabon","Ogooué-Ivindo",737,0.00269
739
+ "Republic of the Congo","Lékoumou",738,0.00268
740
+ "Djibouti","Obock",739,0.00262
741
+ "Central African Republic","Nana-Mambéré",740,0.00257
742
+ "Uganda","Kaabong",741,0.00254
743
+ "Central African Republic","Sangha-Mbaéré",742,0.00248
744
+ "Republic of the Congo","Cuvette-Ouest",743,0.00247
745
+ "Kenya","North-Eastern",744,0.00244
746
+ "Namibia","Kunene",745,0.00237
747
+ "United Republic of Tanzania","Katavi",746,0.00236
748
+ "Central African Republic","Kémo",747,0.00235
749
+ "S. Sudan","Unity",748,0.00235
750
+ "Gabon","Ngounié",749,0.0023
751
+ "Madagascar","Menabe",750,0.00228
752
+ "Angola","Namibe",751,0.0022
753
+ "Senegal","Kédougou",752,0.00219
754
+ "Botswana","Kgalagadi",753,0.00213
755
+ "Ethiopia","Gambela Peoples",754,0.0021
756
+ "Egypt","Shamal Sina'",755,0.00208
757
+ "Uganda","Serere",756,0.00197
758
+ "Chad","Guéra",757,0.00196
759
+ "Chad","Mayo-Kebbi Est",758,0.00194
760
+ "S. Sudan","Warrap",759,0.00182
761
+ "Algeria","Adrar",760,0.00181
762
+ "Chad","Mandoul",761,0.00176
763
+ "Republic of the Congo","Pool",762,0.00175
764
+ "Libya","Ghat",763,0.00173
765
+ "Libya","Murzuq",764,0.00173
766
+ "Central African Republic","Basse-Kotto",765,0.00169
767
+ "Sudan","North Darfur",766,0.00162
768
+ "Morocco","Laâyoune - Boujdour - Sakia El Hamra",767,0.00159
769
+ "Algeria","Illizi",768,0.00157
770
+ "Madagascar","Melaky",769,0.00154
771
+ "Mauritania","Adrar",770,0.00154
772
+ "Mauritania","Dakhlet Nouadhibou",771,0.00151
773
+ "Gabon","Nyanga",772,0.00149
774
+ "Uganda","Nwoya",773,0.00148
775
+ "Central African Republic","Ouham",774,0.00144
776
+ "Botswana","Ghanzi",775,0.00134
777
+ "Mauritania","Hodh ech Chargui",776,0.00129
778
+ "Cameroon","Adamaoua",777,0.00125
779
+ "Chad","Ouaddaï",778,0.00116
780
+ "Angola","Moxico",779,0.00114
781
+ "Central African Republic","Mbomou",780,0.00107
782
+ "Uganda","Kalangala",781,0.00106
783
+ "Cameroon","Sud-Ouest",782,0.00102
784
+ "S. Sudan","Jonglei",783,0.00102
785
+ "S. Sudan","Western Equatoria",784,0.00102
786
+ "Chad","Moyen-Chari",785,0.00097
787
+ "S. Sudan","Western Bahr el Ghazal",786,0.00092
788
+ "Mauritania","Inchiri",787,0.00091
789
+ "S. Sudan","Lakes",788,9e-04
790
+ "Mali","Gao",789,0.00089
791
+ "Djibouti","Dikhil",790,0.00086
792
+ "Chad","Ennedi",791,0.00084
793
+ "Chad","Sila",792,0.00079
794
+ "Democratic Republic of the Congo","Orientale",793,0.00074
795
+ "Chad","Salamat",794,0.00065
796
+ "S. Sudan","Eastern Equatoria",795,0.00065
797
+ "Mali","Timbuktu",796,0.00057
798
+ "Chad","Wadi Fira",797,0.00054
799
+ "Eritrea","Debubawi Keyih Bahri",798,0.00053
800
+ "Algeria","Tindouf",799,5e-04
801
+ "Uganda","Nakapiripirit",800,0.00049
802
+ "Central African Republic","Haut-Mbomou",801,0.00047
803
+ "Niger","Agadez",802,0.00046
804
+ "Chad","Batha",803,0.00045
805
+ "Niger","Diffa",804,0.00044
806
+ "Libya","Al Kufrah",805,0.00043
807
+ "Algeria","Tamanghasset",806,0.00043
808
+ "Uganda","Katakwi",807,0.00042
809
+ "Chad","Mayo-Kebbi Ouest",808,0.00038
810
+ "Mauritania","Tiris Zemmour",809,0.00036
811
+ "Chad","Tibesti",810,0.00036
812
+ "Morocco","Oued el Dahab",811,0.00025
813
+ "Cameroon","Sud",812,0.00023
814
+ "Chad","Borkou",813,2e-04
815
+ "Mali","Kidal",814,0.00019
816
+ "Central African Republic","Nana-Grébizi",815,0.00018
817
+ "Gabon","Ogooué-Lolo",816,0.00014
818
+ "Uganda","Oyam",817,0.00011
819
+ "Uganda","Ngora",818,1e-04
820
+ "Chad","Lac",819,8e-05
821
+ "Central African Republic","Vakaga",820,6e-05
822
+ "Central African Republic","Bamingui-Bangoran",821,5e-05
823
+ "Uganda","Soroti",822,1e-05
824
+ "Uganda","Moroto",823,0
825
+ "Djibouti","Djibouti",824,0
826
+ "Seychelles","Outer Islands",825,0
827
+ "Comoros","Moûhîlî",826,0
828
+ "Comoros","Andjouân",827,0
829
+ "Comoros","Andjazîdja",828,0
830
+ "Equatorial Guinea","Annobón",829,0
831
+ "Sao Tome and Principe","São Tomé",830,0
832
+ "Sao Tome and Principe","Príncipe",831,0
833
+ "Uganda","Lira",832,-4e-05
834
+ "Central African Republic","Ouaka",833,-7e-05
835
+ "Chad","Barh El Gazel",834,-1e-04
836
+ "Uganda","Amudat",835,-0.00012
837
+ "Uganda","Agago",836,-0.00013
838
+ "Central African Republic","Haute-Kotto",837,-0.00016
839
+ "Chad","Kanem",838,-0.00018
840
+ "Central African Republic","Mambéré-Kadéï",839,-0.00023
841
+ "Republic of the Congo","Likouala",840,-0.00059
842
+ "Uganda","Bukwa",841,-0.00062
843
+ "Republic of the Congo","Sangha",842,-0.00083
844
+ "Democratic Republic of the Congo","Équateur",843,-0.00156
845
+ "Uganda","Otuke",844,-0.0017
846
+ "Niger","Zinder",845,-0.00189
847
+ "Uganda","Abim",846,-0.00248
848
+ "Uganda","Kween",847,-0.00263
849
+ "Uganda","Dokolo",848,-0.00416
850
+ "Niger","Maradi",849,-0.00542
851
+ "Uganda","Alebtong",850,-0.00578
852
+ "Uganda","Kole",851,-0.00593
853
+ "Cameroon","Est",852,-0.00641
854
+ "Uganda","Amuria",853,-0.00875
855
+ "Nigeria","Bayelsa",854,-0.00919
856
+ "Benin","Littoral",855,-0.07788
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ shiny
2
+ shiny
3
+ shinywidgets
4
+ ipyleaflet
5
+ ipywidgets
6
+ numpy
7
+ matplotlib
8
+ pandas
9
+ plotly
10
+ rasterio
11
+ geopandas
12
+ plotnine
13
+ palettable
14
+
residual_by_country.csv ADDED
The diff for this file is too large to render. See raw diff
 
residual_plot.ipynb ADDED
@@ -0,0 +1,754 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "Intel MKL WARNING: Support of Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) enabled only processors has been deprecated. Intel oneAPI Math Kernel Library 2025.0 will require Intel(R) Advanced Vector Extensions (Intel(R) AVX) instructions.\n",
13
+ "Intel MKL WARNING: Support of Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) enabled only processors has been deprecated. Intel oneAPI Math Kernel Library 2025.0 will require Intel(R) Advanced Vector Extensions (Intel(R) AVX) instructions.\n"
14
+ ]
15
+ },
16
+ {
17
+ "data": {
18
+ "text/html": [
19
+ "<div>\n",
20
+ "<style scoped>\n",
21
+ " .dataframe tbody tr th:only-of-type {\n",
22
+ " vertical-align: middle;\n",
23
+ " }\n",
24
+ "\n",
25
+ " .dataframe tbody tr th {\n",
26
+ " vertical-align: top;\n",
27
+ " }\n",
28
+ "\n",
29
+ " .dataframe thead th {\n",
30
+ " text-align: right;\n",
31
+ " }\n",
32
+ "</style>\n",
33
+ "<table border=\"1\" class=\"dataframe\">\n",
34
+ " <thead>\n",
35
+ " <tr style=\"text-align: right;\">\n",
36
+ " <th></th>\n",
37
+ " <th>Unnamed: 0</th>\n",
38
+ " <th>RegionID</th>\n",
39
+ " <th>ClusterID</th>\n",
40
+ " <th>lon</th>\n",
41
+ " <th>lat</th>\n",
42
+ " <th>country.code.ISO.3166.alpha.3</th>\n",
43
+ " <th>year.of.interview</th>\n",
44
+ " <th>month.of.interview</th>\n",
45
+ " <th>rural</th>\n",
46
+ " <th>country</th>\n",
47
+ " <th>continent</th>\n",
48
+ " <th>iwi_mean</th>\n",
49
+ " <th>iwi_var</th>\n",
50
+ " <th>iwi_skewness</th>\n",
51
+ " <th>iwi_kurtosis</th>\n",
52
+ " <th>geometry</th>\n",
53
+ " <th>date</th>\n",
54
+ " </tr>\n",
55
+ " </thead>\n",
56
+ " <tbody>\n",
57
+ " <tr>\n",
58
+ " <th>0</th>\n",
59
+ " <td>1</td>\n",
60
+ " <td>AO.Estavel Mesoendemica</td>\n",
61
+ " <td>AO.Estavel Mesoendemica.51.1</td>\n",
62
+ " <td>13.859255</td>\n",
63
+ " <td>-12.169283</td>\n",
64
+ " <td>24</td>\n",
65
+ " <td>2006</td>\n",
66
+ " <td>12</td>\n",
67
+ " <td>Urban</td>\n",
68
+ " <td>Angola</td>\n",
69
+ " <td>Africa</td>\n",
70
+ " <td>0.632356</td>\n",
71
+ " <td>51.530785</td>\n",
72
+ " <td>-1.136435</td>\n",
73
+ " <td>4.376306</td>\n",
74
+ " <td>POINT (13.85925 -12.16928)</td>\n",
75
+ " <td>2006-12-15</td>\n",
76
+ " </tr>\n",
77
+ " <tr>\n",
78
+ " <th>1</th>\n",
79
+ " <td>2</td>\n",
80
+ " <td>AO.Estavel Mesoendemica</td>\n",
81
+ " <td>AO.Estavel Mesoendemica.51.1</td>\n",
82
+ " <td>13.859255</td>\n",
83
+ " <td>-12.169283</td>\n",
84
+ " <td>24</td>\n",
85
+ " <td>2006</td>\n",
86
+ " <td>11</td>\n",
87
+ " <td>Urban</td>\n",
88
+ " <td>Angola</td>\n",
89
+ " <td>Africa</td>\n",
90
+ " <td>0.632356</td>\n",
91
+ " <td>51.530785</td>\n",
92
+ " <td>-1.136435</td>\n",
93
+ " <td>4.376306</td>\n",
94
+ " <td>POINT (13.85925 -12.16928)</td>\n",
95
+ " <td>2006-11-15</td>\n",
96
+ " </tr>\n",
97
+ " <tr>\n",
98
+ " <th>2</th>\n",
99
+ " <td>3</td>\n",
100
+ " <td>AO.Estavel Mesoendemica</td>\n",
101
+ " <td>AO.Estavel Mesoendemica.51.2</td>\n",
102
+ " <td>13.845458</td>\n",
103
+ " <td>-12.167753</td>\n",
104
+ " <td>24</td>\n",
105
+ " <td>2006</td>\n",
106
+ " <td>11</td>\n",
107
+ " <td>Urban</td>\n",
108
+ " <td>Angola</td>\n",
109
+ " <td>Africa</td>\n",
110
+ " <td>0.596262</td>\n",
111
+ " <td>99.839389</td>\n",
112
+ " <td>-1.121912</td>\n",
113
+ " <td>3.897659</td>\n",
114
+ " <td>POINT (13.84546 -12.16775)</td>\n",
115
+ " <td>2006-11-15</td>\n",
116
+ " </tr>\n",
117
+ " <tr>\n",
118
+ " <th>3</th>\n",
119
+ " <td>4</td>\n",
120
+ " <td>AO.Estavel Mesoendemica</td>\n",
121
+ " <td>AO.Estavel Mesoendemica.51.3</td>\n",
122
+ " <td>13.607121</td>\n",
123
+ " <td>-12.747312</td>\n",
124
+ " <td>24</td>\n",
125
+ " <td>2006</td>\n",
126
+ " <td>11</td>\n",
127
+ " <td>Urban</td>\n",
128
+ " <td>Angola</td>\n",
129
+ " <td>Africa</td>\n",
130
+ " <td>0.640985</td>\n",
131
+ " <td>96.416849</td>\n",
132
+ " <td>-0.199522</td>\n",
133
+ " <td>2.731744</td>\n",
134
+ " <td>POINT (13.60712 -12.74731)</td>\n",
135
+ " <td>2006-11-15</td>\n",
136
+ " </tr>\n",
137
+ " <tr>\n",
138
+ " <th>4</th>\n",
139
+ " <td>5</td>\n",
140
+ " <td>AO.Estavel Mesoendemica</td>\n",
141
+ " <td>AO.Estavel Mesoendemica.51.4</td>\n",
142
+ " <td>14.060841</td>\n",
143
+ " <td>-11.502919</td>\n",
144
+ " <td>24</td>\n",
145
+ " <td>2006</td>\n",
146
+ " <td>12</td>\n",
147
+ " <td>Urban</td>\n",
148
+ " <td>Angola</td>\n",
149
+ " <td>Africa</td>\n",
150
+ " <td>0.505828</td>\n",
151
+ " <td>359.699498</td>\n",
152
+ " <td>-0.507887</td>\n",
153
+ " <td>2.371137</td>\n",
154
+ " <td>POINT (14.06084 -11.50292)</td>\n",
155
+ " <td>2006-12-15</td>\n",
156
+ " </tr>\n",
157
+ " <tr>\n",
158
+ " <th>...</th>\n",
159
+ " <td>...</td>\n",
160
+ " <td>...</td>\n",
161
+ " <td>...</td>\n",
162
+ " <td>...</td>\n",
163
+ " <td>...</td>\n",
164
+ " <td>...</td>\n",
165
+ " <td>...</td>\n",
166
+ " <td>...</td>\n",
167
+ " <td>...</td>\n",
168
+ " <td>...</td>\n",
169
+ " <td>...</td>\n",
170
+ " <td>...</td>\n",
171
+ " <td>...</td>\n",
172
+ " <td>...</td>\n",
173
+ " <td>...</td>\n",
174
+ " <td>...</td>\n",
175
+ " <td>...</td>\n",
176
+ " </tr>\n",
177
+ " <tr>\n",
178
+ " <th>66024</th>\n",
179
+ " <td>66025</td>\n",
180
+ " <td>ZM.Lusaka</td>\n",
181
+ " <td>ZM.Lusaka.71.541</td>\n",
182
+ " <td>28.370067</td>\n",
183
+ " <td>-15.416081</td>\n",
184
+ " <td>894</td>\n",
185
+ " <td>2018</td>\n",
186
+ " <td>9</td>\n",
187
+ " <td>Urban</td>\n",
188
+ " <td>Zambia</td>\n",
189
+ " <td>Africa</td>\n",
190
+ " <td>0.530495</td>\n",
191
+ " <td>201.920771</td>\n",
192
+ " <td>-0.296764</td>\n",
193
+ " <td>3.270728</td>\n",
194
+ " <td>POINT (28.37007 -15.41608)</td>\n",
195
+ " <td>2018-09-15</td>\n",
196
+ " </tr>\n",
197
+ " <tr>\n",
198
+ " <th>66025</th>\n",
199
+ " <td>66026</td>\n",
200
+ " <td>ZM.Muchinga</td>\n",
201
+ " <td>ZM.Muchinga.71.542</td>\n",
202
+ " <td>32.946955</td>\n",
203
+ " <td>-11.150453</td>\n",
204
+ " <td>894</td>\n",
205
+ " <td>2018</td>\n",
206
+ " <td>9</td>\n",
207
+ " <td>Rural</td>\n",
208
+ " <td>Zambia</td>\n",
209
+ " <td>Africa</td>\n",
210
+ " <td>0.179347</td>\n",
211
+ " <td>70.917266</td>\n",
212
+ " <td>0.186924</td>\n",
213
+ " <td>2.157706</td>\n",
214
+ " <td>POINT (32.94696 -11.15045)</td>\n",
215
+ " <td>2018-09-15</td>\n",
216
+ " </tr>\n",
217
+ " <tr>\n",
218
+ " <th>66026</th>\n",
219
+ " <td>66027</td>\n",
220
+ " <td>ZM.Lusaka</td>\n",
221
+ " <td>ZM.Lusaka.71.543</td>\n",
222
+ " <td>28.299570</td>\n",
223
+ " <td>-15.769918</td>\n",
224
+ " <td>894</td>\n",
225
+ " <td>2018</td>\n",
226
+ " <td>12</td>\n",
227
+ " <td>Rural</td>\n",
228
+ " <td>Zambia</td>\n",
229
+ " <td>Africa</td>\n",
230
+ " <td>0.340004</td>\n",
231
+ " <td>305.619875</td>\n",
232
+ " <td>0.645395</td>\n",
233
+ " <td>2.523493</td>\n",
234
+ " <td>POINT (28.29957 -15.76992)</td>\n",
235
+ " <td>2018-12-15</td>\n",
236
+ " </tr>\n",
237
+ " <tr>\n",
238
+ " <th>66027</th>\n",
239
+ " <td>66028</td>\n",
240
+ " <td>ZM.Central</td>\n",
241
+ " <td>ZM.Central.71.544</td>\n",
242
+ " <td>30.039495</td>\n",
243
+ " <td>-12.876392</td>\n",
244
+ " <td>894</td>\n",
245
+ " <td>2018</td>\n",
246
+ " <td>9</td>\n",
247
+ " <td>Rural</td>\n",
248
+ " <td>Zambia</td>\n",
249
+ " <td>Africa</td>\n",
250
+ " <td>0.135886</td>\n",
251
+ " <td>59.794252</td>\n",
252
+ " <td>0.061590</td>\n",
253
+ " <td>1.959555</td>\n",
254
+ " <td>POINT (30.0395 -12.87639)</td>\n",
255
+ " <td>2018-09-15</td>\n",
256
+ " </tr>\n",
257
+ " <tr>\n",
258
+ " <th>66028</th>\n",
259
+ " <td>66029</td>\n",
260
+ " <td>ZM.Muchinga</td>\n",
261
+ " <td>ZM.Muchinga.71.545</td>\n",
262
+ " <td>32.608905</td>\n",
263
+ " <td>-9.421954</td>\n",
264
+ " <td>894</td>\n",
265
+ " <td>2018</td>\n",
266
+ " <td>12</td>\n",
267
+ " <td>Rural</td>\n",
268
+ " <td>Zambia</td>\n",
269
+ " <td>Africa</td>\n",
270
+ " <td>0.205844</td>\n",
271
+ " <td>261.427106</td>\n",
272
+ " <td>1.139779</td>\n",
273
+ " <td>3.475082</td>\n",
274
+ " <td>POINT (32.6089 -9.42195)</td>\n",
275
+ " <td>2018-12-15</td>\n",
276
+ " </tr>\n",
277
+ " </tbody>\n",
278
+ "</table>\n",
279
+ "<p>65655 rows × 17 columns</p>\n",
280
+ "</div>"
281
+ ],
282
+ "text/plain": [
283
+ " Unnamed: 0 RegionID ClusterID \\\n",
284
+ "0 1 AO.Estavel Mesoendemica AO.Estavel Mesoendemica.51.1 \n",
285
+ "1 2 AO.Estavel Mesoendemica AO.Estavel Mesoendemica.51.1 \n",
286
+ "2 3 AO.Estavel Mesoendemica AO.Estavel Mesoendemica.51.2 \n",
287
+ "3 4 AO.Estavel Mesoendemica AO.Estavel Mesoendemica.51.3 \n",
288
+ "4 5 AO.Estavel Mesoendemica AO.Estavel Mesoendemica.51.4 \n",
289
+ "... ... ... ... \n",
290
+ "66024 66025 ZM.Lusaka ZM.Lusaka.71.541 \n",
291
+ "66025 66026 ZM.Muchinga ZM.Muchinga.71.542 \n",
292
+ "66026 66027 ZM.Lusaka ZM.Lusaka.71.543 \n",
293
+ "66027 66028 ZM.Central ZM.Central.71.544 \n",
294
+ "66028 66029 ZM.Muchinga ZM.Muchinga.71.545 \n",
295
+ "\n",
296
+ " lon lat country.code.ISO.3166.alpha.3 year.of.interview \\\n",
297
+ "0 13.859255 -12.169283 24 2006 \n",
298
+ "1 13.859255 -12.169283 24 2006 \n",
299
+ "2 13.845458 -12.167753 24 2006 \n",
300
+ "3 13.607121 -12.747312 24 2006 \n",
301
+ "4 14.060841 -11.502919 24 2006 \n",
302
+ "... ... ... ... ... \n",
303
+ "66024 28.370067 -15.416081 894 2018 \n",
304
+ "66025 32.946955 -11.150453 894 2018 \n",
305
+ "66026 28.299570 -15.769918 894 2018 \n",
306
+ "66027 30.039495 -12.876392 894 2018 \n",
307
+ "66028 32.608905 -9.421954 894 2018 \n",
308
+ "\n",
309
+ " month.of.interview rural country continent iwi_mean iwi_var \\\n",
310
+ "0 12 Urban Angola Africa 0.632356 51.530785 \n",
311
+ "1 11 Urban Angola Africa 0.632356 51.530785 \n",
312
+ "2 11 Urban Angola Africa 0.596262 99.839389 \n",
313
+ "3 11 Urban Angola Africa 0.640985 96.416849 \n",
314
+ "4 12 Urban Angola Africa 0.505828 359.699498 \n",
315
+ "... ... ... ... ... ... ... \n",
316
+ "66024 9 Urban Zambia Africa 0.530495 201.920771 \n",
317
+ "66025 9 Rural Zambia Africa 0.179347 70.917266 \n",
318
+ "66026 12 Rural Zambia Africa 0.340004 305.619875 \n",
319
+ "66027 9 Rural Zambia Africa 0.135886 59.794252 \n",
320
+ "66028 12 Rural Zambia Africa 0.205844 261.427106 \n",
321
+ "\n",
322
+ " iwi_skewness iwi_kurtosis geometry date \n",
323
+ "0 -1.136435 4.376306 POINT (13.85925 -12.16928) 2006-12-15 \n",
324
+ "1 -1.136435 4.376306 POINT (13.85925 -12.16928) 2006-11-15 \n",
325
+ "2 -1.121912 3.897659 POINT (13.84546 -12.16775) 2006-11-15 \n",
326
+ "3 -0.199522 2.731744 POINT (13.60712 -12.74731) 2006-11-15 \n",
327
+ "4 -0.507887 2.371137 POINT (14.06084 -11.50292) 2006-12-15 \n",
328
+ "... ... ... ... ... \n",
329
+ "66024 -0.296764 3.270728 POINT (28.37007 -15.41608) 2018-09-15 \n",
330
+ "66025 0.186924 2.157706 POINT (32.94696 -11.15045) 2018-09-15 \n",
331
+ "66026 0.645395 2.523493 POINT (28.29957 -15.76992) 2018-12-15 \n",
332
+ "66027 0.061590 1.959555 POINT (30.0395 -12.87639) 2018-09-15 \n",
333
+ "66028 1.139779 3.475082 POINT (32.6089 -9.42195) 2018-12-15 \n",
334
+ "\n",
335
+ "[65655 rows x 17 columns]"
336
+ ]
337
+ },
338
+ "execution_count": 1,
339
+ "metadata": {},
340
+ "output_type": "execute_result"
341
+ }
342
+ ],
343
+ "source": [
344
+ "import numpy as np \n",
345
+ "import pandas as pd \n",
346
+ "import json \n",
347
+ "from ipyleaflet import Map, GeoJSON,Heatmap\n",
348
+ "import matplotlib.pyplot as plt \n",
349
+ "from fetch_data import fetch_data\n",
350
+ "import geopandas as gp \n",
351
+ "import seaborn as sns \n",
352
+ "\n",
353
+ "\n",
354
+ "geo_json_data = fetch_data(\"data/ground_truth/ground_truth.geojson\")\n",
355
+ "\n",
356
+ "ground_truth_df = fetch_data('data/ground_truth/ground_truth_R.csv')\n",
357
+ "\n",
358
+ "gdf = gp.GeoDataFrame(ground_truth_df, geometry=gp.points_from_xy(ground_truth_df['lon'], ground_truth_df['lat']), crs=\"EPSG:4326\")\n",
359
+ "gdf['iwi_mean'] = gdf['iwi_mean']/100 #scale IWIs by 100 \n",
360
+ "gdf = gdf[gdf['month.of.interview'] > 0]\n",
361
+ "gdf['date'] = pd.to_datetime(dict(year = gdf['year.of.interview'], month = gdf['month.of.interview'], day = 15))\n",
362
+ "\n",
363
+ "# fiilter data by the start and end year for a single band \n",
364
+ "def create_band(gdf, start, end):\n",
365
+ " gdf = gdf[['country','year.of.interview','date','iwi_mean','geometry']]\n",
366
+ " return gdf[(gdf['year.of.interview'] >= start) & (gdf['year.of.interview'] <= end)]\n",
367
+ "\n",
368
+ "# create a dictionary storing each band's data based on their year range \n",
369
+ "empty_dict = {}\n",
370
+ "def create_dict(ground_truth_dict):\n",
371
+ " start = 1990 \n",
372
+ " for i in range(1,11): \n",
373
+ " end = start +2 \n",
374
+ " band = create_band(gdf, start, end)\n",
375
+ " ground_truth_dict[f'band_{i}'] = band \n",
376
+ " temp = end \n",
377
+ " start = temp +1 \n",
378
+ " return ground_truth_dict\n",
379
+ "\n",
380
+ "ground_truth_dict = create_dict(empty_dict)\n",
381
+ "\n",
382
+ "gdf"
383
+ ]
384
+ },
385
+ {
386
+ "cell_type": "code",
387
+ "execution_count": 2,
388
+ "metadata": {},
389
+ "outputs": [
390
+ {
391
+ "name": "stdout",
392
+ "output_type": "stream",
393
+ "text": [
394
+ "Band 1 upload complete!\n",
395
+ "Band 2 upload complete!\n",
396
+ "Band 3 upload complete!\n",
397
+ "Band 4 upload complete!\n",
398
+ "Band 5 upload complete!\n",
399
+ "Band 6 upload complete!\n",
400
+ "Band 7 upload complete!\n",
401
+ "Band 8 upload complete!\n",
402
+ "Band 9 upload complete!\n",
403
+ "Band 10 upload complete!\n"
404
+ ]
405
+ }
406
+ ],
407
+ "source": [
408
+ "#load data for each band \n",
409
+ "band_dict= {}\n",
410
+ "for i in range(1,11): \n",
411
+ " band_json = fetch_data(f'data/band_geojson/band_{i}.geojson')\n",
412
+ " band_dict[f'band_{i}'] = band_json\n",
413
+ " print(f'Band {i} upload complete!')\n",
414
+ "\n",
415
+ "with open('data/band_json.geojson', 'w') as w:\n",
416
+ " json.dump(band_dict, w, indent=4)\n",
417
+ "\n"
418
+ ]
419
+ },
420
+ {
421
+ "cell_type": "code",
422
+ "execution_count": 3,
423
+ "metadata": {},
424
+ "outputs": [
425
+ {
426
+ "name": "stdout",
427
+ "output_type": "stream",
428
+ "text": [
429
+ "Processing Band 1...\n",
430
+ "Processing Band 2...\n",
431
+ "Processing Band 3...\n",
432
+ "Processing Band 4...\n",
433
+ "Processing Band 5...\n",
434
+ "Processing Band 6...\n",
435
+ "Processing Band 7...\n",
436
+ "Processing Band 8...\n",
437
+ "Processing Band 9...\n",
438
+ "Processing Band 10...\n"
439
+ ]
440
+ },
441
+ {
442
+ "data": {
443
+ "text/html": [
444
+ "<div>\n",
445
+ "<style scoped>\n",
446
+ " .dataframe tbody tr th:only-of-type {\n",
447
+ " vertical-align: middle;\n",
448
+ " }\n",
449
+ "\n",
450
+ " .dataframe tbody tr th {\n",
451
+ " vertical-align: top;\n",
452
+ " }\n",
453
+ "\n",
454
+ " .dataframe thead th {\n",
455
+ " text-align: right;\n",
456
+ " }\n",
457
+ "</style>\n",
458
+ "<table border=\"1\" class=\"dataframe\">\n",
459
+ " <thead>\n",
460
+ " <tr style=\"text-align: right;\">\n",
461
+ " <th></th>\n",
462
+ " <th>country</th>\n",
463
+ " <th>year.of.interview</th>\n",
464
+ " <th>date</th>\n",
465
+ " <th>iwi_mean</th>\n",
466
+ " <th>geometry</th>\n",
467
+ " <th>index_right</th>\n",
468
+ " <th>iwi_pred</th>\n",
469
+ " <th>residual</th>\n",
470
+ " </tr>\n",
471
+ " </thead>\n",
472
+ " <tbody>\n",
473
+ " <tr>\n",
474
+ " <th>2364</th>\n",
475
+ " <td>Cameroon</td>\n",
476
+ " <td>1991</td>\n",
477
+ " <td>1991-08-15</td>\n",
478
+ " <td>0.210099</td>\n",
479
+ " <td>POINT (14.9 12.3833)</td>\n",
480
+ " <td>30259</td>\n",
481
+ " <td>0.239990</td>\n",
482
+ " <td>0.029891</td>\n",
483
+ " </tr>\n",
484
+ " <tr>\n",
485
+ " <th>2365</th>\n",
486
+ " <td>Cameroon</td>\n",
487
+ " <td>1991</td>\n",
488
+ " <td>1991-07-15</td>\n",
489
+ " <td>0.254330</td>\n",
490
+ " <td>POINT (14.15 11.05)</td>\n",
491
+ " <td>37563</td>\n",
492
+ " <td>0.240723</td>\n",
493
+ " <td>-0.013607</td>\n",
494
+ " </tr>\n",
495
+ " <tr>\n",
496
+ " <th>2366</th>\n",
497
+ " <td>Cameroon</td>\n",
498
+ " <td>1991</td>\n",
499
+ " <td>1991-07-15</td>\n",
500
+ " <td>0.174986</td>\n",
501
+ " <td>POINT (14.15 10.8667)</td>\n",
502
+ " <td>38528</td>\n",
503
+ " <td>0.166138</td>\n",
504
+ " <td>-0.008848</td>\n",
505
+ " </tr>\n",
506
+ " <tr>\n",
507
+ " <th>2367</th>\n",
508
+ " <td>Cameroon</td>\n",
509
+ " <td>1991</td>\n",
510
+ " <td>1991-07-15</td>\n",
511
+ " <td>0.174986</td>\n",
512
+ " <td>POINT (13.8833 10.8667)</td>\n",
513
+ " <td>38527</td>\n",
514
+ " <td>0.150146</td>\n",
515
+ " <td>-0.024839</td>\n",
516
+ " </tr>\n",
517
+ " <tr>\n",
518
+ " <th>2368</th>\n",
519
+ " <td>Cameroon</td>\n",
520
+ " <td>1991</td>\n",
521
+ " <td>1991-07-15</td>\n",
522
+ " <td>0.178511</td>\n",
523
+ " <td>POINT (13.8 10.75)</td>\n",
524
+ " <td>39175</td>\n",
525
+ " <td>0.179443</td>\n",
526
+ " <td>0.000933</td>\n",
527
+ " </tr>\n",
528
+ " <tr>\n",
529
+ " <th>...</th>\n",
530
+ " <td>...</td>\n",
531
+ " <td>...</td>\n",
532
+ " <td>...</td>\n",
533
+ " <td>...</td>\n",
534
+ " <td>...</td>\n",
535
+ " <td>...</td>\n",
536
+ " <td>...</td>\n",
537
+ " <td>...</td>\n",
538
+ " </tr>\n",
539
+ " <tr>\n",
540
+ " <th>66019</th>\n",
541
+ " <td>Zambia</td>\n",
542
+ " <td>2018</td>\n",
543
+ " <td>2018-10-15</td>\n",
544
+ " <td>0.348706</td>\n",
545
+ " <td>POINT (28.09312 -15.34204)</td>\n",
546
+ " <td>108281</td>\n",
547
+ " <td>0.504883</td>\n",
548
+ " <td>0.156177</td>\n",
549
+ " </tr>\n",
550
+ " <tr>\n",
551
+ " <th>66022</th>\n",
552
+ " <td>Zambia</td>\n",
553
+ " <td>2018</td>\n",
554
+ " <td>2018-08-15</td>\n",
555
+ " <td>0.547186</td>\n",
556
+ " <td>POINT (28.34869 -15.39249)</td>\n",
557
+ " <td>108374</td>\n",
558
+ " <td>0.556641</td>\n",
559
+ " <td>0.009455</td>\n",
560
+ " </tr>\n",
561
+ " <tr>\n",
562
+ " <th>66023</th>\n",
563
+ " <td>Zambia</td>\n",
564
+ " <td>2018</td>\n",
565
+ " <td>2018-08-15</td>\n",
566
+ " <td>0.530495</td>\n",
567
+ " <td>POINT (28.37007 -15.41608)</td>\n",
568
+ " <td>108455</td>\n",
569
+ " <td>0.439209</td>\n",
570
+ " <td>-0.091286</td>\n",
571
+ " </tr>\n",
572
+ " <tr>\n",
573
+ " <th>66024</th>\n",
574
+ " <td>Zambia</td>\n",
575
+ " <td>2018</td>\n",
576
+ " <td>2018-09-15</td>\n",
577
+ " <td>0.530495</td>\n",
578
+ " <td>POINT (28.37007 -15.41608)</td>\n",
579
+ " <td>108455</td>\n",
580
+ " <td>0.439209</td>\n",
581
+ " <td>-0.091286</td>\n",
582
+ " </tr>\n",
583
+ " <tr>\n",
584
+ " <th>66028</th>\n",
585
+ " <td>Zambia</td>\n",
586
+ " <td>2018</td>\n",
587
+ " <td>2018-12-15</td>\n",
588
+ " <td>0.205844</td>\n",
589
+ " <td>POINT (32.6089 -9.42195)</td>\n",
590
+ " <td>101268</td>\n",
591
+ " <td>0.182495</td>\n",
592
+ " <td>-0.023349</td>\n",
593
+ " </tr>\n",
594
+ " </tbody>\n",
595
+ "</table>\n",
596
+ "<p>52102 rows × 8 columns</p>\n",
597
+ "</div>"
598
+ ],
599
+ "text/plain": [
600
+ " country year.of.interview date iwi_mean \\\n",
601
+ "2364 Cameroon 1991 1991-08-15 0.210099 \n",
602
+ "2365 Cameroon 1991 1991-07-15 0.254330 \n",
603
+ "2366 Cameroon 1991 1991-07-15 0.174986 \n",
604
+ "2367 Cameroon 1991 1991-07-15 0.174986 \n",
605
+ "2368 Cameroon 1991 1991-07-15 0.178511 \n",
606
+ "... ... ... ... ... \n",
607
+ "66019 Zambia 2018 2018-10-15 0.348706 \n",
608
+ "66022 Zambia 2018 2018-08-15 0.547186 \n",
609
+ "66023 Zambia 2018 2018-08-15 0.530495 \n",
610
+ "66024 Zambia 2018 2018-09-15 0.530495 \n",
611
+ "66028 Zambia 2018 2018-12-15 0.205844 \n",
612
+ "\n",
613
+ " geometry index_right iwi_pred residual \n",
614
+ "2364 POINT (14.9 12.3833) 30259 0.239990 0.029891 \n",
615
+ "2365 POINT (14.15 11.05) 37563 0.240723 -0.013607 \n",
616
+ "2366 POINT (14.15 10.8667) 38528 0.166138 -0.008848 \n",
617
+ "2367 POINT (13.8833 10.8667) 38527 0.150146 -0.024839 \n",
618
+ "2368 POINT (13.8 10.75) 39175 0.179443 0.000933 \n",
619
+ "... ... ... ... ... \n",
620
+ "66019 POINT (28.09312 -15.34204) 108281 0.504883 0.156177 \n",
621
+ "66022 POINT (28.34869 -15.39249) 108374 0.556641 0.009455 \n",
622
+ "66023 POINT (28.37007 -15.41608) 108455 0.439209 -0.091286 \n",
623
+ "66024 POINT (28.37007 -15.41608) 108455 0.439209 -0.091286 \n",
624
+ "66028 POINT (32.6089 -9.42195) 101268 0.182495 -0.023349 \n",
625
+ "\n",
626
+ "[52102 rows x 8 columns]"
627
+ ]
628
+ },
629
+ "execution_count": 3,
630
+ "metadata": {},
631
+ "output_type": "execute_result"
632
+ }
633
+ ],
634
+ "source": [
635
+ "#load all data at once and perform spatial join for each band \n",
636
+ "with open('data/band_json.geojson') as d: \n",
637
+ " band_data = json.load(d)\n",
638
+ "\n",
639
+ "joined_gdf_list = []\n",
640
+ "for i in range(1, 11):\n",
641
+ " print(f'Processing Band {i}...')\n",
642
+ " pred_gdf = gp.GeoDataFrame.from_features(band_data[f'band_{i}'], crs = \"EPSG:4326\")\n",
643
+ " pred_gdf = pred_gdf.rename(columns={'IWI':'iwi_pred'})\n",
644
+ "\n",
645
+ " joined_gdf = gp.sjoin(ground_truth_dict[f'band_{i}'], pred_gdf, predicate='intersects')\n",
646
+ " joined_gdf['residual'] = joined_gdf['iwi_pred'] - joined_gdf['iwi_mean']\n",
647
+ " joined_gdf_list.append(joined_gdf)\n",
648
+ "\n",
649
+ "\n",
650
+ "#join all the dataframes together into a single dataframe \n",
651
+ "full_gdf = pd.concat(joined_gdf_list)\n",
652
+ "\n",
653
+ "full_gdf\n"
654
+ ]
655
+ },
656
+ {
657
+ "cell_type": "code",
658
+ "execution_count": null,
659
+ "metadata": {},
660
+ "outputs": [
661
+ {
662
+ "data": {
663
+ "text/plain": [
664
+ "2364 Cameroon\n",
665
+ "2365 Cameroon\n",
666
+ "2366 Cameroon\n",
667
+ "2367 Cameroon\n",
668
+ "2368 Cameroon\n",
669
+ " ... \n",
670
+ "66019 Zambia\n",
671
+ "66022 Zambia\n",
672
+ "66023 Zambia\n",
673
+ "66024 Zambia\n",
674
+ "66028 Zambia\n",
675
+ "Name: country, Length: 52102, dtype: object"
676
+ ]
677
+ },
678
+ "execution_count": 10,
679
+ "metadata": {},
680
+ "output_type": "execute_result"
681
+ }
682
+ ],
683
+ "source": [
684
+ "#rename two-word countries to standardized names \n",
685
+ "full_gdf['country'].replace('Côte d’Ivoire', 'Ivory Coast')\n"
686
+ ]
687
+ },
688
+ {
689
+ "cell_type": "code",
690
+ "execution_count": 19,
691
+ "metadata": {},
692
+ "outputs": [],
693
+ "source": [
694
+ "#write to csv \n",
695
+ "full_gdf.to_csv('data/residual_by_country.csv')"
696
+ ]
697
+ },
698
+ {
699
+ "cell_type": "code",
700
+ "execution_count": 4,
701
+ "metadata": {},
702
+ "outputs": [
703
+ {
704
+ "data": {
705
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAJOCAYAAACqS2TfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABgiElEQVR4nO3deXhU5f3//9fJdiYIRAgkLAZQPy6guIECogYU44Ia0X6JohErYhHQqq39SK1lUQvVuiKKO6407nH7YGlZXCAWw2LdcBdEAopsLjPZ7t8flPyIZJlk5uScufN8XFeuKzlz5sz7xUyYvOe+z30cY4wRAAAAAACIuyS/CwAAAAAAwFY03QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAITTcAAAAAAB6h6QYAAAAAwCM03QAAz82ZM0eO4+idd96RJP3tb3+T4zh6++23a+1XXV2tjh07ynEcrV69utZt5eXlatOmjc4666yabY7jaOLEiY0+fq9eveQ4Ts3XHnvsoSOOOEJ33XWXjDFxSFg3x3E0ZcqURvfb+e/z5ZdfelZLU+rZ9d/KcRxlZGRoyJAheuWVV2rt16tXL1144YVNruOnn37SlClTtGjRoqj2//LLL3eraedX//79m/z4zfXdd9/Jdd1ar+UgmTJlihzH8bsMAMAv0HQDAFrc0KFDJUkLFy6stX3VqlXavHmz9thjj91ue/vtt/Xzzz/X3LepBg8erKVLl2rp0qV67LHH1KZNG1122WWaPn1680JEYenSpbr44os9O76XfvWrX2np0qV66623NGvWLJWVlen000/frfFujp9++klTp06Nuune6bLLLqt5Dnd+zZkzJ+Z6ovXYY4+pvLxckvTggw+22OMCABIbTTcAoMUdfvjh2nPPPXdruhYtWqRu3brpjDPO2K3p3rlvc5vuPffcUwMHDtTAgQN11lln6dVXX1VGRobuvffeZh0vGgMHDtRee+3l2fG9lJ2drYEDB+roo4/W+eefr1deeUXGGN1+++2+1dSjR4+a53Dn18EHHxzzcSsqKlRZWdnofg899JCysrJ05JFHau7cufr5559jfmwAgP1ougEALS4pKUnHHXec3nrrrVrNzqJFizRkyBDl5ubW2ZB37txZBx10UFxqaN++vfbff39t2LCh1vby8nLdcMMNOvDAA+W6rjp37qxf//rX+vbbb2vtt2DBAg0ZMkSZmZlKT09Xjx49dPbZZ+unn36q2aeu6dwlJSUaPHiwQqGQunXrpkmTJqmiomK3+uqbCv7LKd3ffvutxo8frz59+qht27bKysrS8ccfrzfeeKPp/ygN2HfffdW5c2d99dVXDe63Zs0anX/++crKypLruurdu7duueUWVVdXS9oxVbxz586SpKlTp9ZME2/ONPVfeu+995Sfn68OHTooFArpsMMO0yOPPFJrn0WLFslxHD322GP63e9+p+7du8t1XX366acNHvvtt9/We++9p8LCQo0dO1Zbt27Vs88+u9t+Q4YM0cEHH6xly5bp2GOPVZs2bbTPPvtoxowZNf8GO73//vvKy8tTmzZt1LlzZ02YMEGvvPKKHMfZ7fX/0EMP6dBDD1UoFFLHjh01YsQIffjhh43+mxQVFSkvL09du3ZVenq6evfurWuuuUY//vhjo/cFAMQHTTcAwBdDhw7VDz/8oGXLlknacT7366+/rtzcXOXm5mrjxo364IMPJO1ohJcuXaohQ4bE7ZzVyspKrV27Vvvvv3/NturqauXn52vGjBkaNWqUXnnlFc2YMUPz58/XkCFDakY2v/zySw0fPlxpaWl66KGHNG/ePM2YMUN77LFHzfTjunzwwQc64YQTtGXLFs2ZM0ezZ8/WihUrdMMNNzQ7x/fffy9Jmjx5sl555RU9/PDD2meffTRkyJAmT99uyObNm7Vp06aahrku3377rY4++mj94x//0PXXX68XX3xRw4YN0+9///uac++7du2qefPmSZLGjBlTM038uuuua7SG6upqVVZW1vraeU7+6tWrdfTRR+v999/XnXfeqeeee059+vTRhRdeqJtuumm3Y02aNElr1qzR7Nmz9dJLLykrK6vBx945nfyiiy7SOeecozZt2tQ7xbysrEznnXeezj//fL344os65ZRTNGnSJD3++OM1+6xfv165ublavXq17rnnHj366KPavn17nWsUTJ8+XWPGjNFBBx2k5557TnfccYfeffddDRo0SJ988kmDdX/yySc69dRT9eCDD2revHm64oor9NRTT+n0009v8H4AgDgyAAB47OGHHzaSzLJly2q2rVy50kgyf/nLX4wxxpSWlhpJ5qOPPjLGGJOdnW3uuusuY4wxixcvNpLM3XffXeu4ksyECRMaffyePXuaU0891VRUVJiKigrz1VdfmbFjx5rU1FTz8ssv1+w3d+5cI8k8++yzte6/bNmyWo//zDPPGElm5cqVDT6uJDN58uSanwsKCkx6eropKyur2VZZWWkOPPBAI8l88cUX9d531yyjR4+u9zErKytNRUWFOeGEE8yIESMarKehusePH28qKipMeXm5+fDDD80pp5xiJJlZs2bVW8s111xjJJm333671vEuvfRS4ziOWb16tTHGmG+//TbqWowx5osvvjCS6vyaP3++McaYc845x7iua9asWVPrvqeccopp06aN2bJlizHGmIULFxpJ5rjjjovqsY0x5scffzTt27c3AwcOrNk2evRo4ziO+fTTT2vtm5ubW+e/QZ8+fcxJJ51U8/PVV19tHMcx77//fq39TjrpJCPJLFy40BhjzObNm016ero59dRTa+23Zs0a47quGTVqVM22yZMnm4b+tKuurjYVFRU1v0+rVq2K7h8AABATRroBAL445JBDlJmZWTMau2jRInXp0kUHHHCAJOm4446rOa871vO5JenVV19VamqqUlNT1bNnT91///2aOXOmhg8fXrPPyy+/rD333FOnn356rdHUww47TF26dKmp47DDDlNaWpouueQSPfLII/r888+jqmHhwoU64YQTlJ2dXbMtOTlZBQUFzc4lSbNnz9YRRxyhUCiklJQUpaam6l//+ldU04/rc/fddys1NVVpaWnq3bu3lixZomnTpmn8+PH13mfBggXq06ePjjrqqFrbL7zwQhljtGDBgmbXI0m//e1vtWzZslpfAwYMqHnsE044QTk5Obs99k8//aSlS5fW2n722WdH/bhPPfWUtm3bposuuqhm20UXXSRjjB5++OHd9u/Spctu/waHHHJIran5ixcv1sEHH6w+ffrU2u/cc8+t9fPSpUv1888/7zb9PicnR8cff7z+9a9/NVj7559/rlGjRqlLly5KTk5WamqqcnNzJSmm1wcAIHo03QAAXziOo9zcXL311luqqKjQwoULa5oBScrNzdXixYtljNHChQvVpUsXHXjggc1+vGOOOUbLli1TSUmJHnvsMfXq1UsTJ07Um2++WbPPhg0btGXLFqWlpdU06Du/ysrK9N1330nacX7zP//5T2VlZWnChAnad999te++++qOO+5osIZNmzapS5cuu22va1u0br31Vl166aUaMGCAnn32WZWUlGjZsmU6+eSTY1roa+TIkVq2bJneeecdrV69Wps2bWp0CvimTZvUtWvX3bZ369at5vZY7LXXXurfv3+tr3bt2jXrsevatz4PPvigQqGQTj75ZG3ZskVbtmzRIYccol69emnOnDmqqqqqtX9mZuZux3Bdt9bzsWnTplofvuz0y207664vW0P/pj/88IOOPfZYvf3227rhhhu0aNEiLVu2TM8995wksRAcALSQFL8LAAC0XkOHDtVzzz2nt99+W2+88Uaty3fl5ubqu+++U2lpqUpKSjRixIiYHisjI6Pmms4DBgzQgAEDdOihh2r8+PFauXKlkpKS1KlTJ2VmZtacc/xLOxs8STr22GN17LHHqqqqSu+8845mzpypK664QtnZ2TrnnHPqvH9mZqbKysp2217XNtd1FYlEdtv+yybr8ccf15AhQ3TPPffU2r59+/Y6a4hW586dm3wN7MzMTK1fv3637d98840kqVOnTjHVFM/HjnZtgI8//rjmg5kePXrUuc9rr72mU089tSnlKjMzc7dF/KTdXws7G/j6sjX0b7pgwQJ98803WrRoUa0PtLZs2dKkWgEAsWGkGwDgm53TxW+77TZt3bpVQ4YMqbntoIMOUmZmpqZPn65wOBzT1PK67LfffvrDH/6g//znPyoqKpIknXbaadq0aZOqqqp2G1Ht379/zdT3XSUnJ2vAgAGaNWuWJGn58uX1PubQoUP1r3/9q1azVVVVVfP4u+rVq5fefffdWtsWLFigH374odY2x3Hkum6tbe++++5u06lbwgknnKAPPvhgt3+DRx99VI7j1DyHO+uN50jrCSecUNNk/vKx27Rpo4EDBzbruDsXS7v//vu1cOHCWl87T1l46KGHmnzc3NxcvffeezWLBe7097//vdbPgwYNUnp6eq1F2CTp66+/rplSX5+dHyz88vXh5WXyAAC7Y6QbAOCbgw46SFlZWXr++efVuXNn9e7du+Y2x3F03HHH6fnnn5cU2/nc9fn973+v2bNna+rUqRo5cqTOOeccPfHEEzr11FP129/+VkcddZRSU1P19ddfa+HChcrPz9eIESM0e/ZsLViwQMOHD1ePHj0UDodrGq9hw4bV+3h/+tOf9OKLL+r444/Xn//8Z7Vp00azZs2q8/JNhYWFuu666/TnP/9Zubm5+uCDD3TXXXcpIyOj1n6nnXaarr/+ek2ePLlmNexp06Zp7733jura0/F05ZVX6tFHH9Xw4cM1bdo09ezZU6+88oruvvtuXXrppTUrxbdr1049e/ZUcXGxTjjhBHXs2FGdOnVSr169mv3YkydP1ssvv6yhQ4fqz3/+szp27KgnnnhCr7zyim666abd/t2iUVlZqUcffVS9e/fWxRdfXOc+p59+ul588UV9++23Da7s/ktXXHGFHnroIZ1yyimaNm2asrOz9eSTT+qjjz6StOOyetKO68tfd911+uMf/6gLLrhA5557rjZt2qSpU6cqFApp8uTJ9T7G0UcfrQ4dOmjcuHGaPHmyUlNT9cQTT2jVqlVN+FcAAMSKkW4AgK+GDBkiY0yt6a875ebmyhij7t2763/+53/i/tht27bVn//8Z61evVpPPPGEkpOT9eKLL+qPf/yjnnvuOY0YMUJnnnmmZsyYoVAopL59+0rasZBaZWWlJk+erFNOOUWFhYX69ttv9eKLLyovL6/exzv44IP1z3/+U+3bt9fo0aN1ySWX6JBDDqnzXOmrr75aV199tebMmaPTTz9dzz77rJ566intueeetfa79tpr9bvf/U4PPvighg8frgceeECzZ8/WMcccE9d/q2h07txZS5Ys0fHHH69JkybptNNO02uvvaabbrpJM2fOrLXvgw8+qDZt2uiMM87QkUceWec1yZvigAMO0JIlS3TAAQdowoQJOvPMM/Xee+/p4Ycf1tVXX92sY77yyisqKyvTb37zm3r3ueSSS1RRUaHHHnusScfu1q2bFi9erP3331/jxo3Teeedp7S0NE2bNk2Saj3PkyZN0gMPPKBVq1bpzDPP1MSJE3XQQQdpyZIl2m+//ep9jMzMTL3yyitq06aNzj//fF100UVq27ZtnTMrAADecYz57wUuAQAA4KtLLrlEc+fO1aZNm5SWluZ3OQCAOGB6OQAAgA+mTZumbt26aZ999tEPP/ygl19+WQ888ID+9Kc/0XADgEVougEAAHyQmpqqm2++WV9//bUqKyu133776dZbb9Vvf/tbv0sDAMQR08sBAAAAAPAIC6kBAAAAAOARmm4AAAAAADxC0w0AAAAAgEdYSK0R1dXV+uabb9SuXTs5juN3OQAAAACAADDGaPv27erWrZuSkuofz6bpbsQ333yjnJwcv8sAAAAAAATQ2rVrtddee9V7O013I9q1aydpxz9k+/btfa4GAAAAABAE27ZtU05OTk3PWB+a7kbsnFLevn17mm4AAAAAQC2NnYbMQmoAAAAAAHiEphsAAAAAAI/QdAMAAAAA4BGabgAAAAAAPELTDQAAAACAR2i6AQAAAADwCE03AAAAAAAeoekGAAAAAMAjNN0AAAAAAHiEphsAAAAAAI/QdAMAAAAA4BGabgAAAAAAPELTDQAAAACAR2i6AQAAAADwCE03AAAAAAAeoekGAAAAAMAjKX4XAAAAAMAexhhFIpEm7ee6rhzHafQ+0e4HBAlNNwAAAIC4iUQiys/P9+TYxcXFCoVCnhwb8ArTywEAAAAA8Agj3QAAAADixnVdFRcXN7pfOBxWQUGBJKmoqCiqEWzXdWOuD2hpNN0AAACAz2w6D9pxnCZPAQ+FQkwbh7VougEAAACfcR40YC/O6QYAAAAAwCOMdAMAAAA+4zxowF403QAAAIDPOA8asBfTywEAAAAA8AhNNwAAAAAAHqHpBgAAAADAIzTdAAAAAAB4hKYbAAAAAACP0HQDAAAAAOARmm4AAAAAADxC0w0AAAAAgEdougEAAAAA8AhNNwAAAAAAHknxuwAAQHAYYxSJRJq0n+u6chyn0ftEux8AAIBNaLoBADUikYjy8/M9OXZxcbFCoZAnxwYAAAgqmm4AAAAA+AVmfyFeaLoBADVc11VxcXGj+4XDYRUUFEiSioqKohrBdl035voAAGgpzP5CvNB0AwBqOI7T5D8CQqEQfzgAAADUg6YbAAAAAH6B2V+IF5puAACAVibac1V/uS/nq6I1YfYX4oWmGwAAoJXx8lxVifNVAWBXSX4XAAAAAACArRjpBgAAaGWiPVdV4nxVAIgVTTcAAEAr05xzVSXOVwWA5ki46eV333239t57b4VCIfXr109vvPFGvfs+99xzOvHEE9W5c2e1b99egwYN0muvvdaC1QIAAAAAWrOEarqLiop0xRVX6Nprr9WKFSt07LHH6pRTTtGaNWvq3P/111/XiSeeqFdffVWlpaUaOnSoTj/9dK1YsaKFKwcAAAAAtEYJ1XTfeuutGjNmjC6++GL17t1bt99+u3JycnTPPffUuf/tt9+uP/zhDzryyCO133776S9/+Yv2228/vfTSSy1cOQAAAACgNUqYpru8vFylpaXKy8urtT0vL09LliyJ6hjV1dXavn27OnbsWO8+kUhE27Ztq/UFAAAAAEBzJEzT/d1336mqqkrZ2dm1tmdnZ6usrCyqY9xyyy368ccfNXLkyHr3mT59ujIyMmq+cnJyYqobAAAAANB6JUzTvZPjOLV+Nsbstq0uc+fO1ZQpU1RUVKSsrKx695s0aZK2bt1a87V27dqYawYAAAAAtE4Jc8mwTp06KTk5ebdR7Y0bN+42+v1LRUVFGjNmjJ5++mkNGzaswX1d1+XakgAAAACAuEiYke60tDT169dP8+fPr7V9/vz5Ovroo+u939y5c3XhhRfqySef1PDhw70uEwAAAACAGgkz0i1JV111lQoLC9W/f38NGjRI9913n9asWaNx48ZJ2jE1fN26dXr00Ucl7Wi4L7jgAt1xxx0aOHBgzSh5enq6MjIyfMsBAAAAAGgdEqrpLigo0KZNmzRt2jStX79eBx98sF599VX17NlTkrR+/fpa1+y+9957VVlZqQkTJmjChAk120ePHq05c+a0dPkAAAAAgFYmoZpuSRo/frzGjx9f522/bKQXLVrkfUEAAAAAANQjYc7pBgAAAAAg0STcSDcAAACwkzFGkUikSfu5rhvVJWej3Q8AGkLTDQAAECUavOCJRCLKz8/35NjFxcUKhUKeHBtA60HTDQAAECUaPABAU9F0AwAAIGG5rqvi4uJG9wuHwyooKJAkFRUVRfUBh+u6MdcHADTdAAAAUaLBCx7HcZo8QyAUCjGrAECLoekGAACIEg0eAKCpuGQYAAAAAAAeoekGAAAAAMAjNN0AAAAAAHiEphsAAAAAAI/QdAMAAAAA4BGabgAAAAAAPELTDQAAAACAR2i6AQAAAADwCE03AAAAAAAeoekGAAAAAMAjNN0AAAAAAHiEphsAAAAAAI/QdAMAAAAA4BGabgAAAAAAPELTDQAAAACAR2i6AQAAAADwCE03AAAAAAAeoekGAAAAAMAjNN0AAAAAAHiEphsAAAAAAI+k+F0AAADxZoxRJBJp0n6u68pxnEbvE+1+AAAAEk03AMBCkUhE+fn5nhy7uLhYoVDIk2MDAAD7ML0cAAAAAACPMNINALCO67oqLi5udL9wOKyCggJJUlFRUVQj2K7rxlwfAABoPWi6AQDWcRynyVPAQ6EQ08YBAEDcMb0cAAAAAACP0HQDAAAAAOARmm4AAAAAADxC0w0AAAAAgEdougEAAAAA8AhNNwAAAAAAHqHpBgAAAADAI1yn2yPGGEUikSbt57quHMdp9D7R7gcAAAAA8BdNt0cikYjy8/M9OXZxcbFCoZAnxwYAAAAAxA9NNwAAAABYyssZuE3dt7Wi6faI67oqLi5udL9wOKyCggJJUlFRUVQj2K7rxlwfAAAAAPt5OQNXYhZuNGi6PeI4TpNffKFQiBcsAAAAAFiEphsAAAAALOXlDNydx0fDaLoBAAAAwFLMwPUf1+kGAAAAAMAjNN0AAAAAAHiEphsAAAAAAI/QdAMAAAAA4BGabgAAAAAAPELTDQAAAACAR7hkGFoNY4wikUiT9nNdV47jNHqfaPcDAAAA0LrQdKPViEQiys/P9+TYxcXFXMsQAAAAwG6YXg4AAAAAgEcY6Uar4bquiouLG90vHA6roKBAklRUVBTVCLbrujHXBwAAAMA+NN1oNRzHafIU8FAoxLRxAGgFol33I1rhcLjO7+OBdUQAILHQdAMAAM8FfTFLL9f92Dl7Kl5YRwQAEgtNNwAA8ByLWQIAWiuabgAA0GzRjmDHe4p1c44d7Yh42vljpJTUmGoyxkiVlTt+SEmJfTp4ZYXKH38wtmMAAHxB0w0kGC+naDZ1XwDwcgQ7WtFO3456RDwlVU5qbE23I0lpaTEdY1cmbkcCALQ0mm4gIHY2yY2N2ITDYY0ePdqzOh555JFG/ygNhUI05wAAAEAUaLqBgAjCaJGkqBt6zqEEAAAAGkfTjUYFfcVZAEAwJJ/3/+SkButPC1NRqaonnva7DABAKxasd8YEkEjX8ZSCfxkVRkvrdkGeo1j/bq2uNgqX7/g+lCYlJcX+4UZFpfToPzizEEDdnNSUmM+FBgDANjTdTZRI1/GUaGoTlTeNLc0yAAAA0NJoutEo13VVXFzc6H7hcLjmg4OioqKomn3XdWOuDwBsxek9AAAkPpruGMw65Vdyk2P7JzTGqLyqSpKUlpwclz+AIlWVmvB/z8R8nJ0cx2nyaHkoFGKEvYmi/XAjWs35EKQp+MAE8B6n9wAAkPhoumPgJqcolBL7uWvpnP4GRf/hRrzXFfglRr8AAACA+KHpBhJMc0a+mrJeAKNfQHAk3Ok9lZUxrx5hjJEqd8wAU0ocZoBVVsZYEQAAsaHpBgAgoBLt9J7Kx7k0FwAAv0TTDSSYaEe+mrOw0s59AQAAAMQHTTeQYJoy8pWenu5xNbFhZWYg8SXSIpB8qAgA8ANNNwDfsDIzkPiaMwU+WlwJAwBgA5puAEDCiPfq/eFwuM7v44HZFgAAQKLpBuCjhFuZGb7zcnZEU1b5jwazLQDYhg8+geah6Qbgm0RbmTlReXFtd/5Qgs1MRYXfJewmiDWh9eGDT6B5aLoBwHJe/pEk+feHUtLow6XUpJgea8c1oat3/JCSFHuzX1Gt6kdWxHYMS0X74U9zPtCJ9wc1FU88GLdjAQBA0w0ASEypSXJSk2M6hCNJaXGpRpJk4nco6zTnw59oP9BhRAtoeb87e5ZSU2I7lcsYo4qqcklSanJazB+eVVRGdMuzE2I6BuAFmm4AaEWyR0tOHP7nN0YylTu+d1KkWAcZTaW04ZHY6wLiIfW8MXJSU/0uoxZTUcEIPAIlNcVVWkrsH3a5qcG+vCkQDzTdANCKOClSUmqcpuHGcYS4mjFi60W7cOKu09CjnTYe74UTndTUwDXd0WINBwAIHppuAADguaYsnJiezshXc9m0hgMrZQOwBU03AAAAAoeVsgHYgqYbAADAQm0Kr5ZSYj8PZMcq//+9ZFlKauwjupXl+umxm2OuCwASBU03AACAjVLS5KTG3nTvWOU/fufNN2cFh31H36qkOKyUbSp3rJTtpMS+UnZ1ZUSfPXJVTMcA0DrQdAMAACDQklJcJaXGofFPYwo4gJaX5HcBAAAAAADYiqYbAAAAAACP0HQDAAAAAOCRhGu67777bu29994KhULq16+f3njjjQb3X7x4sfr166dQKKR99tlHs2fPbqFKAQAAAACtXUI13UVFRbriiit07bXXasWKFTr22GN1yimnaM2aNXXu/8UXX+jUU0/VscceqxUrVuiPf/yjLr/8cj377LMtXDkAAAAAoDVKqNXLb731Vo0ZM0YXX3yxJOn222/Xa6+9pnvuuUfTp0/fbf/Zs2erR48euv322yVJvXv31jvvvKO//e1vOvvss1uydAAAALRCxhhFIpG4HS8cDtf5fTy4rhv7ddgB7CZhmu7y8nKVlpbqmmuuqbU9Ly9PS5YsqfM+S5cuVV5eXq1tJ510kh588EFVVFQoNTV1t/tEIpFa/zFu27YtDtUDAICEUVnRrGtJ78oYI1VW7vghJSX2RqayIsaK4JdIJKL8/HxPjl1QUBDX4xUXFysU4rJqQLwlTNP93XffqaqqStnZ2bW2Z2dnq6ysrM77lJWV1bl/ZWWlvvvuO3Xt2nW3+0yfPl1Tp06NX+EAACChlD/+oN8lAPAQsw/Q0hKm6d7ply86Y0yDL8S69q9r+06TJk3SVVddVfPztm3blJOT09xyAQAAAElSQeEspaS4MR3DGKOqynJJUnJKWswNWWVlREWPTYjpGImG2QdoaQnTdHfq1EnJycm7jWpv3Lhxt9Hsnbp06VLn/ikpKcrMzKzzPq7rynVj+88QgF22bNnS4O3V1dXavn27J4/drl07JSU1vOblnnvu6cljA62J67oqLi6O2/HC4XDNH99FRUVx/aOZv1MSV0qKq9TUOLwW0tJjPwaAFpMwTXdaWpr69eun+fPna8SIETXb58+fX+8nVYMGDdJLL71Ua9s//vEP9e/fv87zuQGgLvH+1DreXnvtNb9LABKe4ziejSaFQiFGqoCAuvn4mXKTY599UF69Y/ZBWlLssw8iVRFdveCymI6BYEmYpluSrrrqKhUWFqp///4aNGiQ7rvvPq1Zs0bjxo2TtGNq+Lp16/Too49KksaNG6e77rpLV111lcaOHaulS5fqwQcf1Ny5c/2MAQAAACAA3GRXboxT/iUpJD5YQ/0SqukuKCjQpk2bNG3aNK1fv14HH3ywXn31VfXs2VOStH79+lrX7N5777316quv6sorr9SsWbPUrVs33XnnnVwuDECTFBUVNXi739PLAQAAEFwJ1XRL0vjx4zV+/Pg6b5szZ85u23Jzc7V8+XKPqwJgs2jOme7YsaP3haAWU1Hldwm7CWJNAADAXwnXdAMAIEnmkZUxX0sZAADAazTdAAC0sES6RqzEdWIBAIgFTTeAuEukhqK1NRPVFZICOD68o66mcUYfJic1Of7FxMBUVMk8srLR/RLpGrES14kFACAWNN0A4i6RGorW1kxsfNTvCuLHSU0OXNMtBfEjDQAA4CeabgAAfJR8wclSSmwfHhhjpMr/LuKWkhyf2RuVVap6dF7sxwEAoJWj6QbgqV+NkFJi/J/GGKnqv/1EcrIUaz9RWSk983xsx0hUWRdISal+V7G76gq7RuGbJCVZTmpsvySOJKXF94llxB4AgPig6QbgqZSU2JtuSUoNYKOYiJJSpaTUIJ7DTosHAADslOR3AQAAAAAA2IqR7hhEKiv9LqFOQa0LAAAAAFobmu4YTJj3jN8lAAAAAAACjOnlAAAAAAB4hJHuGMw6+Vdy47FCVJxFKisZhUdgBPFshyDWBAAAADsFr2NMIG5KikIpLKkMNKS1XpoLAAAAkJheDgAAAACAZxjpBuCpX42Iz3W646mykhF4AAAAtIyA/SkMwDYpKcFrugEAAICWwvRyAAAAAAA8QtMNAAAAAIBHmPSJhGeMUSQSidvxwuFwnd/Hg+u6chwnrscEAAAAEFw03Uh4kUhE+fn5nhy7oKAgrscrLi5WKBSK6zEBAAAABBfTywEAAAAA8Agj3bDK5FPSlJYc2zGMMaqo2vF9arJing5eXiVN/b/y2IoCAAAAkJBoumGVtGQpLSXWc6YdualxKee/TDwPBgAAACCB0HQDAAAg0Kor4rdgarwEsSYAwUTTDQCAj0xFpd8l1CmodaF1+uzRq/wuAQCajaYbAAAfVT/2mt8lAAAAD9F0AwAAIND2veBWJaW6fpdRS3VFhBF4AFGh6QYAwEdJhSfJSQ3e27GpqGQUHoGRlOoGrukGgGgF710eAIBWxElNCWTTDQAA4oN3+VbMGKNIJH4rb4bD4Tq/jwfXdWO+XjYAAADio7wyeKu3B7EmNM2WLVsavL26ulrbt2/35LHbtWunpKSkBvfZc889m3Vsmu5WLBKJKD8/35NjFxQUxPV4xcXFCoVCcT0mAAAAmufWZyf4XQIsFO8eIt5ee615p1013MoDAAAAAIBmY6QbkqSZJ/eTmxzbZzDGGJVXVUuS0pKTYp4OHqmq1mXzSmM6BgAAAOLvqrNnKS0lWIvblVdGGIFPcEVFRQ3e7vf08uai6YYkyU1OkpuSHPNxQqlxKAYAAACBlpbiKi2FU/8QX9GcM92xY0fvC4kzppcDAAAAAOARmm4AAAAAADzC9HIAAACgBVRWBO+SVkGsCbANTXcMIlWVMR9jx+JjVZKktOTkuFyLOh51AUDgVVTLxHgIY4xUuWMBSKXEvgCkKqpjrAiAzYoeZ5EvoDWi6Y7BhP97xu8SAKDVqn5kRdyPGWsTDwAA8Es03QAAAEALKDh/llJSg3WZrcqKCCPwgMdoupvIdV0VFxfH7XjhcFgFBQWSdlyXLhSK76UXXDdY/7EDQCwS6f9g/v8F8Espqa5SU7nMFtDa0HQ3keM4cW+MdwqFQp4dGwBswP/B8JsxRpFI4wtPhcPhOr9viOu6cVnbBQAQLDTdAAAAUYpEIsrPz2/SfXbOpmhMcXFxXD/4MRXlcTtWPAW1LiDRRPshYLSa82FhU7TmDxab3XRXVlZq0aJF+uyzzzRq1Ci1a9dO33zzjdq3b6+2bdvGs0YAAAA00c+P3+x3CQA81JwPAaMV7YeFTRHvDxYTSbOa7q+++konn3yy1qxZo0gkohNPPFHt2rXTTTfdpHA4rNmzZ8e7TgAAAN9Fu67AriNQ0Y7usA4AANipWU33b3/7W/Xv31+rVq1SZmZmzfYRI0bo4osvjltxAAAAQdKUdQXS09M9rqaRxz//ajmpab7WUBdTUc4oPBBndw2dLDc5tt93Y4zKqyskSWlJqXGZCh6pKtfEhVNjPk6ia1bT/eabb+qtt95SWlrtJ7Znz55at25dXAoDAABA8zmpaYFsugHEn5ucJjcl9t/3kJhx44VmNd3V1dWqqqrabfvXX3+tdu3axVwUAACtRmWVTIyHMMZIlf99X05Jjs9CNZW7v88DAICma1bTfeKJJ+r222/XfffdJ2nHVKsffvhBkydP1qmnnhrXAgEAsFnVo/P8LgEAAHioWU33bbfdpqFDh6pPnz4Kh8MaNWqUPvnkE3Xq1Elz586Nd40AAAAAACSkZjXd3bp108qVKzV37lwtX75c1dXVGjNmjM477zzfFw0BACDool0BO1rhcLjm8i5FRUVxvyQLq2oDANB8zb5Od3p6ui666CJddNFF8awHAADrNWUF7KYKhUKt9jqoAAAEUbOa7kcffbTB2y+44IJmFQMA8JaplKpjXrZLMmbHsSTJSZFiXbdr57EAAABs0+zrdO+qoqJCP/30k9LS0tSmTRuabvimvDL2ZiLeglgTWq8Nj/hdAQAAQOvSrKZ78+bNu2375JNPdOmll+rqq6+OuSiguabOq/C7BAAAAACo0exzun9pv/3204wZM3T++efro48+itdhAQAxiveiXZK3C3exaBcAALBJ3JpuSUpOTtY333wTz0MCTTL55FSlpcR4cmmclVcaRuDhKy8X7ZJYuAsAAKAhzWq6X3zxxVo/G2O0fv163XXXXRo8eHBcCgOaIy3FCVzTDQAAAKD1albTfeaZZ9b62XEcde7cWccff7xuueWWeNQFAAAAAEDCa1bTXV1dHe86AAAAAACwTpLfBQAAAAAAYKuoR7qvuuqqqA966623NqsYAAAAAABsEnXTvWLFiqj2cxwWsQIAAAAQfJGqiN8l7CaINSE2UTfdCxcu9LIOAAAAAGhRVy+4zO8S0ApwTjcAAAAAAB5p1urlkrRs2TI9/fTTWrNmjcrLy2vd9txzz8VcGAAAAAB46ebjZ8pNdv0uo5ZIVYQReMs0q+n++9//rgsuuEB5eXmaP3++8vLy9Mknn6isrEwjRoyId40AAAAAEHdusis3JVhNN+zTrOnlf/nLX3Tbbbfp5ZdfVlpamu644w59+OGHGjlypHr06BHvGgEAAAAASEjNGun+7LPPNHz4cEmS67r68ccf5TiOrrzySh1//PGaOnVqXIuE9yKVVX6XsJsg1gQAAAAATdGsprtjx47avn27JKl79+5677331LdvX23ZskU//fRTXAtEy7jsteV+lwAAAAAA1mlW033sscdq/vz56tu3r0aOHKnf/va3WrBggebPn68TTjgh3jUCSGCVlbEfwxip6r8TH5KTJcfxvyYAAAAgGs1quu+66y6Fw2FJ0qRJk5Samqo333xTZ511lq677rq4FoiWMfOkI+SmJPtdRi2RyipG4C3wzPN+VwAAAAD4p9nTy3dKSkrSH/7wB/3hD3+IW1FoeW5KcuCabgAAAABIdM1quocOHarzzz9fv/rVr5SRkRHvmgAkONd1VVxcHLfjhcNhFRQUSJKKiooUCoXidmzX5TIhAAAA8E6zmu6+ffvqT3/6kyZOnKhTTz1VhYWFOvXUU5WWlhbv+gAkIMdx4toY7yoUCnl2bAAAACDemnWd7jvvvFPr1q1TcXGx2rVrp9GjR6tLly665JJLtHjx4njXCAAAAABAQmpW0y3tOJc7Ly9Pc+bM0YYNG3Tvvffq3//+t44//vh41gcAAAAAQMJq1vTyXZWVlenvf/+7Hn/8cb377rs68sgj41EXAAAAAAAJr1kj3du2bdPDDz+sE088UTk5Obrnnnt0+umn6+OPP9bbb78d7xoBAAAAAEhIzRrpzs7OVocOHTRy5Ej95S9/YXQbQLMYYxSJRBrdLxwO1/l9Q1zXleM4za4NAAAAiIdmNd3FxcUaNmyYkpIaHih/66231L9/fy7JA6BOkUhE+fn5TbrPzkuHNaa4uJhVzgEAAOC7ZjXdeXl5Ue13yimnaOXKldpnn32a8zAAALRqzAYBACDxxbyQWkOMMV4eHkCCc11XxcXFje63a+MRbaPADBvYgNkgAAAkPk+bbgBoiOM4Uf/Rn56e7nE1AAAgWhWVjc/CaYwxRhVV5ZKk1OS0mGffxKMmwAs03QAABBSzQQAE1S3PTvC7BCBh0HQDABBQzAYBdqiO06iqqdwxquqkxD6qGo+aALQOnjbdLNACAACAWH32yFV+lwBFP/smWuFwuGYdiqKioriuM8FsHgQJC6l5hBVnAQAAYJOmzL5pqlAoxOKOsJanTff27du9PHygseIsAADwVWW54jH8YYyRKit2/JCSGvsH//+d4t0YRlUB2CLqpvuII47Qv/71L3Xo0EGHH354g//hLl++PC7F7Wrz5s26/PLL9eKLL0qSzjjjDM2cOVN77rlnnftXVFToT3/6k1599VV9/vnnysjI0LBhwzRjxgx169Yt7vUBAAAEyU+P3ex3CTFhVBWALaJuuvPz82s+xcvPz2/x6c2jRo3S119/rXnz5kmSLrnkEhUWFuqll16qc/+ffvpJy5cv13XXXadDDz1Umzdv1hVXXKEzzjhD77zzjuf1suIsAAAAdlUZpwXhqv47WyA5DgvCxaMmAA2LuumePHlyzfdTpkzxopZ6ffjhh5o3b55KSko0YMAASdL999+vQYMGafXq1TrggAN2u09GRobmz59fa9vMmTN11FFHac2aNerRo4enNbPiLAAAaGnxnpItMS07nooe4zJbQGvUrHO6r732Wg0ZMkSDBw9WmzZt4l3TbpYuXaqMjIyahluSBg4cqIyMDC1ZsqTOprsuW7duleM49U5Jl3aci73rAmjbtm1rdt0AAAAtycsp2RLTsgGgOZrVdJeWlmrmzJmKRCI64ogjNGTIEOXm5uqYY45R27Zt412jysrKlJWVtdv2rKwslZWVRXWMcDisa665RqNGjVL79u3r3W/69OmaOnVqs2sFAAAAdmJBOADNarrnzZunqqoq/fvf/9bixYu1aNEi3X333fr55591xBFHqKSkJKrjTJkypdEGd9myZZLqvua3MSaq81gqKip0zjnnqLq6WnfffXeD+06aNElXXfX/Xwty27ZtysnJafQxAAAAgF9iQTgAzb5kWHJysgYNGqSOHTuqQ4cOateunV544QV99tlnUR9j4sSJOueccxrcp1evXnr33Xe1YcOG3W779ttvlZ2d3eD9KyoqNHLkSH3xxRdasGBBg6Pc0o5P+PiUDwAAAAAQD81quu+55x4tXrxYixcvVlVVlY499ljl5ubquuuu0yGHHBL1cTp16qROnTo1ut+gQYO0detW/fvf/9ZRRx0lSXr77be1detWHX300fXeb2fD/cknn2jhwoXKzMyMujYAAAAAAGLVrKZ7woQJ6ty5s373u99p3LhxjY4ex6p37946+eSTNXbsWN17772Sdlwy7LTTTqu1iNqBBx6o6dOna8SIEaqsrNSvfvUrLV++XC+//LKqqqpqzv/u2LGj0tLSPK0ZAAAAAICk5tzpueee03nnnae///3vysrK0oABA/S///u/+r//+z/98MMP8a5RkvTEE0+ob9++ysvLU15eng455BA99thjtfZZvXq1tm7dKkn6+uuv9eKLL+rrr7/WYYcdpq5du9Z8LVmyxJMaAQAAAADYVbNGus8880ydeeaZknZchuuNN97QM888o/z8fDmOU+uSW/HSsWNHPf744w3uY4yp+b5Xr161fgYAAAAAoKU1eyG177//vmbl8kWLFum9995TZmamcnNz41kfAAAAAAAJq1lN9yGHHKIPPvhAHTt21HHHHaexY8dqyJAhOvjgg+NdHwAAAAAACatZTfcll1xCk41AKq+SpNhOKzDGqKJqx/epyXVfI77pNQEAAABojaJuuq+66ipdf/312mOPPfT555/r888/r3ffW2+9NS7FAU019f/K/S4BAAAAAGpE3XSvWLFCFRUVNd/XJ9ZRQQAAAAAAbBF1071w4cI6vwf85rquiouL43a8cDisgoICSVJRUZFCoVDcju26btyOBQAAACD4mr16ORAUjuPEtTHeVSgU8uzYAAAAAOyX5HcBAAAAAADYiqYbAAAAAACP0HQDAAAAAOARzumGJClSVR3zMYwxKv/vcdKSk2JeyT4eNQEAAAC2i1QF87K5Qa2rpdF0Q5J02bxSv0sAAAAA0AwTF071uwQ0gOnlAAAAAAB4hJHuVozrWwMAAACJ766hk+Ump/ldxm4iVeWMwoumu1Xj+tYAAABA4nOT0+SmBK/pxg5MLwcAAAAAwCOMdAMAAABolSJVkZiPYYxRefWOVbrTktLicAWf2GtCsNB0AwAAAGiVrl5wmd8loBVgejkAAAAAAB5hpBsAAABAq8EVfNDSaLoBAAAAtBpcwQctjenlAAAAAAB4hKYbAAAAAACPML0cAGAdY4wikcYvuRIOh+v8viGu68Z8ORgAANB60HQDAKwTiUSUn5/fpPvsXASnMcXFxZyvBwAAosb0cgAAAAAAPMJINwDAOtFeDmbXaejRThvn8i0AAKApaLoBANZpyuVg0tPTPa4GAAC0ZkwvBwAAAADAIzTdAAAAAAB4hKYbAAAAAACP0HQDAAAAAOARmm4AAAAAADxC0w0AAAAAgEdougEAAAAA8AhNNwAAAAAAHqHpBgAAAADAIzTdAAAAAAB4hKYbAAAAAACP0HQDAAAAAOARmm4AAAAAADxC0w0AAAAAgEdougEAAAAA8AhNNwCgVSspKVFhYaFKSkr8LgUAAFiIphsA0GqFw2Hdeeed2rhxo2bOnKlwOOx3SQAAwDI03QCAVquoqEjff/+9JGnTpk0qKiryuSIAAGAbmm4AQKu0bt06FRUVyRgjSTLG6KmnntK6det8rgwAANiEphsA0OoYYzRr1qx6t+9sxAEAAGJF0w0AaHXWrl2r0tJSVVVV1dpeVVWl0tJSrV271qfKAACAbVL8LgDBZ4xRJBJpdL9dFyCKdjEi13XlOE6za2sKW3IAiF1OTo769eunFStWqLq6umZ7cnKyDj/8cOXk5PhYHQAAsAlNNxoViUSUn5/fpPsUFBREtV9xcbFCoVBzymoyW3IAiJ3jOJowYYLGjh1b53Y+RAMAAPHC9HIAQKvUvXt3FRQU1DTYjuNo5MiR6tatm8+VAQAAmzDSjUa5rqvi4uJG99t1+na0061d1425vmjZkgNA/BQUFOi1117Tpk2blJmZGfXsFgAAgGjRdKNRjuNEPXU6PT3d42qaz5YcAOInFArp8ssv16xZszRhwgROEwEAAHFH0w0AaNUGDhyogQMH+l0GAACwFOd0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAIC6kBAGrsesm8hoTD4Tq/b0i0l+ADAACwCU03AKBGJBJRfn5+k+4T7bWti4uLuSQXAABodWi6AQAAACCBRarKYz6GMUbl1RWSpLSk1LjMTotHXTag6QYA1HBdV8XFxY3ut+s09GinjbuuG3N9AABgdxMXTvW7BDSAphsAUMNxnKingKenp3tcDQAAQOKj6QYAAACABBPt7LRohcPhmnVaioqK4r4OS2ue8UbTDQAAAAAJpimz05oqFAqx+GkccZ1uAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAITTcAAAAAAB6h6QYAAAAAwCM03QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAITTcAAAAAAB6h6QYAAAAAwCM03QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAITTcAAAAAAB6h6QYAAAAAwCM03QAAAAAAeISmGwAAAAAAjyRM071582YVFhYqIyNDGRkZKiws1JYtW6K+/29+8xs5jqPbb7/dsxoBAAAAANhVwjTdo0aN0sqVKzVv3jzNmzdPK1euVGFhYVT3feGFF/T222+rW7duHlcJAAAAAMD/L8XvAqLx4Ycfat68eSopKdGAAQMkSffff78GDRqk1atX64ADDqj3vuvWrdPEiRP12muvafjw4S1VMgAAAAAAidF0L126VBkZGTUNtyQNHDhQGRkZWrJkSb1Nd3V1tQoLC3X11VfroIMOiuqxIpGIIpFIzc/btm2LrXgAAAB4xhhT62+3+oTD4Tq/b4jrunIcp9m1AYCUIE13WVmZsrKydtuelZWlsrKyeu/317/+VSkpKbr88sujfqzp06dr6tSpzaoTAAAALSsSiSg/P79J9ykoKIhqv+LiYoVCoeaUBQA1fD2ne8qUKXIcp8Gvd955R5Lq/JTRGFPvp4+lpaW64447NGfOnCZ9Qjlp0iRt3bq15mvt2rXNCwcAAAAAaPV8HemeOHGizjnnnAb36dWrl959911t2LBht9u+/fZbZWdn13m/N954Qxs3blSPHj1qtlVVVel3v/udbr/9dn355Zd13s91XbmuG30IAAAA+MZ1XRUXFze6367T0KOdNs7fhADiwdemu1OnTurUqVOj+w0aNEhbt27Vv//9bx111FGSpLfffltbt27V0UcfXed9CgsLNWzYsFrbTjrpJBUWFurXv/517MUDAADAd47jRD0FPD093eNqAGB3CXFOd+/evXXyySdr7NixuvfeeyVJl1xyiU477bRai6gdeOCBmj59ukaMGKHMzExlZmbWOk5qaqq6dOnS4GrnAAAAAADES8Jcp/uJJ55Q3759lZeXp7y8PB1yyCF67LHHau2zevVqbd261acKAQAAAACoLSFGuiWpY8eOevzxxxvcxxjT4O31nccNAAAAAIAXEmakGwAAAACAREPTDQAAAACAR2i6AQAAAADwCE03AAAAAAAeoekGAAAAAMAjNN0AAAAAAHiEphtAQigpKVFhYaFKSkr8LgUAAACIGk03gMALh8O68847tXHjRs2cOVPhcNjvkgAAAICo0HQDCLyioiJ9//33kqRNmzapqKjI54oAAACA6NB0Awi0devWqaioSMYYSZIxRk899ZTWrVvnc2UAAABA42i6AQSWMUazZs2qd/vORhwAAAAIKppuAIG1du1alZaWqqqqqtb2qqoqlZaWau3atT5VBgAAAESHphtAYOXk5Khfv35KSqr9X1VycrL69++vnJwcnyoDAAAAokPTDSCwHMfRhAkT5DhOVNsBAACAoKHpBhBo3bt3V0FBQU2D7TiORo4cqW7duvlcGQAAANA4mm4AgVdQUKCOHTtKkjIzM1VQUOBzRQAAAEB0aLoBBF4oFNLll1+urKwsXXbZZQqFQn6XBAAAAEQlxe8CACAaAwcO1MCBA/0uAwAAAGgSRroBAAAAAPAITTcAAAAAAB6h6QYAAAAAwCM03QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPBIit8FAAAAAK2dMUaRSKTR/cLhcJ3fN8R1XTmO0+zaAMSGphsAAADwWSQSUX5+fpPuU1BQENV+xcXFCoVCzSkLQBwwvRwAAAAAAI8w0g0AAAD4zHVdFRcXN7rfrtPQo5027rpuzPU1BVPlgdpougEAAACfOY4T9RTw9PR0j6uJDVPlgdqYXg4AAAAAgEcY6QYAAAAQNzZNlQfigaYbAAAAQNzYNFUeiAemlwMAAAAA4BFGugEAAADAUl6uJi+xonw0aLoBAAAAwFJeriYvsaJ8NJheDgAAAACARxjpBgAAAABLebma/M590TCabgAAAACwFKvJ+4/p5QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAAAAAIBHaLoBAADQKpSUlKiwsFAlJSV+lwKgFaHpBgAAgPXC4bDuvPNObdy4UTNnzlQ4HPa7JACtBE03AAAArFdUVKTvv/9ekrRp0yYVFRX5XBGA1iLF7wIAAADQsowxikQiUe2764hwtKPDruvKcZxm1eaFdevWqaioSMYYSTvyP/XUUxo2bJi6d+/uc3UAbEfTDQAA0MpEIhHl5+c3+X4FBQVR7VdcXKxQKNTk43vBGKNZs2bVu/3GG28M1AcEAOzD9HIAAABYa+3atSotLVVVVVWt7VVVVSotLdXatWt9qgxAa8FINwAAQCvjuq6Ki4uj2nfXqejRTht3XTem+uIpJydH/fr104oVK1RdXV2zPTk5WYcffrhycnJ8rA5Aa0DTDQAA0Mo4jtOk6d/p6ekeVuMtx3E0YcIEjR07ts7tTC0H4DWmlwMAAMBq3bt3V0FBQU2D7TiORo4cqW7duvlcGYDWgKYbAAAA1isoKFDHjh0lSZmZmVEvCgcAsaLpBgAAgPVCoZAuv/xyZWVl6bLLLgvM6uoA7Mc53QAAAGgVBg4cqIEDB/pdBoBWhpFuAAAAAAA8QtMNAAAAAIBHaLoBAAAAAPAITTcAAABahZKSEhUWFqqkpMTvUgC0IjTdAAAAsF44HNadd96pjRs3aubMmQqHw36XBKCVoOkGAACA9YqKivT9999LkjZt2qSioiKfKwLQWtB0AwAAwGrr1q1TUVGRjDGSJGOMnnrqKa1bt87nygC0BjTdAAAAsJYxRrNmzap3+85GHAC8QtMNAAAAa61du1alpaWqqqqqtb2qqkqlpaVau3atT5UBaC1ougEAAGCtnJwc9evXT0lJtf/sTU5OVv/+/ZWTk+NTZQBaC5puAAAAWMtxHE2YMEGO40S1HQDijaYbAAAAVuvevbsKCgpqGmzHcTRy5Eh169bN58oAtAY03QAAALBeQUGBOnbsKEnKzMxUQUGBzxUBaC1ougEAAGC9UCikyy+/XFlZWbrssssUCoX8LglAK5HidwEAAABASxg4cKAGDhzodxkAWhlGugEAAAAA8AhNNwAAAAAAHqHpBgAAAADAIzTdAAAAAAB4hKYbAAAASCAlJSUqLCxUSUmJ36UAiAJNNwAAAJAgwuGw7rzzTm3cuFEzZ85UOBz2uyQAjaDpBgAAABJEUVGRvv/+e0nSpk2bVFRU5HNFABrDdboBAACABLBu3ToVFRXJGCNJMsboqaee0rBhw9S9e3efq7OPMUaRSKTR/XadbRDtzAPXdeU4TrNrQ2Kh6QYAAAACzhijWbNm1bv9xhtvpImLs0gkovz8/Cbdp6CgIKr9iouLFQqFmlMWEhDTywEAAICAW7t2rUpLS1VVVVVre1VVlUpLS7V27VqfKgPQGEa6AQAAgIDLyclRv379tGLFClVXV9dsT05O1uGHH66cnBwfq7OT67oqLi5udL9dp6FHO23cdd2Y60PioOkGAAAAAs5xHE2YMEFjx46tcztTy+PPcZyop4Cnp6d7XA0SGdPLAQAAgATQvXt3FRQU1DTYjuNo5MiR6tatm8+VAWgITTcAAACQIAoKCtSxY0dJUmZmZtQLdwHwD003AAAAkCBCoZAuv/xyZWVl6bLLLmMFbCABcE43AAAAkEAGDhyogQMH+l0GgCglzEj35s2bVVhYqIyMDGVkZKiwsFBbtmxp9H4ffvihzjjjDGVkZKhdu3YaOHCg1qxZ433BAAAAAIBWL2Ga7lGjRmnlypWaN2+e5s2bp5UrV6qwsLDB+3z22Wc65phjdOCBB2rRokVatWqVrrvuOqbhAAAAAABahGOMMX4X0ZgPP/xQffr0UUlJiQYMGCBJKikp0aBBg/TRRx/pgAMOqPN+55xzjlJTU/XYY481+7G3bdumjIwMbd26Ve3bt2/2cQAAAAAA9oi2V0yIke6lS5cqIyOjpuGWdpzLkpGRoSVLltR5n+rqar3yyivaf//9ddJJJykrK0sDBgzQCy+80OBjRSIRbdu2rdYXAAAAAADNkRBNd1lZmbKysnbbnpWVpbKysjrvs3HjRv3www+aMWOGTj75ZP3jH//QiBEjdNZZZ2nx4sX1Ptb06dNrzhvPyMhQTk5O3HIAAAAAAFoXX5vuKVOmyHGcBr/eeecdSZLjOLvd3xhT53Zpx0i3JOXn5+vKK6/UYYcdpmuuuUannXaaZs+eXW9NkyZN0tatW2u+1q5dG4ekAAAAAIDWyNdLhk2cOFHnnHNOg/v06tVL7777rjZs2LDbbd9++62ys7PrvF+nTp2UkpKiPn361Nreu3dvvfnmm/U+nuu6cl03iuoBAAAAAGiYr013p06d1KlTp0b3GzRokLZu3ap///vfOuqooyRJb7/9trZu3aqjjz66zvukpaXpyCOP1OrVq2tt//jjj9WzZ8/YiwcAAAAAoBEJcU537969dfLJJ2vs2LEqKSlRSUmJxo4dq9NOO63WyuUHHnignn/++Zqfr776ahUVFen+++/Xp59+qrvuuksvvfSSxo8f70cMAAAAAEArkxBNtyQ98cQT6tu3r/Ly8pSXl6dDDjlkt0uBrV69Wlu3bq35ecSIEZo9e7Zuuukm9e3bVw888ICeffZZHXPMMS1dPgAAAACgFUqI63T7iet0AwAAAAB+yarrdAMAAAAAkIhougEAAAAA8Iivq5cngp2z77dt2+ZzJQAAAACAoNjZIzZ2xjZNdyO2b98uScrJyfG5EgAAAABA0Gzfvl0ZGRn13s5Cao2orq7WN998o3bt2slxHE8eY9u2bcrJydHatWsTfrE2W7KQI3hsyWJLDsmeLOQIHluy2JJDsicLOYLHlizkCJ6WyGKM0fbt29WtWzclJdV/5jYj3Y1ISkrSXnvt1SKP1b59+4R/ce9kSxZyBI8tWWzJIdmThRzBY0sWW3JI9mQhR/DYkoUcweN1loZGuHdiITUAAAAAADxC0w0AAAAAgEdougPAdV1NnjxZruv6XUrMbMlCjuCxJYstOSR7spAjeGzJYksOyZ4s5AgeW7KQI3iClIWF1AAAAAAA8Agj3QAAAAAAeISmGwAAAAAAj9B0AwAAAADgEZpuAAAAAAA8QtMNAIAlFi1apJ9//tnvMgAACaaqqkobNmzQxo0bVVVV5Xc5cROU90Wa7oD58MMPtc8++/hdRlwkUpZVq1bphhtu0N13363vvvuu1m3btm3TRRdd5FNlTWNLDkl64IEHNHr0aD388MOSpKKiIvXu3Vv77LOPJk+e7HN10eM5CR6bnpNfysvL05dfful3GU3y8ccfa9cLqbz55ps688wzddBBB2nYsGEqLi72sbr4SaT3RMnu35OdEuk5sen5sOW9pCGJ9Np6/vnnNXjwYLVp00bdunVT165d1aZNGw0ePFgvvPCC3+XFLDDviwaBsnLlSpOUlOR3GXGRKFlee+01k5aWZg466CDTo0cP06lTJ7NgwYKa28vKysjRwm677Tazxx57mLPOOst07drV3HDDDSYzM9PccMMNZtq0aSYjI8Pce++9fpfZKJ6T4LHlOTn88MPr/HIcx/Tu3bvm50SQlJRkNmzYYIwxZuHChSYpKcmcfvrp5sYbbzRnn322SUpKMvPmzfO5ytglynuiMfb8njQmUZ4Tm54PW95LGpMor63Zs2ebtLQ0M27cOPP888+bJUuWmLfeess8//zzZty4ccZ1XXPffff5XWZUgv6+mOJ309/aXHXVVQ3e/u2337ZQJbGzJcuUKVP0+9//XjfeeKOMMfrb3/6mM844Q08//bROPvlkv8uLmi05JOnee+/Vfffdp1GjRmnFihU66qijNHv2bI0ZM0aStNdee2nWrFm65JJLfK60YTwnwWPLc/Kf//xHw4YN08CBA2u2GWO0atUqDR06VFlZWT5W1zRml1HuG264QePGjdOsWbNqtk2aNEl/+ctfdNJJJ/lRXtRseU+U7Pk9seU5seX5kOx5L7HltXXzzTfr7rvvrvn339WZZ56pI488UjfeeKPGjh3rQ3VNE/T3Rcfs+m4HzyUnJ+uwww5T+/bt67z9hx9+0PLlyxPiXApbsmRkZGj58uXad999a7bNnTtXY8eO1dy5c3XUUUepW7du5GhBbdq00UcffaQePXpIkkKhkEpLS3XQQQdJkj799FMdeeSR2rx5s59lNornJHhseU7eeustjR49Wuedd54mT56spKQdZ4ulpqZq1apV6tOnj88VRi8pKUllZWXKyspSt27d9Pzzz2vAgAE1t3/wwQc67rjjdptSGzS2vCdK9vye2PKc2PJ8SPa8l9jy2kpPT9fKlSt1wAEH1Hn7Rx99pMMPPzwQ50Q3Jujvi4x0t7D99ttPV155pc4///w6b1+5cqX69evXwlU1jy1ZXNfVli1bam0799xzlZSUpHPOOUe33HKLP4U1kS05pB1vyj/++GPNz507d1bbtm1r7VNZWdnSZTUZz0nw2PKcDB48WMuXL9dvfvMbDRo0SE8++WStP8gTzfbt2xUKhZSeni7XdWvdlpaWlhB/8NnynijZ83tiy3Niy/Mh2fNeYstr66CDDtJ9991X72vo/vvvr/lAJOiC/r5I093C+vXrp9LS0np/SR3HUaJMPrAly2GHHaaFCxfu9p9jQUGBqqurNXr0aJ8qaxpbckjSgQceqHfffVe9e/eWJK1du7bW7R999JF69erlQ2VNw3MSPDY9J+3bt9fcuXP18MMP65hjjtHUqVPlOI7fZTXL/vvvL2nHVMDS0lIddthhNbe9//776t69u0+VRc+W90TJnt8TW54TW54PyZ73ElteW7fccouGDx+uefPmKS8vT9nZ2XIcR2VlZZo/f76++uorvfrqq36XGbUgvy/SdLewW265RZFIpN7bDz30UFVXV7dgRc1nS5ZLL71Ur7/+ep23nXvuuZKk++67ryVLahZbckjSX//6V+2xxx713r5mzRr95je/acGKmofnJHhsek52+vWvf61jjjlG5513XkKMEP3SwoULa/3ctWvXWj9/+eWXCXE+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",
706
+ "text/plain": [
707
+ "<Figure size 1000x600 with 1 Axes>"
708
+ ]
709
+ },
710
+ "metadata": {},
711
+ "output_type": "display_data"
712
+ }
713
+ ],
714
+ "source": [
715
+ "def plot_country(country_name, gdf):\n",
716
+ " gdf = gdf[gdf['country'] == country_name]\n",
717
+ " modified_xticks = gdf['date'].dt.to_period('M')\n",
718
+ " plt.figure(figsize=(10,6))\n",
719
+ " sns.boxplot(x=modified_xticks, y=gdf['residual'])\n",
720
+ " plt.xlabel('date')\n",
721
+ " plt.xticks(rotation=90)\n",
722
+ " plt.ylabel('iwi_value')\n",
723
+ " plt.title(f'IWI Residual Plot For {country_name}')\n",
724
+ " plt.tight_layout()\n",
725
+ "\n",
726
+ "\n",
727
+ "plot_country('Angola', full_gdf)\n",
728
+ "\n",
729
+ "\n"
730
+ ]
731
+ }
732
+ ],
733
+ "metadata": {
734
+ "kernelspec": {
735
+ "display_name": "myenv",
736
+ "language": "python",
737
+ "name": "python3"
738
+ },
739
+ "language_info": {
740
+ "codemirror_mode": {
741
+ "name": "ipython",
742
+ "version": 3
743
+ },
744
+ "file_extension": ".py",
745
+ "mimetype": "text/x-python",
746
+ "name": "python",
747
+ "nbconvert_exporter": "python",
748
+ "pygments_lexer": "ipython3",
749
+ "version": "3.10.13"
750
+ }
751
+ },
752
+ "nbformat": 4,
753
+ "nbformat_minor": 2
754
+ }
residuals.cpython-311.pyc ADDED
Binary file (2.5 kB). View file
 
residuals.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib.pyplot as plt
2
+ import seaborn as sns
3
+ import pandas as pd
4
+ import geopandas as gp
5
+ import numpy as np
6
+
7
+ def get_residual_plot(country_name, gdf):
8
+ fig, ax = plt.subplots(1,1,figsize=(10,6))
9
+ if country_name is None:
10
+ ax.text(0.5, 0.5, "Click on the map to see the IWI time-series here.",
11
+ horizontalalignment='center', verticalalignment='center',
12
+ transform=ax.transAxes, fontsize=14)
13
+
14
+ elif gdf['country'].str.contains(country_name).any():
15
+ gdf = gdf[gdf['country'] == country_name]
16
+ gdf['date'] = pd.to_datetime(gdf['date'])
17
+ modified_xticks = gdf['date'].dt.to_period('M')
18
+ ticks_unique = np.unique(modified_xticks)
19
+ sns.boxplot(x=modified_xticks, y=gdf['residual'], ax=ax)
20
+ ax.set_xlabel('date')
21
+ ax.set_xticks(range(len(ticks_unique)))
22
+ ax.set_xticklabels(labels = ticks_unique, rotation=45)
23
+ ax.set_ylabel('iwi_value')
24
+ ax.set_title(f'IWI Residual Plot For {country_name}')
25
+ ax.grid(True, linestyle='--', alpha=0.7)
26
+ plt.tight_layout()
27
+ return fig
28
+
29
+ else:
30
+ ax.text(0.5, 0.5, "No country data available. Please select another country.",
31
+ horizontalalignment='center', verticalalignment='center',
32
+ transform=ax.transAxes, fontsize=14)
wealth_map.tif ADDED

Git LFS Details

  • SHA256: 43a501f255e0fae6222a4e95d95f4b096ec01b7cdb184b5d9547e316d3c50dba
  • Pointer size: 133 Bytes
  • Size of remote file: 54.8 MB