geocif 0.2.47__tar.gz → 0.2.49__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. {geocif-0.2.47/geocif.egg-info → geocif-0.2.49}/PKG-INFO +1 -1
  2. {geocif-0.2.47 → geocif-0.2.49}/geocif/geocif.py +0 -2
  3. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner.py +3 -3
  4. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/stats.py +13 -14
  5. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/aa.py +90 -0
  6. geocif-0.2.49/geocif/playground/aaaa.py +165 -0
  7. {geocif-0.2.47 → geocif-0.2.49/geocif.egg-info}/PKG-INFO +1 -1
  8. {geocif-0.2.47 → geocif-0.2.49}/geocif.egg-info/SOURCES.txt +1 -0
  9. {geocif-0.2.47 → geocif-0.2.49}/setup.py +1 -1
  10. {geocif-0.2.47 → geocif-0.2.49}/LICENSE +0 -0
  11. {geocif-0.2.47 → geocif-0.2.49}/MANIFEST.in +0 -0
  12. {geocif-0.2.47 → geocif-0.2.49}/README.md +0 -0
  13. {geocif-0.2.47 → geocif-0.2.49}/geocif/__init__.py +0 -0
  14. {geocif-0.2.47 → geocif-0.2.49}/geocif/agmet/__init__.py +0 -0
  15. {geocif-0.2.47 → geocif-0.2.49}/geocif/agmet/geoagmet.py +0 -0
  16. {geocif-0.2.47 → geocif-0.2.49}/geocif/agmet/plot.py +0 -0
  17. {geocif-0.2.47 → geocif-0.2.49}/geocif/agmet/utils.py +0 -0
  18. {geocif-0.2.47 → geocif-0.2.49}/geocif/analysis.py +0 -0
  19. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/__init__.py +0 -0
  20. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/constants.py +0 -0
  21. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/features.py +0 -0
  22. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/geo.py +0 -0
  23. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/geocif.py +0 -0
  24. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/metadata.py +0 -0
  25. {geocif-0.2.47 → geocif-0.2.49}/geocif/backup/models.py +0 -0
  26. {geocif-0.2.47 → geocif-0.2.49}/geocif/cei/__init__.py +0 -0
  27. {geocif-0.2.47 → geocif-0.2.49}/geocif/cei/definitions.py +0 -0
  28. {geocif-0.2.47 → geocif-0.2.49}/geocif/cei/indices.py +0 -0
  29. {geocif-0.2.47 → geocif-0.2.49}/geocif/experiments.py +0 -0
  30. {geocif-0.2.47 → geocif-0.2.49}/geocif/geocif_runner.py +0 -0
  31. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_algeria.py +0 -0
  32. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_angola.py +0 -0
  33. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_madagascar.py +0 -0
  34. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_malawi.py +0 -0
  35. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_mozambique.py +0 -0
  36. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_south_africa.py +0 -0
  37. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_zambia.py +0 -0
  38. {geocif-0.2.47 → geocif-0.2.49}/geocif/indices_runner_zimbabwe.py +0 -0
  39. {geocif-0.2.47 → geocif-0.2.49}/geocif/logger.py +0 -0
  40. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/__init__.py +0 -0
  41. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/correlations.py +0 -0
  42. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/embedding.py +0 -0
  43. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/feature_engineering.py +0 -0
  44. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/feature_selection.py +0 -0
  45. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/outliers.py +0 -0
  46. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/outlook.py +0 -0
  47. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/output.py +0 -0
  48. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/spatial_autocorrelation.py +0 -0
  49. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/stages.py +0 -0
  50. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/trainers.py +0 -0
  51. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/trend.py +0 -0
  52. {geocif-0.2.47 → geocif-0.2.49}/geocif/ml/xai.py +0 -0
  53. {geocif-0.2.47 → geocif-0.2.49}/geocif/mm.py +0 -0
  54. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/__init__.py +0 -0
  55. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/area.py +0 -0
  56. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/automl.py +0 -0
  57. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/download_esi.py +0 -0
  58. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/enso.py +0 -0
  59. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/eval.py +0 -0
  60. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/gamtest.py +0 -0
  61. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/gee_access.py +0 -0
  62. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/misc.py +0 -0
  63. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/play_xagg.py +0 -0
  64. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/reg.py +0 -0
  65. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/sustain.py +0 -0
  66. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/test_catboost.py +0 -0
  67. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/tmp.py +0 -0
  68. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/tmp2.py +0 -0
  69. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/tmp3.py +0 -0
  70. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/tmp4.py +0 -0
  71. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/tmp5.py +0 -0
  72. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/wolayita.py +0 -0
  73. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/wolayita_maize_mask.py +0 -0
  74. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/wolayita_v2.py +0 -0
  75. {geocif-0.2.47 → geocif-0.2.49}/geocif/playground/wolayita_v3.py +0 -0
  76. {geocif-0.2.47 → geocif-0.2.49}/geocif/risk/__init__.py +0 -0
  77. {geocif-0.2.47 → geocif-0.2.49}/geocif/risk/impact_assessment.py +0 -0
  78. {geocif-0.2.47 → geocif-0.2.49}/geocif/utils.py +0 -0
  79. {geocif-0.2.47 → geocif-0.2.49}/geocif/viz/__init__.py +0 -0
  80. {geocif-0.2.47 → geocif-0.2.49}/geocif/viz/gt.py +0 -0
  81. {geocif-0.2.47 → geocif-0.2.49}/geocif/viz/plot.py +0 -0
  82. {geocif-0.2.47 → geocif-0.2.49}/geocif/viz/tmp.py +0 -0
  83. {geocif-0.2.47 → geocif-0.2.49}/geocif/viz/viz_ml.py +0 -0
  84. {geocif-0.2.47 → geocif-0.2.49}/geocif.egg-info/dependency_links.txt +0 -0
  85. {geocif-0.2.47 → geocif-0.2.49}/geocif.egg-info/not-zip-safe +0 -0
  86. {geocif-0.2.47 → geocif-0.2.49}/geocif.egg-info/top_level.txt +0 -0
  87. {geocif-0.2.47 → geocif-0.2.49}/requirements.txt +0 -0
  88. {geocif-0.2.47 → geocif-0.2.49}/setup.cfg +0 -0
  89. {geocif-0.2.47 → geocif-0.2.49}/tests/test_geocif.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geocif
