@@ -758,12 +758,16 @@ def create_bivariate_legend(bivariate_colors, poverty_label, hazard_label, num_q
758758
759759 # Set labels at the middle of each axis with color information
760760 ax .text (num_quantiles / 2 , - 0.7 , f"{ poverty_label } ({ poverty_color } )" , ha = 'center' , va = 'center' , fontsize = 12 )
761- ax .text (- 0.7 , num_quantiles / 2 , f"{ hazard_label } ({ hazard_color } )" , ha = 'center' , va = 'center' , rotation = 90 , fontsize = 12 )
761+ ax .text (- 1.2 , num_quantiles / 2 , f"{ hazard_label } ({ hazard_color } )" , ha = 'center' , va = 'center' , rotation = 90 , fontsize = 12 )
762762
763- # Adjust "Low" and "High" positions for both axes to put "High" at the end
764- # For exposure to hazard (y-axis): Low at bottom, High at top
765- ax .text (- 0.3 , 0 , "Low" , ha = 'right' , va = 'center' , fontsize = 10 ) # Hazard low (bottom)
766- ax .text (- 0.3 , num_quantiles , "High" , ha = 'right' , va = 'center' , fontsize = 10 ) # Hazard high (top)
763+ # Calculate percentage labels for fixed scale exposure
764+ max_exposure = 0.40 # 40%
765+ exposure_percentages = [f"{ x * 100 :.1f} %" for x in np .linspace (0 , max_exposure , num_quantiles + 1 )]
766+
767+ # For exposure (y-axis): Add percentage labels at each level
768+ # Position further to the left to avoid overlap
769+ for i in range (num_quantiles + 1 ):
770+ ax .text (- 0.1 , i , exposure_percentages [i ], ha = 'right' , va = 'center' , fontsize = 10 )
767771
768772 # For poverty (x-axis): Low at left, High at right
769773 ax .text (0 , - 0.3 , "Low" , ha = 'center' , va = 'top' , fontsize = 10 ) # Poverty low (left)
@@ -773,7 +777,7 @@ def create_bivariate_legend(bivariate_colors, poverty_label, hazard_label, num_q
773777 plt .title (f"Bivariate Legend: { hazard_color } -{ poverty_color } " , fontsize = 12 )
774778
775779 # Set axis limits with more space for labels
776- ax .set_xlim (- 1.2 , num_quantiles + 0.2 )
780+ ax .set_xlim (- 1.5 , num_quantiles + 0.2 )
777781 ax .set_ylim (- 1.2 , num_quantiles + 0.2 )
778782
779783 plt .tight_layout ()
@@ -1333,18 +1337,24 @@ def export_static_map(gdf, colors_list, output_path, num_quantiles, bivariate_pa
13331337 )
13341338 )
13351339
1336- # Add labels for the axes
1340+ # Add labels for the axes with proper positioning
13371341 legend_ax .text (num_quantiles / 2 , - 0.7 , f"Poverty ({ poverty_color } )" , ha = 'center' , va = 'center' , fontsize = 12 )
1338- legend_ax .text (- 0.7 , num_quantiles / 2 , f"Hazard ({ hazard_color } )" , ha = 'center' , va = 'center' , rotation = 90 , fontsize = 12 )
1342+ legend_ax .text (- 1.2 , num_quantiles / 2 , f"Exposure ({ hazard_color } )" , ha = 'center' , va = 'center' , rotation = 90 , fontsize = 12 )
1343+
1344+ # Calculate percentage labels for fixed scale exposure
1345+ max_exposure = 0.40 # 40%
1346+ exposure_percentages = [f"{ x * 100 :.1f} %" for x in np .linspace (0 , max_exposure , num_quantiles + 1 )]
13391347
1340- # Add "Low" and "High" labels
1341- legend_ax .text (0 , - 0.3 , "Low" , ha = 'center' , va = 'top' , fontsize = 10 )
1342- legend_ax .text (num_quantiles , - 0.3 , "High" , ha = 'center' , va = 'top' , fontsize = 10 )
1343- legend_ax .text (- 0.3 , 0 , "Low" , ha = 'right' , va = 'center' , fontsize = 10 )
1344- legend_ax .text (- 0.3 , num_quantiles , "High" , ha = 'right' , va = 'center' , fontsize = 10 )
1348+ # For exposure (y-axis): Add percentage labels at each level
1349+ for i in range (num_quantiles + 1 ):
1350+ legend_ax .text (- 0.1 , i , exposure_percentages [i ], ha = 'right' , va = 'center' , fontsize = 10 )
1351+
1352+ # Add "Low" and "High" labels only for the poverty axis
1353+ legend_ax .text (0 , - 0.3 , "Low" , ha = 'center' , va = 'top' , fontsize = 10 ) # Poverty low (left)
1354+ legend_ax .text (num_quantiles , - 0.3 , "High" , ha = 'center' , va = 'top' , fontsize = 10 ) # Poverty high (right)
13451355
13461356 # Set limits for legend with more space for labels
1347- legend_ax .set_xlim (- 1.2 , num_quantiles + 0.2 )
1357+ legend_ax .set_xlim (- 1.5 , num_quantiles + 0.2 )
13481358 legend_ax .set_ylim (- 1.2 , num_quantiles + 0.2 )
13491359
13501360 # Add a title to the legend
@@ -1454,10 +1464,50 @@ def run_analysis(b):
14541464 gdf ['relative_exposure' ] = gdf [hazard_field ] / gdf [pop_field ]
14551465 print (f"Relative Exposure Range: { gdf ['relative_exposure' ].min ():.6f} to { gdf ['relative_exposure' ].max ():.6f} \n " )
14561466
1457- # Create quantile classifications (using relative exposure)
1458- print (f"Creating { num_quantiles } ×{ num_quantiles } quantile classifications..." )
1459- gdf = classify_data (gdf , 'w_RWIxPOP_scaled' , 'relative_exposure' , num_quantiles )
1460-
1467+ # Instead of using quantiles, use a fixed scale from 0% to 40% for exposure
1468+ print (f"Creating fixed-scale classification for exposure (0-40%)..." )
1469+ # Calculate fixed scale breaks for exposure (0% to 40%)
1470+ exposure_max = 0.40 # 40%
1471+ exposure_breaks = np .linspace (0 , exposure_max , num_quantiles + 1 )
1472+ exposure_percentages = [f"{ x * 100 :.1f} %" for x in exposure_breaks ]
1473+ print (f"Exposure scale breaks: { ', ' .join (exposure_percentages )} " )
1474+
1475+ # Create wealth quantiles normally
1476+ try :
1477+ # Create wealth quantiles using standard method
1478+ gdf ['wealth_quantile' ] = pd .qcut (
1479+ gdf ['w_RWIxPOP_scaled' ],
1480+ q = num_quantiles ,
1481+ labels = False ,
1482+ duplicates = 'drop'
1483+ )
1484+ except Exception as e :
1485+ print (f"Error in wealth quantile calculation: { str (e )} " )
1486+ print ("Using manual quantile calculation..." )
1487+ wealth_values = gdf ['w_RWIxPOP_scaled' ].values
1488+ gdf ['wealth_quantile' ] = np .digitize (
1489+ wealth_values ,
1490+ np .percentile (wealth_values , np .linspace (0 , 100 , num_quantiles + 1 )[1 :- 1 ]),
1491+ right = True
1492+ )
1493+
1494+ # Manually classify exposure using fixed scale
1495+ gdf ['hazard_quantile' ] = pd .cut (
1496+ gdf ['relative_exposure' ],
1497+ bins = exposure_breaks ,
1498+ labels = False ,
1499+ include_lowest = True
1500+ )
1501+
1502+ # Handle values above the max scale (40%)
1503+ above_max = gdf ['relative_exposure' ] > exposure_max
1504+ if above_max .any ():
1505+ print (f"Warning: { above_max .sum ()} features have exposure above { exposure_max * 100 :.1f} % and are classified in the highest category" )
1506+ gdf .loc [above_max , 'hazard_quantile' ] = num_quantiles - 1
1507+
1508+ # Create combined classification
1509+ gdf ['bivariate_class' ] = gdf ['wealth_quantile' ] * num_quantiles + gdf ['hazard_quantile' ]
1510+
14611511 # Generate bivariate color scheme
14621512 print ("Generating bivariate color scheme with enhanced saturation..." )
14631513 bivariate_colors , colors_list = create_bivariate_colormap (bivariate_palette , num_quantiles )
0 commit comments