23
23
load_eruption_style_analogy ,
24
24
load_volcano_names )
25
25
26
+
27
+ # Define custom message formatter for warnings
28
+ def _format_pyvolcans_warning (message , * args , ** kwargs ):
29
+ """
30
+ Format warnings into PyVOLCANS style, discarding all but the
31
+ message.
32
+ """
33
+ return f"\n UserWarning (PyVOLCANS): { message } \n "
34
+
35
+
36
+ # Replace built-in warning format function
37
+ warnings .formatwarning = _format_pyvolcans_warning
38
+
26
39
# fuzzywuzzy would like to use a sequence matcher provided by the
27
40
# Python-Levenshtein package, but this has dependencies that require
28
41
# compilation. When it is not installed, it uses the matcher provided
@@ -364,19 +377,13 @@ def calculate_weighted_analogy_matrix(my_volcano, weights,
364
377
weights (or weighting scheme) that is chosen by the user for each
365
378
particular run of PyVOLCANS. A different weighting scheme can generate
366
379
an entirely different set of total analogy values.
367
-
368
- my_volcano_data_dictionary : dict
369
- Dictionary containing information on whether there is volcanological
370
- data available (dict_value = 1), or there is not (dict_value = 0); for
371
- each of the volcanological criteria used by PyVOLCANS, considering the
372
- specific target volcano chosen by the user to run the program.
373
380
"""
374
381
375
382
# get the index for my_volcano
376
383
volcano_idx = convert_to_idx (my_volcano )
377
384
378
385
# check for volcanological criteria without data for the target volcano
379
- my_volcano_data_dictionary = {} # empty dictionary
386
+ my_volcano_data_dictionary = {}
380
387
# NB. If the single-criterion analogy of the target volcano with itself is
381
388
# equal to zero, then there is no data available for that particular
382
389
# volcanological criterion
@@ -389,6 +396,11 @@ def calculate_weighted_analogy_matrix(my_volcano, weights,
389
396
my_volcano_data_dictionary [criterion ] = \
390
397
my_volcano_single_analogies [volcano_idx ]
391
398
399
+ # check for volcanological criteria without data for target volcano
400
+ warn_on_criteria_without_data (my_volcano_data_dictionary ,
401
+ my_volcano ,
402
+ weights )
403
+
392
404
# calculate single-criterion analogy matrices for specific weighting scheme
393
405
weighted_tectonic_analogy = \
394
406
weights ['tectonic_setting' ] * analogies ['tectonic_setting' ]
@@ -426,7 +438,7 @@ def calculate_weighted_analogy_matrix(my_volcano, weights,
426
438
volcans_result ['ASt' ] = \
427
439
weighted_eruption_style_analogy [volcano_idx , ]
428
440
429
- return volcans_result , my_volcano_data_dictionary
441
+ return volcans_result
430
442
431
443
432
444
def get_analogies (my_volcano , volcans_result , count = 10 ):
@@ -481,10 +493,10 @@ def get_analogies(my_volcano, volcans_result, count=10):
481
493
return filtered_result , volcano_name
482
494
483
495
484
- def check_for_perfect_analogues (result ):
496
+ def warn_on_perfect_analogues (result ):
485
497
"""
486
498
Assesses whether all the calculated top analogue volcanoes share the same
487
- value of total analogy, and raises a PyvolcansError exception if that is
499
+ value of total analogy, and raises UserWarning if that is
488
500
the case.
489
501
490
502
Parameters
@@ -493,36 +505,23 @@ def check_for_perfect_analogues(result):
493
505
Sub-set of results from the Pandas dataframe volcans_result,
494
506
thus only including the data for the top analogue volcanoes
495
507
to the target volcano.
496
-
497
- Raises
498
- -------
499
- PyvolcansError
500
- If all the top analogue volcanoes have the same value of total analogy.
501
- This observation may be related to issues with the data available for
502
- the target volcano (and/or analogue volcanoes), but can also be
503
- indicative of the fact that the weighting scheme selected is too
504
- simplified, or not informative enough (e.g. a single-criterion search
505
- of volcanoes on subduction zones under continental crust will yield
506
- hundreds of volcanoes that share that same characteristic. Please see
507
- Tierz et al., 2019, for more details)
508
508
"""
509
509
510
510
maximum_analogy = result ['total_analogy' ].iloc [0 ]
511
511
if result ['total_analogy' ].eq (maximum_analogy ).all ():
512
- msg = ("WARNING!!! "
513
- "All top analogue volcanoes have the same value "
512
+ msg = ("All top analogue volcanoes have the same value "
514
513
"of total analogy. Please be aware of possible "
515
514
"data deficiencies and/or the use of a simplified "
516
515
"weighting scheme (see Tierz et al., 2019, for more "
517
- "details).\n " )
518
- raise PyvolcansError (msg )
516
+ "details)." )
517
+ warnings . warn (msg )
519
518
520
519
521
- def check_for_criteria_without_data (my_volcano_data , my_volcano_name ):
520
+ def warn_on_criteria_without_data (my_volcano_data , my_volcano_name , weights ):
522
521
"""
523
522
Assesses whether some volcanological criteria do not have any data for the
524
- specific target volcano chosen by the user, raising a PyvolcansError
525
- exception if this is the case, informing the user which are these criteria.
523
+ specific target volcano chosen by the user, raising a UserWarning
524
+ if this is the case, informing the user which are these criteria.
526
525
527
526
Parameters
528
527
----------
@@ -533,33 +532,25 @@ def check_for_criteria_without_data(my_volcano_data, my_volcano_name):
533
532
data available (dict_value = 1), or there is not (dict_value = 0); for
534
533
each of the volcanological criteria used by PyVOLCANS, considering the
535
534
specific target volcano chosen by the user to run the program.
536
-
537
- Raises
538
- -------
539
- PyvolcansError
540
- If one or more volcanological criteria have no data available for the
541
- selected target volcano.
535
+ weights : dict
536
+ Set of weights (weighting scheme) selected by the user to run PyVOLCANS
542
537
"""
543
-
544
- # based on:
545
- # https://thispointer.com/python-how-to-find-keys-by-value-in-dictionary
538
+ my_flag_list = ['-Ts' , '-G' , '-M' , '-Sz' , '-St' ]
546
539
my_list_keys = list ()
547
- my_list_items = my_volcano_data .items ()
548
- for item in my_list_items :
549
- if item [1 ] == 0 :
550
- my_list_keys .append (item [0 ])
540
+ for (key , value ), flag in zip (my_volcano_data .items (), my_flag_list ):
541
+ if value == 0 and weights [key ] > 0 :
542
+ my_list_keys .append (f'{ key } ({ flag } )' )
551
543
552
544
# check whether the list is not empty (in other words, there are some
553
545
# volcanological criteria without data)
554
546
if my_list_keys :
555
547
nodata_criteria_text = ', ' .join (my_list_keys )
556
- msg = ("WARNING!!! "
557
- "The following volcanological criteria do not have "
548
+ msg = ("The following selected criteria do not have "
558
549
"any data available for the selected target volcano "
559
- f"({ my_volcano_name } ): { nodata_criteria_text } . Please "
550
+ f"({ my_volcano_name } ) --> { nodata_criteria_text } . Please "
560
551
"consider excluding these criteria from your weighting scheme "
561
552
"(i.e. setting their weights to zero)." )
562
- raise PyvolcansError (msg )
553
+ warnings . warn (msg )
563
554
564
555
565
556
def open_gvp_website (top_analogue_vnum ):
@@ -733,22 +724,22 @@ def plot_bar_apriori_analogues(my_volcano_name, my_volcano_vnum,
733
724
# slice volcans_result to derive a data frame with the a priori analogues
734
725
all_my_apriori_analogies = \
735
726
volcans_result .loc [my_apriori_volcano_idx ,
736
- ['name' ,'ATs' ,'AG' ,'AM' ,'ASz' ,'ASt' ]]
727
+ ['name' , 'ATs' , 'AG' , 'AM' , 'ASz' , 'ASt' ]]
737
728
738
729
# plot single- and total-analogy values for all a priori analogues
739
730
my_apriori_analogues_plot = \
740
731
all_my_apriori_analogies .plot .bar (x = "name" ,
741
- y = ["ATs" ,"AG" ,"AM" ,"ASz" ,"ASt" ],
732
+ y = ["ATs" , "AG" , "AM" , "ASz" , "ASt" ],
742
733
stacked = True )
743
734
744
735
fig1 = plt .gcf ()
745
- my_apriori_analogues_plot .set_ylim ([0 ,1 ])
736
+ my_apriori_analogues_plot .set_ylim ([0 , 1 ])
746
737
plt .title (f"A priori analogues: { my_volcano_name } ({ my_volcano_vnum } )" ,
747
738
y = 1.15 , pad = 5 )
748
739
plt .xlabel (None )
749
740
plt .ylabel ('Total Analogy' )
750
741
plt .legend (bbox_to_anchor = (0.9 , 1.16 ), ncol = 5 )
751
- plt .tight_layout () # ensuring labels/titles are displayed properly
742
+ plt .tight_layout () # ensuring labels/titles are displayed properly
752
743
753
744
if save_figure :
754
745
fig1 .savefig (
@@ -758,6 +749,7 @@ def plot_bar_apriori_analogues(my_volcano_name, my_volcano_vnum,
758
749
759
750
return all_my_apriori_analogies
760
751
752
+
761
753
def plot_bar_better_analogues (my_volcano_name , my_volcano_vnum ,
762
754
better_analogues , criteria_weights_text ,
763
755
save_figure = None ):
@@ -807,15 +799,13 @@ def plot_bar_better_analogues(my_volcano_name, my_volcano_vnum,
807
799
y = "percentage_better" ,
808
800
legend = False ,
809
801
title = f"Better analogues: { my_volcano_name } ({ my_volcano_vnum } )" ,
810
- ylim = [0 ,50 ])
802
+ ylim = [0 , 50 ])
811
803
plt .xlabel (None )
812
804
plt .ylabel ('Percentage of better analogues' )
813
805
plt .tight_layout ()
814
806
if save_figure :
815
- plt .savefig (
816
- (f"{ my_volcano_name } _better_analogues_"
817
- f"{ criteria_weights_text } .png" ),
818
- dpi = 600 )
807
+ filename = (f"{ my_volcano_name } _better_analogues_{ criteria_weights_text } .png" )
808
+ plt .savefig (filename , dpi = 600 )
819
809
820
810
return df_better_analogues
821
811
0 commit comments