3
- Version: 0.2.47
3
+ Version: 0.2.49
4
4
  Summary: Models to visualize and forecast crop conditions and yields
5
5
  Home-page: https://ritviksahajpal.github.io/yield_forecasting/
6
6
  Author: Ritvik Sahajpal
@@ -844,8 +844,6 @@ class Geocif:
844
844
  # Some models cannot handle any NaN values, so gapfill them
845
845
  if self.model_name in ["gam", "linear"]:
846
846
  for col in self.X_train.columns:
847
- if self.X_train[col].isnull().any():
848
- breakpoint()
849
847
  median = self.X_train[col].median()
850
848
  self.X_train[col].fillna(median, inplace=True)
851
849
 
@@ -165,7 +165,7 @@ class cei_runner(base.BaseGeo):
165
165
  combinations = [
166
166
  i
167
167
  for i in combinations
168
- if "ethiopia" in i[3]
168
+ # if "ethiopia" in i[3]
169
169
  # or "lesotho_maize" in i[3] or
170
170
  # # "namibia_" in i[2] or
171
171
  # "united_republic_of_tanzania_maize" in i[3]
@@ -174,8 +174,8 @@ class cei_runner(base.BaseGeo):
174
174
  # or "south_africa_maize" in i[3]
175
175
  # or "mozambique_maize" in i[3]
176
176
  # or "united_states_of_america" in i[3]
177
- #or "russian_federation" in i[3]
178
- # or "ukraine" in i[3]
177
+ if "russian_federation" in i[3]
178
+ or "ukraine" in i[3]
179
179
  ]
180
180
  # "malawi" in i[2]]
181
181
 
