Source code for pyValEIA.plots.mad_stat_plots

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# DISTRIBUTION STATEMENT A: Approved for public release. Distribution is
# unlimited.
# ----------------------------------------------------------------------------
"""Functions for visualizing Madrigal TEC EIA statistics."""

import numpy as np
import matplotlib.pyplot as plt
import warnings

from pyValEIA.stats import skill_score


[docs] def Mad_LSS_plot(model1, eia_type, date_range, model_name='Model', PorC='PC', DayNight=True, LT_range='day', coin=True): """Plot LSS vs CSI or PC 4 panels (one for each LSS) for 1 model alone. Parameters ---------- model1 : pd.DataFrame model DataFrame built by states_report_swarm eia_type : str desired eia type for fig title date_range : datetime range For plotting title purposes model_name : str kwarg first model name for labelling purposes PorC : str kwarg Percent correct or Critical success index for x axes DayNight : bool kwarg True (default) if panels should have separate markers for day and night otherwise (false) all are plotted together LT_range : list-like or str Range of day night local time, or 'day' for 7 LT to 19 LT and 'night' for 19 LT to 7 LT (default='day') coin : bool kwarg If True, coin LSS will be plotted for comparison (default) if false, coin LSS will not be plotted Returns ------- fig : fig handle 4 panel figure (one for each LSS) Raises ------ ValueError Unexpected input values Notes ----- LSS is only useful in comparison to another model, therefore, coin set to True is highly recommended! """ if LT_range == 'day': LT_range = [7, 19] elif LT_range == 'night': LT_range = [19, 7] elif len(LT_range) != 2: raise ValueError('unknown LT range: {:}'.format(LT_range)) # Print Warning if coin is set to False if not coin: warnings.warn("Warning: Coin is False! LSS is a comparison tool!") # Set date array for given time range date_array = date_range.to_pydatetime() # let's make a plot of changing PC or CSI fig, axs = plt.subplots(2, 2, figsize=(11, 11)) look = ['All'] cols1 = ['blue'] colsc = ['black'] # Start with whole model without separating into # Day and Night model_use = model1 # IF DayNight Separation is specified if DayNight: model1_day = model1[((model1['LT'] > LT_range[0]) & (model1['LT'] < LT_range[1]))] model1_night = model1[((model1['LT'] < LT_range[0]) | (model1['LT'] > LT_range[1]))] look = ['Day', 'Night'] cols1 = ['skyblue', 'blue'] colsc = ['gray', 'black'] look = np.array(look) for lo in range(len(look)): if DayNight: if lo == 0: model_use = model1_day else: model_use = model1_night col1 = cols1[lo] colc = colsc[lo] # Compute PC and CSI PC_1, CSI_1 = skill_score.calc_pc_and_csi( model_use['skill'].values, coin=False) PC_coin, CSI_coin = skill_score.calc_pc_and_csi( model_use['skill'].values, coin=True) # Compute Skill Scores (LSS1_mod1, LSS2_mod1, LSS3_mod1, LSS4_mod1) = skill_score.liemohn_skill_score( model_use['skill'].values, coin=False) (LSS1_coin, LSS2_coin, LSS3_coin, LSS4_coin) = skill_score.liemohn_skill_score( model_use['skill'].values, coin=True) # MAkE LSS arrays LSS_mod1 = np.array([LSS1_mod1, LSS2_mod1, LSS3_mod1, LSS4_mod1]) LSS_coin = np.array([LSS1_coin, LSS2_coin, LSS3_coin, LSS4_coin]) # Change label and variables depending on if user specified # CSI or PC if PorC == 'PC': lab = 'Percent Correct' exes = np.array([PC_coin, PC_1]) elif PorC == 'CSI': lab = 'Critical Success Index' exes = np.array([CSI_coin, CSI_1]) # Establish axes for i in range(4): if i == 0: ax = axs[0, 0] if i == 1: ax = axs[0, 1] if i == 2: ax = axs[1, 0] if i == 3: ax = axs[1, 1] # only plot coin toss if specified as True if coin: ax.text(exes[0], LSS_coin[i], 'O', fontsize=12, color=colc, label=None) ax.text(exes[1], LSS_mod1[i], 'N', fontsize=12, color=col1, label=None) # Set labels depending on plot number if (i == 0) | (i == 2): ax.set_ylabel('Skill Score') ax.set_xlabel(lab) ax.set_title('LSS' + str(i + 1)) # Legend: # If you want to plot the legend for both day and night colors # in the first legend remove "& (lo == 0)" if (i == 0) & (lo == 0): ax.plot(-99, -99, color=col1, label=model_name) if coin: ax.plot(-99, -99, color=colc, label='Coin Flip') ax.legend() if DayNight: # Getting LT hours for legend sm_arm = abs(model_use['LT'] - LT_range[0]).argmin() bg_arm = abs(model_use['LT'] - LT_range[1]).argmin() sm_lt = model_use['LT'].iloc[sm_arm] bg_lt = model_use['LT'].iloc[bg_arm] # Add Legend if (i == 1) & (lo == 0): lab1 = (str(np.round(sm_lt, 1)) + '-' + str(np.round(bg_lt, 1)) + ' LT') ax.plot(-99, -99, color=col1, label=lab1) if (i == 1) & (lo == 1): lab1 = (str(np.round(bg_lt, 1)) + '-' + str(np.round(sm_lt, 1)) + ' LT') ax.plot(-99, -99, color=col1, label=lab1) ax.legend() ax.set_ylim([-1, 1]) ax.set_xlim([0, 1]) # Add super title fig.suptitle((eia_type + ' ' + date_array[0].strftime('%Y/%m/%d') + '-' + date_array[-1].strftime('%Y/%m/%d')), x=0.5, y=0.92, fontsize=17) return fig