Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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
Пример #4
0
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