@@ -203,9 +203,9 @@ def add_statistics(
203
203
  fn = "illinois.csv"
204
204
  elif country == "Ethiopia":
205
205
  # HACK
206
- fn = "adm_crop_production.csv"
206
+ fn = "hvstat_africa_data_v1.0.csv"
207
207
  else:
208
- fn = "adm_crop_production.csv"
208
+ fn = "hvstat_africa_data_v1.0.csv"
209
209
  df_fewsnet = pd.read_csv(dir_stats / fn, low_memory=False)
210
210
  # HACK
211
211
  if country == "Afghanistan":
@@ -220,6 +220,10 @@ def add_statistics(
220
220
  # Check if country and crop exist in the fewsnet database
221
221
  mask = (df_fewsnet["country"] == country) & (df_fewsnet["product"] == crop)
222
222
 
223
+ # If qc_flag column exists, filter out rows with qc_flag != 0
224
+ if "qc_flag" in df_fewsnet.columns:
225
+ df_fewsnet = df_fewsnet[df_fewsnet["qc_flag"] == 0]
226
+
223
227
  if mask.sum() == 0:
224
228
  df = add_GEOGLAM_statistics(dir_stats, df, stats, method, admin_zone)
225
229
  else:
@@ -241,6 +245,7 @@ def add_statistics(
241
245
  "All (PS)",
242
246
  "irrigated",
243
247
  "rainfed",
248
+ "Rainfed (PS)"
244
249
  ]
245
250
  )
246
251
  & (df_fewsnet["harvest_year"] == harvest_year)
@@ -256,20 +261,14 @@ def add_statistics(
256
261
  "Winter",
257
262
  ]
258
263
  )
259
- & (df_fewsnet["indicator"].isin(["yield", "area", "production"]))
260
264
  )
261
265
 
262
- # Fetching values for each indicator
263
- yield_value = df_fewsnet.loc[
264
- mask_yield & mask_region & (df_fewsnet["indicator"] == "yield"), "value"
265
- ]
266
- area_value = df_fewsnet.loc[
267
- mask_yield & mask_region & (df_fewsnet["indicator"] == "area"), "value"
268
- ]
269
- prod_value = df_fewsnet.loc[
270
- mask_yield & mask_region & (df_fewsnet["indicator"] == "production"),
271
- "value",
272
- ]
266
+ # Fetching values for each statistic
267
+ mask_combined = mask_yield & mask_region
268
+
269
+ yield_value = df_fewsnet.loc[mask_combined, "yield"]
270
+ area_value = df_fewsnet.loc[mask_combined, "area"]
271
+ prod_value = df_fewsnet.loc[mask_combined, "production"]
273
272
 
274
273
  # Replace any inf or 0 values by NaN
275
274
  yield_value = yield_value.replace([0, np.inf, -np.inf], np.nan)
@@ -6,6 +6,96 @@ from pathlib import Path
6
6
 
7
7
  import pandas as pd
8
8
 
