def plot_dv(dv, save_dir='.', figure_file_name=None, mark_time=None, normalize_simmat=False, sim_mat_Clim=[], figsize=(9, 11), dpi=72): """ Plot the "extended" dv dictionary This function is thought to plot the result of the velocity change estimate as output by :class:`~miic.core.stretch_mod.multi_ref_vchange_and_align` and successively "extended" to contain also the timing in the form {'time': time_vect} where `time_vect` is a :class:`~numpy.ndarray` of :class:`~datetime.datetime` objects. This addition can be done, for example, using the function :class:`~miic.core.miic_utils.add_var_to_dict`. The produced figure is saved in `save_dir` that, if necessary, it is created. It is also possible to pass a "special" time value `mark_time` that will be represented in the `dv/v` and `corr` plot as a vertical line; It can be a string (i.e. YYYY-MM-DD) or directly a :class:`~datetime.datetime` object. if the `dv` dictionary also contains a 'comb_mseedid' keyword, its `value` (i.e. MUST be a string) will be reported in the title. In case of the chosen filename exist in the `save_dir` directory, a prefix _<n> with n:0..+Inf, is added. The aspect of the plot may change depending on the matplotlib version. The recommended one is matplotlib 1.1.1 :type dv: dict :param dv: velocity change estimate dictionary as output by :class:`~miic.core.stretch_mod.multi_ref_vchange_and_align` and successively "extended" to contain also the timing in the form {'time': time_vect} where `time_vect` is a :class:`~numpy.ndarray` of :class:`~datetime.datetime` objects. :type save_dir: string :param save_dir: Directory where to save the produced figure. It is created if it doesn't exist. :type figure_file_name: string :param figure_file_name: filename to use for saving the figure. If None the figure is displayed in interactive mode. :type mark_time: string or :class:`~datetime.datetime` object :param mark_time: It is a "special" time location that will be represented in the `dv/v` and `corr` plot as a vertical line. :type normalize_simmat: Bool :param normalize_simmat: if True the simmat will be normalized to a maximum of 1. Defaults to False :type sim_mat_Clim: 2 element array_like :param sim_mat_Clim: if non-empty it set the color scale limits of the similarity matrix image """ check_state = dv_check(dv) # Check if the dv dictionary is "correct" if check_state['is_incomplete']: print "Error: Incomplete dv" print "Possible errors:" for key in check_state: if key is not 'is_incomplete': print "%s: %s" % (key, check_state[key]) raise ValueError # For compatibility with TraitsUI if mark_time == '': mark_time = None if mark_time and type(mark_time) == str: mark_time = from_str_to_datetime(mark_time, datetimefmt=True) elif mark_time and type(mark_time) == datetime.datetime: pass elif mark_time: print "Error: wrong mark_time format!" mark_time = None if not os.path.isdir(save_dir): print "Warning: `save_dir` doesn't exist. Creating ..." os.mkdir(save_dir) print "Directory %s created" % save_dir # Create a unique filename if TraitsUI-default is given if figure_file_name == 'plot_default': fname = figure_file_name + '_change.png' exist = os.path.isfile(os.path.join(save_dir, fname)) i = 0 while exist: fname = "%s_%i" % (figure_file_name, i) exist = os.path.isfile(os.path.join(save_dir, fname + '_change.png')) i += 1 figure_file_name = fname # Extract the data from the dictionary value_type = dv['value_type'][0] method = dv['method'][0] corr = dv['corr'] dt = dv['value'] sim_mat = dv['sim_mat'] stretch_vect = dv['second_axis'] rtime = convert_time(dv['time']) # normalize simmat if requested if normalize_simmat: sim_mat = sim_mat/np.tile(np.max(sim_mat,axis=1),(sim_mat.shape[1],1)).T # if dv_type == 'single_ref': # dt = 1 - dt # stretch_vect = stretch_vect - 1 n_stretching = stretch_vect.shape[0] stretching_amount = np.max(stretch_vect) # Adapt plot details in agreement with the type of dictionary that # has been passed if (value_type == 'stretch') and (method == 'single_ref'): tit = "Single reference dv/v" dv_tick_delta = 0.01 dv_y_label = "dv/v" elif (value_type == 'stretch') and (method == 'multi_ref'): tit = "Multi reference dv/v" dv_tick_delta = 0.01 dv_y_label = "dv/v" elif (value_type == 'shift') and (method == 'time_shift'): tit = "Time shift" dv_tick_delta = 5 dv_y_label = "time shift (sample)" else: print "Error: Wrong dv type!" return f = plt.figure(figsize=figsize, dpi=dpi) if matplotlib.__version__ >= '1.1.1': gs = gridspec.GridSpec(3, 1, height_ratios=[3, 1, 1]) else: gs = [311, 312, 313] ax1 = f.add_subplot(gs[0]) imh = plt.imshow(sim_mat.T, interpolation='none', aspect='auto') if sim_mat_Clim: assert len(sim_mat_Clim) == 2, "sim_mat_Clim must be a two element list" imh.set_clim(sim_mat_Clim[0], sim_mat_Clim[1]) plt.gca().get_xaxis().set_visible(False) ax1.set_yticks(np.floor(np.linspace(0, n_stretching - 1, 7)).astype('int')) ax1.set_yticklabels(["%4.3f" % x for x in stretch_vect[np.floor(np.linspace(0, n_stretching - 1, 7)).astype('int')][:-1]]) if 'stats' in dv: stats = flatten_recarray(dv['stats']) comb_mseedid = \ stats['network'] + '.' + stats['station'] + \ '.' + stats['location'] + '.' + stats['channel'] tit = "%s estimate (%s)" % (tit, comb_mseedid) else: tit = "%s estimate" % tit ax1.set_title(tit) ax1.yaxis.set_label_position('right') ax1.yaxis.label.set_rotation(270) ax1.set_xticklabels([]) ax1.set_ylabel(dv_y_label) ax2 = f.add_subplot(gs[1]) plt.plot(rtime, -dt, '.') plt.xlim([rtime[0], rtime[-1]]) plt.ylim((-stretching_amount, stretching_amount)) if mark_time and not np.all(rtime < mark_time) \ and not np.all(rtime > mark_time): plt.axvline(mark_time, lw=1, color='r') ax2.yaxis.set_ticks_position('left') ax2.yaxis.set_label_position('right') ax2.yaxis.label.set_rotation(270) ax2.set_ylabel(dv_y_label) ax2.yaxis.set_major_locator(plt.MultipleLocator(dv_tick_delta)) ax2.yaxis.grid(True, 'major', linewidth=1) ax2.xaxis.grid(True, 'major', linewidth=1) ax2.set_xticklabels([]) ax3 = f.add_subplot(gs[2]) plt.plot(rtime, corr, '.') plt.xlim([rtime[0], rtime[-1]]) ax3.yaxis.set_ticks_position('right') ax3.set_ylabel("Correlation") plt.ylim((0, 1)) if mark_time and not np.all(rtime < mark_time)\ and not np.all(rtime > mark_time): plt.axvline(mark_time, lw=1, color='r') plt.setp(ax3.get_xticklabels(), rotation=45, ha='right') ax3.yaxis.set_major_locator(plt.MultipleLocator(0.2)) ax3.yaxis.grid(True, 'major', linewidth=1) ax3.xaxis.grid(True, 'major', linewidth=1) plt.subplots_adjust(hspace=0, wspace=0) if figure_file_name == None: plt.show() else: print 'saving to %s' % figure_file_name f.savefig(os.path.join(save_dir, figure_file_name + '_change.png'), dpi=dpi) plt.close()
def plot_dv(dv, save_dir='.', figure_file_name=None, mark_time=None, normalize_simmat=False, sim_mat_Clim=[], figsize=(9, 11), dpi=72): """ Plot the "extended" dv dictionary This function is thought to plot the result of the velocity change estimate as output by :class:`~miic.core.stretch_mod.multi_ref_vchange_and_align` and successively "extended" to contain also the timing in the form {'time': time_vect} where `time_vect` is a :class:`~numpy.ndarray` of :class:`~datetime.datetime` objects. This addition can be done, for example, using the function :class:`~miic.core.miic_utils.add_var_to_dict`. The produced figure is saved in `save_dir` that, if necessary, it is created. It is also possible to pass a "special" time value `mark_time` that will be represented in the `dv/v` and `corr` plot as a vertical line; It can be a string (i.e. YYYY-MM-DD) or directly a :class:`~datetime.datetime` object. if the `dv` dictionary also contains a 'comb_mseedid' keyword, its `value` (i.e. MUST be a string) will be reported in the title. In case of the chosen filename exist in the `save_dir` directory, a prefix _<n> with n:0..+Inf, is added. The aspect of the plot may change depending on the matplotlib version. The recommended one is matplotlib 1.1.1 :type dv: dict :param dv: velocity change estimate dictionary as output by :class:`~miic.core.stretch_mod.multi_ref_vchange_and_align` and successively "extended" to contain also the timing in the form {'time': time_vect} where `time_vect` is a :class:`~numpy.ndarray` of :class:`~datetime.datetime` objects. :type save_dir: string :param save_dir: Directory where to save the produced figure. It is created if it doesn't exist. :type figure_file_name: string :param figure_file_name: filename to use for saving the figure. If None the figure is displayed in interactive mode. :type mark_time: string or :class:`~datetime.datetime` object :param mark_time: It is a "special" time location that will be represented in the `dv/v` and `corr` plot as a vertical line. :type normalize_simmat: Bool :param normalize_simmat: if True the simmat will be normalized to a maximum of 1. Defaults to False :type sim_mat_Clim: 2 element array_like :param sim_mat_Clim: if non-empty it set the color scale limits of the similarity matrix image """ check_state = dv_check(dv) # Check if the dv dictionary is "correct" if check_state['is_incomplete']: print "Error: Incomplete dv" print "Possible errors:" for key in check_state: if key is not 'is_incomplete': print "%s: %s" % (key, check_state[key]) raise ValueError # For compatibility with TraitsUI if mark_time == '': mark_time = None if mark_time and type(mark_time) == str: mark_time = from_str_to_datetime(mark_time, datetimefmt=True) elif mark_time and type(mark_time) == datetime.datetime: pass elif mark_time: print "Error: wrong mark_time format!" mark_time = None if not os.path.isdir(save_dir): print "Warning: `save_dir` doesn't exist. Creating ..." os.mkdir(save_dir) print "Directory %s created" % save_dir # Create a unique filename if TraitsUI-default is given if figure_file_name == 'plot_default': fname = figure_file_name + '_change.png' exist = os.path.isfile(os.path.join(save_dir, fname)) i = 0 while exist: fname = "%s_%i" % (figure_file_name, i) exist = os.path.isfile( os.path.join(save_dir, fname + '_change.png')) i += 1 figure_file_name = fname # Extract the data from the dictionary value_type = dv['value_type'][0] method = dv['method'][0] corr = dv['corr'] dt = dv['value'] sim_mat = dv['sim_mat'] stretch_vect = dv['second_axis'] rtime = convert_time(dv['time']) # normalize simmat if requested if normalize_simmat: sim_mat = sim_mat / np.tile(np.max(sim_mat, axis=1), (sim_mat.shape[1], 1)).T # if dv_type == 'single_ref': # dt = 1 - dt # stretch_vect = stretch_vect - 1 n_stretching = stretch_vect.shape[0] stretching_amount = np.max(stretch_vect) # Adapt plot details in agreement with the type of dictionary that # has been passed if (value_type == 'stretch') and (method == 'single_ref'): tit = "Single reference dv/v" dv_tick_delta = 0.01 dv_y_label = "dv/v" elif (value_type == 'stretch') and (method == 'multi_ref'): tit = "Multi reference dv/v" dv_tick_delta = 0.01 dv_y_label = "dv/v" elif (value_type == 'shift') and (method == 'time_shift'): tit = "Time shift" dv_tick_delta = 5 dv_y_label = "time shift (sample)" else: print "Error: Wrong dv type!" return f = plt.figure(figsize=figsize, dpi=dpi) if matplotlib.__version__ >= '1.1.1': gs = gridspec.GridSpec(3, 1, height_ratios=[3, 1, 1]) else: gs = [311, 312, 313] ax1 = f.add_subplot(gs[0]) imh = plt.imshow(sim_mat.T, interpolation='none', aspect='auto') if sim_mat_Clim: assert len( sim_mat_Clim) == 2, "sim_mat_Clim must be a two element list" imh.set_clim(sim_mat_Clim[0], sim_mat_Clim[1]) plt.gca().get_xaxis().set_visible(False) ax1.set_yticks(np.floor(np.linspace(0, n_stretching - 1, 7)).astype('int')) ax1.set_yticklabels([ "%4.3f" % x for x in stretch_vect[np.floor(np.linspace(0, n_stretching - 1, 7)).astype('int')][:-1] ]) if 'stats' in dv: stats = flatten_recarray(dv['stats']) comb_mseedid = \ stats['network'] + '.' + stats['station'] + \ '.' + stats['location'] + '.' + stats['channel'] tit = "%s estimate (%s)" % (tit, comb_mseedid) else: tit = "%s estimate" % tit ax1.set_title(tit) ax1.yaxis.set_label_position('right') ax1.yaxis.label.set_rotation(270) ax1.set_xticklabels([]) ax1.set_ylabel(dv_y_label) ax2 = f.add_subplot(gs[1]) plt.plot(rtime, -dt, '.') plt.xlim([rtime[0], rtime[-1]]) plt.ylim((-stretching_amount, stretching_amount)) if mark_time and not np.all(rtime < mark_time) \ and not np.all(rtime > mark_time): plt.axvline(mark_time, lw=1, color='r') ax2.yaxis.set_ticks_position('left') ax2.yaxis.set_label_position('right') ax2.yaxis.label.set_rotation(270) ax2.set_ylabel(dv_y_label) ax2.yaxis.set_major_locator(plt.MultipleLocator(dv_tick_delta)) ax2.yaxis.grid(True, 'major', linewidth=1) ax2.xaxis.grid(True, 'major', linewidth=1) ax2.set_xticklabels([]) ax3 = f.add_subplot(gs[2]) plt.plot(rtime, corr, '.') plt.xlim([rtime[0], rtime[-1]]) ax3.yaxis.set_ticks_position('right') ax3.set_ylabel("Correlation") plt.ylim((0, 1)) if mark_time and not np.all(rtime < mark_time)\ and not np.all(rtime > mark_time): plt.axvline(mark_time, lw=1, color='r') plt.setp(ax3.get_xticklabels(), rotation=45, ha='right') ax3.yaxis.set_major_locator(plt.MultipleLocator(0.2)) ax3.yaxis.grid(True, 'major', linewidth=1) ax3.xaxis.grid(True, 'major', linewidth=1) plt.subplots_adjust(hspace=0, wspace=0) if figure_file_name == None: plt.show() else: print 'saving to %s' % figure_file_name f.savefig(os.path.join(save_dir, figure_file_name + '_change.png'), dpi=dpi) plt.close()
def multi_ref_creation(corr_mat, rtime, freq=30, use_break_point=False, break_point=None): """ Create the multi-reference traces This function creates multi-reference traces according with the given frequency. In case of a break-point is passed, the intervals to consider for the reference traces creation are symmetric respect to it. :type corr_mat: :class:`~numpy.ndarray` :param corr_mat: Correlation matrix with one correlation function on each row :type rtime: :class:`~numpy.array` of :class:`~datetime.datetime` objects :param rtime: Time vector associated to the given correlation matrix. Its lenght must be equal to the numer of columns of the `corr_mat` parameter :type freq: int :param freq: One reference trace every `freq` days :type use_break_point: bool :param use_break_point: If `True` the reference traces are calculated in different intervals of `freq` days symmetric respect to the `break_point` :type break_point: string :param break_point: Brake point expressed as "YYYY-MM-DD" """ if use_break_point and break_point == None: print "Error: A break point must be passed!" return None if use_break_point and type(break_point) != str: print "Error: wrong break_point format!\nCheck the docs:\n\n" print __doc__ return None if use_break_point: bp = from_str_to_datetime(break_point, datetimefmt=True) f_frw = "%iD" % int(freq) f_bck = "-%iD" % int(freq) # Time "backward" intervals starting from the break_point and going # back to the first day available in the data. dr = date_range(rtime[rtime <= bp].max(), rtime[rtime < bp].min(), freq=f_bck)[::-1] # Time "forward" intervals starting from the break_point and going # ahead to the last day available in the data. dr1 = date_range(bp, rtime.max(), freq=f_frw)[1:] # break_point must # be removed dr = dr.append(dr1) else: f = "%iD" % int(freq) dr = date_range(np.min(rtime), np.max(rtime), freq=f) # DataFrame creation df = DataFrame(corr_mat, index=rtime) # GroupBy the given intervals dfg = df.groupby(lambda x: np.sum(np.ones(dr.shape)[dr <= x])) # Calculate the reference traces averaging the traces on each interval df_ref = dfg.mean() # Take the raw output ref_mat = df_ref.values return ref_mat