@@ -257,6 +257,7 @@ def plot_shiny(
257257 inp : Input | None = None ,
258258 impf_plot_kwargs : Mapping [str , Any ] | None = None ,
259259 hazard_plot_kwargs : Mapping [str , Any ] | None = None ,
260+ legend : bool = True ,
260261 ):
261262 """Plot all impact functions with appropriate color coding and event data"""
262263 # Store data to plot
@@ -271,9 +272,15 @@ def plot_shiny(
271272 f"impf_id: { impf_id } "
272273 )
273274
274- region_id = country_to_iso (row [("Event" , "region_id" )])
275- event_name = row [("Event" , "event_name" )]
276- event_id = row [("Event" , "event_id" )]
275+ def single_entry (arr ):
276+ """If ``arr`` has a single entry, return it, else ``arr`` itself"""
277+ if len (arr ) == 1 :
278+ return arr [0 ]
279+ return arr
280+
281+ region_id = single_entry (country_to_iso (row [("Event" , "region_id" )]))
282+ event_name = single_entry (row [("Event" , "event_name" )])
283+ event_id = single_entry (row [("Event" , "event_id" )])
277284
278285 label = f"{ event_name } , { region_id } , { event_id } "
279286 if len (event_name ) > 1 or len (event_id ) > 1 :
@@ -289,15 +296,26 @@ def plot_shiny(
289296
290297 # Create plot
291298 _ , ax = plt .subplots ()
299+ legend_xpad = 0
292300
293301 # Plot hazard histogram
294302 # NOTE: Actually requires selection by exposure, but this is not trivial!
295303 if inp is not None :
304+ # Create secondary axis
296305 ax2 = ax .twinx ()
306+ ax2 .set_zorder (1 )
307+ ax .set_zorder (2 )
308+ ax .set_facecolor ("none" )
309+ legend_xpad = 0.15
310+
311+ # Draw histogram
297312 hist_kwargs = {"bins" : 40 , "color" : "grey" , "alpha" : 0.5 }
298313 if hazard_plot_kwargs is not None :
299314 hist_kwargs .update (hazard_plot_kwargs )
300315 ax2 .hist (inp .hazard .intensity .data , ** hist_kwargs )
316+ ax2 .set_ylabel ("Intensity Count" , color = hist_kwargs ["color" ])
317+ ax2 .tick_params (axis = "y" , colors = hist_kwargs ["color" ])
318+
301319 elif hazard_plot_kwargs is not None :
302320 LOGGER .warning ("No 'inp' parameter provided. Ignoring 'hazard_plot_kwargs'" )
303321
@@ -320,16 +338,17 @@ def plot_shiny(
320338 ax .set_title (f"{ haz_type } { impf_id } " )
321339 ax .yaxis .set_major_formatter (mticker .PercentFormatter (xmax = 1 ))
322340 ax .set_ylim (0 , 1 )
323- ax .legend (
324- bbox_to_anchor = (1.05 , 1 ),
325- borderaxespad = 0 ,
326- borderpad = 0 ,
327- loc = "upper left" ,
328- title = "Event Name, Country, Event ID" ,
329- frameon = False ,
330- fontsize = "xx-small" ,
331- title_fontsize = "x-small" ,
332- )
341+ if legend :
342+ ax .legend (
343+ bbox_to_anchor = (1.05 + legend_xpad , 1 ),
344+ borderaxespad = 0 ,
345+ borderpad = 0 ,
346+ loc = "upper left" ,
347+ title = "Event Name, Country, Event ID" ,
348+ frameon = False ,
349+ fontsize = "xx-small" ,
350+ title_fontsize = "x-small" ,
351+ )
333352
334353 return ax
335354
@@ -511,16 +530,21 @@ class AverageEnsembleOptimizer(EnsembleOptimizer):
511530 The number of calibration tasks to perform
512531 random_state : int
513532 The seed for the random number generator selecting the samples
533+ replace : bool
534+ If samples of the impact data should be drawn with replacement
514535 """
515536
516537 sample_fraction : InitVar [float ] = 0.8
517538 ensemble_size : InitVar [int ] = 20
518539 random_state : InitVar [int ] = 1
540+ replace : InitVar [bool ] = False
519541
520- def __post_init__ (self , sample_fraction , ensemble_size , random_state ):
542+ def __post_init__ (self , sample_fraction , ensemble_size , random_state , replace ):
521543 """Create the samples"""
522- if sample_fraction <= 0 or sample_fraction >= 1 :
523- raise ValueError ("Sample fraction must be in (0, 1)" )
544+ if sample_fraction <= 0 :
545+ raise ValueError ("Sample fraction must be larger than 0" )
546+ elif sample_fraction > 1 and not replace :
547+ raise ValueError ("Sample fraction must be <=1 or replace must be True" )
524548 if ensemble_size < 1 :
525549 raise ValueError ("Ensemble size must be >=1" )
526550
@@ -532,7 +556,7 @@ def __post_init__(self, sample_fraction, ensemble_size, random_state):
532556 # Create samples
533557 rng = default_rng (random_state )
534558 self .samples = [
535- rng .choice (notna_idx , size = num_samples , replace = False )
559+ rng .choice (notna_idx , size = num_samples , replace = replace )
536560 for _ in range (ensemble_size )
537561 ]
538562
0 commit comments