9
+ import pandas as pd
10
+
11
+ # Build mapping dict: ISO3 -> region
12
+ region_map = {}
13
+
14
+ # Helper to add many iso codes to same region
15
+ def add(codes, region):
16
+ for code in codes:
17
+ region_map[code] = region
18
+
19
+ # Region lists --------------------------------------------------
20
+ add(["USA", "CAN", "GRL"], "North America")
21
+
22
+ add([
23
+ "MEX","BLZ","GTM","HND","SLV","NIC","CRI","PAN",
24
+ "CUB","DOM","HTI","BHS","BRB","TTO","GRD","KNA",
25
+ "LCA","VCT","ATG","DMA","JAM"
26
+ ], "Central America and the Caribbean")
27
+
28
+ add([
29
+ "ARG","BOL","BRA","CHL","COL","ECU","GUY","PRY",
30
+ "PER","SUR","URY","VEN"
31
+ ], "South America")
32
+
33
+ add([
34
+ "ALB","AND","AUT","BEL","BIH","BLR","BGR","HRV","CYP","CZE",
35
+ "DNK","EST","FIN","FRA","DEU","GRC","HUN","ISL","IRL","ITA",
36
+ "LVA","LIE","LTU","LUX","MLT","MDA","MCO","MNE","NLD","MKD",
37
+ "NOR","POL","PRT","ROU","RUS","SRB","SVK","SVN","ESP","SWE",
38
+ "CHE","UKR","GBR","VAT","SMR","KOS" # KOS = Kosovo (XKX)
39
+ ], "Europe (Including all of Russia)")
40
+
41
+ add([
42
+ "DZA","EGY","LBY","MAR","TUN","ESH", # North Africa incl. W. Sahara
43
+ "ARE","BHR","IRN","IRQ","ISR","JOR","KWT",
44
+ "LBN","OMN","QAT","SAU","SYR","TUR","YEM","PSE"
45
+ ], "Middle East and North Africa")
46
+
47
+ # Sub-Saharan Africa = all AFR codes minus the five NA ones above; list explicitly
48
+ add([
49
+ "AGO","BEN","BWA","BFA","BDI","CMR","CPV","CAF","TCD",
50
+ "COM","COG","COD","CIV","DJI","GNQ","ERI","SWZ","ETH","GAB",
51
+ "GMB","GHA","GIN","GNB","KEN","LSO","LBR","MDG","MWI","MLI",
52
+ "MRT","MUS","MOZ","NAM","NER","NGA","RWA","STP","SEN","SYC",
53
+ "SLE","SOM","ZAF","SSD","SDN","TZA","TGO","UGA","ZMB","ZWE"
54
+ ], "Sub-Saharan Africa")
55
+
56
+ add(["KAZ","KGZ","TJK","TKM","UZB"], "Central Asia")
57
+
58
+ add(["AFG","BGD","BTN","IND","LKA","MDV","NPL","PAK"], "South Asia")
59
+
60
+ add(["CHN","JPN","PRK","KOR","MNG","TWN","HKG","MAC"], "East Asia")
61
+
62
+ add([
63
+ "BRN","KHM","IDN","LAO","MYS","MMR","PHL","SGP","THA","TLS","VNM"
64
+ ], "Southeast Asia")
65
+
66
+ add([
67
+ "AUS","NZL","PNG","FJI","SLB","VUT","WSM","TON","KIR","NRU",
68
+ "PLW","MHL","FSM","TUV"
69
+ ], "Oceania")
70
+
71
+ # Convert to DataFrame
72
+ df = pd.DataFrame(list(region_map.items()), columns=["iso3", "Region"]).sort_values("iso3")
73
+
74
+ # Save to CSV
75
+ csv_path = r"C:\Users\ritvik\Downloads\region_key_iso3.csv"
76
+ df.to_csv(csv_path, index=False)
77
+
78
+ breakpoint()
79
+
80
+ dg = gpd.read_file(r"C:\Users\ritvik\Downloads\Maize_1 (1).gpkg")
81
+ #df = pd.read_csv(r"C:\Users\ritvik\Downloads\Maize_1_Gauss5_2000-2020_modDFvar (1).csv", dtype={'UID': str})
82
+ df1 = pd.read_csv(r"C:\Users\ritvik\Downloads\crRiskIndicator_Maize_1_Gauss5_2000-2020 (1).csv", dtype={'UID': str})
83
+
84
+ # Assuming 'geometry' is the column containing the geometry in the GeoDataFrame dg
85
+ merged_df = dg.merge(df1[['UID', 'Cntry_Code', 'mnRsk', 'vrRsk','brRsk','corRsk','yvrRsk','risk','clim_risk','climCh_risk']], on=['UID', 'Cntry_Code'], how='left')
86
+ # Keep only the varRatio column and the geometry column from the merged GeoDataFrame
87
+ final_gdf = merged_df[['UID', 'Cntry_Code', 'mnRsk','vrRsk','brRsk','corRsk','yvrRsk','risk','clim_risk','climCh_risk', 'geometry']]
88
+
89
+ # drop rows where 'varRatio' is NaN
90
+ final_gdf = final_gdf.dropna(subset=['mnRsk','vrRsk','brRsk','corRsk','risk','yvrRsk', 'clim_risk','climCh_risk'])
91
+ # Save the final GeoDataFrame to a new GeoPackage
92
+ final_gdf.to_file(r"C:\Users\ritvik\Downloads\output_risk.shp")
93
+
94
+ # Output top 10 rows as a csv with geometry
95
+ #final_gdf.head(10).to_csv(r"C:\Users\ritvik\Downloads\output_top10.csv", index=False)
96
+
97
+ breakpoint()
98
+ #######################
9
99
  DATA_DIR = Path(r"C:\Users\ritvik\Downloads\exported_all_db")
10
100
 
11
101
  # Grab all maize CSV files (skip 'models.csv')
@@ -0,0 +1,165 @@
1
+ import geopandas as gpd
2
+ import holoviews as hv
3
+ import hvplot.pandas # registers .hvplot accessor
4
+ import panel as pn
5
+ hv.extension("bokeh"); pn.extension()
6
+
7
+ # ------------------------------------------------------------------
8
+ # 1. Paths
9
+ # ------------------------------------------------------------------
10
+ SHAPE_PATH = r"C:\Users\ritvik\Downloads\output.shp"
11
+ RISK_PATH = r"C:\Users\ritvik\Downloads\output_risk.shp"
12
+ LOGO_IMAGE = r"C:\Users\ritvik\Downloads\combined_logo.png"
13
+
14
+ # ------------------------------------------------------------------
15
+ # 2. Load & prep varRatio layer
16
+ # ------------------------------------------------------------------
17
+ gdf = gpd.read_file(SHAPE_PATH)
18
+ if "varRatio" not in gdf.columns:
19
+ raise KeyError("'varRatio' column missing in output.shp")
20
+
21
+ uid_col = "UID" if "UID" in gdf.columns else "index"
22
+ gdf[uid_col] = gdf.get(uid_col, gdf.index)
23
+ gdf["varRatio"] = gdf["varRatio"].round(2) # 2-decimals
24
+
25
+ # ------------------------------------------------------------------
26
+ # 3. Load & prep risk layer
27
+ # ------------------------------------------------------------------
28
+ risk_gdf = gpd.read_file(RISK_PATH)
29
+ risk_cols = ["risk", "yvrRsk", "clim_risk", "climCh_ris"]
30
+ missing = [c for c in risk_cols if c not in risk_gdf.columns]
31
+ if missing:
32
+ raise KeyError(f"Columns {missing} missing in output_risk.shp")
33
+
34
+ uid2 = "UID" if "UID" in risk_gdf.columns else "index"
35
+ risk_gdf[uid2] = risk_gdf.get(uid2, risk_gdf.index)
36
+ for c in risk_cols:
37
+ risk_gdf[c] = risk_gdf[c].round(2)
38
+
39
+ # ------------------------------------------------------------------
40
+ # 4. Widgets
41
+ # ------------------------------------------------------------------
42
+ country_opts = sorted(gdf["Cntry_Code"].dropna().unique())
43
+ default_val = "US" if "US" in country_opts else "All"
44
+
45
+ country_select = pn.widgets.Select(name="Country",
46
+ options=["All"] + country_opts,
47
+ value=default_val)
48
+
49
+ crop_select = pn.widgets.Select(name="Crop",
50
+ options=["Maize"],
51
+ value="Maize")
52
+
53
+ # ------------------------------------------------------------------
54
+ # 5. varRatio map
55
+ # ------------------------------------------------------------------
56
+ def make_varratio_map(country, crop):
57
+ data = gdf if country == "All" else gdf[gdf["Cntry_Code"] == country]
58
+ if data.empty:
59
+ return pn.pane.Markdown(f"**No data for {country}**")
60
+
61
+ vmin, vmax = data["varRatio"].min(), data["varRatio"].max()
62
+ if vmin == vmax: vmin -= 1e-6; vmax += 1e-6
63
+
64
+ return data.hvplot.polygons(
65
+ c="varRatio", tiles="CartoLight", cmap="Viridis",
66
+ clim=(vmin, vmax),
67
+ line_width=0.1,
68
+ hover_tooltips=[
69
+ #(uid_col, f"@{uid_col}"),
70
+ ("varRatio", "@varRatio{0.00}")
71
+ ],
72
+ colorbar=True,
73
+ toolbar='above',
74
+ line_color='white',
75
+ height=650, width=950,
76
+ title=f"varRatio – {country if country!='All' else 'All Countries'}",
77
+ ).opts(
78
+ hv.opts.Polygons(tools=['hover'], show_grid=False, show_frame=False, toolbar='below',
79
+ line_color='white'))
80
+
81
+ varratio_panel = pn.bind(make_varratio_map, country_select, crop_select)
82
+
83
+ # ------------------------------------------------------------------
84
+ # 6. Helpers to build 4-map risk grid
85
+ # ------------------------------------------------------------------
86
+ def _risk_layer(df, col, title):
87
+ vmin, vmax = df[col].min(), df[col].max()
88
+
89
+ # …then force a symmetric range around 0 so the colourbar is centred
90
+ abs_max = max(abs(vmin), abs(vmax))
91
+ vmin, vmax = -abs_max, abs_max # 0 now sits in the middle
92
+
93
+ return df.hvplot.polygons(
94
+ c=col,
95
+ cmap="PiYG_r",
96
+ clim=(vmin, vmax),
97
+ tiles="CartoLight",
98
+ line_width=0.1,
99
+ hover_tooltips=[
100
+ #(uid2, f"@{uid2}"),
101
+ (col, f"@{col}{{0.00}}")
102
+ ],
103
+ colorbar=True,
104
+ height=325,
105
+ width=450,
106
+ title=title
107
+ ).opts(
108
+ hv.opts.Polygons(tools=['hover'], show_grid=False, show_frame=False, toolbar='below',
109
+ line_color='white'))
110
+
111
+ pn.extension(
112
+ raw_css=[
113
+ """
114
+ /* tighten row/column/grid gaps */
115
+ .tight {
116
+ gap: 4px !important; /* space between children */
117
+ }
118
+ """
119
+ ]
120
+ )
121
+
122
+ def make_risk_panel(country, crop):
123
+ data = risk_gdf if country == "All" else risk_gdf[risk_gdf["Cntry_Code"] == country]
124
+ if data.empty:
125
+ return pn.pane.Markdown(f"**No risk data for {country}**")
126
+
127
+ maps = [
128
+ _risk_layer(data, "risk", "Composite Risk Indicator"),
129
+ _risk_layer(data, "yvrRsk", "Historical Yield Variance Risk Indicator"),
130
+ _risk_layer(data, "clim_risk", "Growing Season Climate Risk Indicator"),
131
+ _risk_layer(data, "climCh_ris", "Climate Change Risk Indicator"),
132
+ ]
133
+
134
+ return pn.GridBox(
135
+ *maps,
136
+ ncols=2,
137
+ sizing_mode="stretch_both",
138
+ css_classes=["tight"], # ← activates the new 4-px gap rule
139
+ margin=0 # (optional) remove outer margin
140
+ )
141
+
142
+
143
+ risk_panel = pn.bind(make_risk_panel, country_select, crop_select)
144
+
145
+ # ------------------------------------------------------------------
146
+ # 7. Template
147
+ # ------------------------------------------------------------------
148
+ template = pn.template.FastListTemplate(
149
+ title="Climate Risk Dashboard",
150
+ sidebar=[
151
+ country_select, crop_select, pn.Spacer(height=20),
152
+ pn.pane.Image(LOGO_IMAGE, width=240, height=360, align="center")
153
+ ],
154
+ main=[
155
+ pn.Tabs(
156
+ ("varRatio", varratio_panel),
157
+ ("Risk Indicator", risk_panel)
158
+ )
159
+ ],
160
+ header_background="lightblue",
161
+ accent_base_color="#1f77b4",
162
+ main_max_width="100%"
163
+ )
164
+
165
+ template.servable()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geocif
3
- Version: 0.2.47
3
+ Version: 0.2.49
4
4
  Summary: Models to visualize and forecast crop conditions and yields
5
5
  Home-page: https://ritviksahajpal.github.io/yield_forecasting/
6
6
  Author: Ritvik Sahajpal
@@ -56,6 +56,7 @@ geocif/ml/trend.py
56
56
  geocif/ml/xai.py
57
57
  geocif/playground/__init__.py
58
58
  geocif/playground/aa.py
59
+ geocif/playground/aaaa.py
59
60
  geocif/playground/area.py
60
61
  geocif/playground/automl.py
61
62
  geocif/playground/download_esi.py
@@ -50,6 +50,6 @@ setup(
50
50
  test_suite="tests",
51
51
  tests_require=test_requirements,
52
52
  url="https://ritviksahajpal.github.io/yield_forecasting/",
53
- version="0.2.47",
53
+ version="0.2.49",
54
54
  zip_safe=False,
55
55
  )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes