Esempio n. 1
0
    def set_xaxis_format(window_len):

        # Formatting x-axis ticks ------------------------------------------------------------------------------------
        if window_len >= .25:
            xfmt = mdates.DateFormatter("%a %b %d, %H:%M:%S")
            bottom_plot_crop_value = .17
        # Shows milliseconds if plotting less than 15-second window
        if window_len < .25:
            xfmt = mdates.DateFormatter("%a %b %d, %H:%M:%S.%f")
            bottom_plot_crop_value = .23

        # Generates ~15 ticks (1/15th of window length apart)
        locator = mdates.MinuteLocator(byminute=np.arange(
            0, 59, int(np.ceil(window_len / 15))),
                                       interval=1)

        # Two-second ticks if window length between 5 and 30 seconds
        if 1 / 12 < window_len <= .5:
            locator = mdates.SecondLocator(interval=2)

        # Plots ~15 ticks if window less than 5 seconds
        if window_len <= 1 / 12:
            locator = mdates.MicrosecondLocator(
                interval=int(1000000 * (window_len * 60 / 15)))

        return xfmt, locator, bottom_plot_crop_value
Esempio n. 2
0
def waterfall_plot(data, xlims, sbs, obs_mode, sbs_interval=10, interval=10000):
    num_plots = int(data.shape[1]/sbs_interval)
    #print(num_plots)
    f, axs = plt.subplots(num_plots, 1, figsize=(10,10), sharex=True)
    x = np.linspace(xlims[0], xlims[1], data.shape[0])
    c = np.arange(1, int(data.shape[1]/sbs_interval)+1) #+1 so the last few plots are not completely white
    norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max())
    cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.cool)
    cmap.set_array([])

    leg = LofarRaw.sb_to_f(sbs[0]+np.linspace(0, data.shape[1], data.shape[1]+1)[::sbs_interval], obs_mode)
    leg = [round(x.value, 2) for x in leg]*u.MHz

    data = data[:,::sbs_interval]

    for i,ax in enumerate(axs):
        ax.plot(x, data[:,num_plots-i], c='k')
        ax.fill_between(x, data[:,num_plots-i], facecolor=cmap.to_rgba(i+1))
        ax.spines['right'].set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['left'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.axhline(y=data.min(), lw=2, clip_on=False, color=cmap.to_rgba(i+1))
        ax.set_yticks([])
        ax.set_ylim([data.min(),data.max()])
        ax.patch.set_alpha(0)
        label(ax, cmap.to_rgba(i+1), leg[num_plots-i])
        date_format = mdates.DateFormatter('%H:%M:%S.%f')
    axs[-1].spines['bottom'].set_visible(True)
    ax.xaxis.set_major_formatter(date_format)
    ax.xaxis.set_minor_locator(mdates.MicrosecondLocator(interval=interval))
    ax.set_xlabel('Time', fontsize=14)
    ax.tick_params(labelsize=14)
    f.subplots_adjust(hspace=-.5)
    f.autofmt_xdate()
Esempio n. 3
0
def plot_event_1d(data, xlims, sbs, obs_mode, sbs_interval=10, interval=10000):
    """
    This just shows a couple 1d plots of an event up close acrdeductionoss sbs_interval frequencies (total_sbs/10)
    """
    f, ax = plt.subplots(figsize=(10,6))
    f.set_facecolor('white')
    plt.plot(np.linspace(xlims[0], xlims[1], data.shape[0]), data[:,::sbs_interval])
    plt.xlim(xlims[0], xlims[1])
    plt.gca().xaxis_date()
    date_format = mdates.DateFormatter('%H:%M:%S.%f')
    ax.xaxis.set_major_formatter(date_format)
    ax.xaxis.set_minor_locator(mdates.MicrosecondLocator(interval=interval))
    f.autofmt_xdate()
    plt.xlabel('Time')
    plt.ylabel('Arbitrary voltages')
    leg = LofarRaw.sb_to_f(sbs[0]+np.linspace(0, data.shape[1], data.shape[1]+1)[::sbs_interval], obs_mode)
    leg = [round(x.value, 2) for x in leg]*u.MHz
    plt.legend(leg)
    plt.grid(ls=':')
    plt.tight_layout()
Esempio n. 4
0
def datetick(dir, **kwargs):
    '''
    datetick('x') or datetick('y') formats the major and minor tick labels
    of the current figure.
    
    datetick('x', axes=ax) or datetick('y', axes=ax) formats the given
    axes `ax`.

    Example:
    --------
        import datetime as dt
        import numpy as np
        import matplotlib.pyplot as plt
        from hapiclient.plot.datetick import datetick
        d1 = dt.datetime(1900, 1, 2)
        d2 = dt.datetime.fromordinal(10 + dt.datetime.toordinal(d1))
        x = np.array([d1, d2], dtype=object)
        y = [0.0,1.0]
        plt.clf()
        plt.plot(x, y)
        datetick('x')
    '''

    # Based on spacepy/plot/utils.py on 07/10/2017, but many additions.

    # TODO: Account for leap years instead of using 367, 366, etc.
    # TODO: Use numsize() to determine if figure width and height
    #       will cause overlap when default number major tick labels is used.
    # TODO: If time[0].day > 28, need to make first tick at time[0].day = 28
    #       as needed.
    # TODO: If first data point has fractional seconds, the plot won't have
    #       a major x-label right below it. This is due to the fact that
    #       MicrosecondLocator() does not take a keyword argument of
    #       "bymicroseconds".
    # TODO: Adjust lower and upper limits as in 366*8 span

    def millis(x, pos):
        x = matplotlib.dates.num2date(x)
        label = x.strftime('.%f')
        label = label[0:3]
        #label = label.rstrip(".")
        return label

    DOPTS = {}
    DOPTS.update({'debug': False})
    DOPTS.update({'set_cb': True})
    DOPTS.update({'axes': None})

    # Override defaults
    for key, value in kwargs.items():
        if key in DOPTS:
            DOPTS[key] = value
        else:
            print('Warning: Keyword option "%s" is not valid.' % key)

    if 'axes' in kwargs:
        axes = kwargs['axes']
        fig = axes.figure
    else:
        axes = plt.gca()
        fig = plt.gcf()

    #import pdb
    #pdb.set_trace()

    debug = DOPTS['debug']

    def on_xlims_change(ax):
        datetick('x', axes=ax, set_cb=False)

    def on_ylims_change(ax):
        datetick('y', axes=ax, set_cb=False)

    def draw(fig):
        fig.canvas.draw()  # Render new ticks and tick labels

    bbox = axes.dataLim

    if dir == 'x':
        datamin = bbox.x0
        datamax = bbox.x1
        lim = axes.get_xlim()
    else:
        datamin = bbox.y0
        datamax = bbox.y1
        lim = axes.get_ylim()

    try:
        mpld.num2date(lim[0])
    except:
        raise ValueError(
            'Lower axis limit of %f is not a valid Matplotlib datenum' %
            lim[0])
    try:
        mpld.num2date(lim[1])
    except:
        raise ValueError(
            'Upper axis limit of %f is not a valid Matplotlib datenum' %
            lim[1])
    try:
        mpld.num2date(datamin)
    except:
        raise ValueError(
            'Minimum data value of %f is not a valid Matplotlib datenum' %
            datamin)
    try:
        mpld.num2date(datamax)
    except:
        raise ValueError(
            'Maximum data value of %f is not a valid Matplotlib datenum' %
            datamax)

    tmin = np.max((lim[0], datamin))
    tmax = np.min((lim[1], datamax))

    time = mpld.num2date((tmin, tmax))

    if debug == True:
        print('Data min time: %f' % datamin)
        print('Data max time: %f' % datamax)

    deltaT = time[-1] - time[0]
    nDays = deltaT.days
    nHours = deltaT.days * 24.0 + deltaT.seconds / 3600.0
    nSecs = deltaT.total_seconds()
    if debug == True:
        print("Total seconds: %s" % deltaT.total_seconds())

    # fmt is format of the tick labels
    # fmt2 contains additional information that is used for the first tick label
    # or when there is a majore change. For example, if
    # fmt = %M:%S and fmt2 = %H, the labels will have only minute and hour and
    # the first tick will have a label of %M:%S\n%H. If there is a change
    # in hour somewhere on the axis, that label will include the new hour.

    # Note that interval=... is specified even when it would seem to be
    # redundant. It is needed to workaround the bug discussed at
    # https://stackoverflow.com/questions/31072589/matplotlib-date-ticker-exceeds-locator-maxticks-error-for-no-apparent-reason
    if deltaT.total_seconds() < 0.1:
        # < 0.1 second
        # At this level of zoom, would need original datetime data
        # which has not been converted by date2num and then re-plot
        # using integer number of milliseconds. E.g., call
        # plotd(dtobj,y)
        # where
        # t = dtobj converted to milliseconds since first array value
        # plotd() calls
        # plot(t,y)
        # and then makes first label indicate %Y-%m-%dT%H:%M:%S
        warnings.warn(
            "Warning: Cannot create accurate time labels with this time resolution."
        )
        # This does not locate microseconds.
        Mtick = mpld.MicrosecondLocator(interval=10000)
        mtick = mpld.MicrosecondLocator(interval=2000)
        from matplotlib.ticker import FuncFormatter
        fmt = FuncFormatter(millis)
        fmt2 = '%H:%M:%S\n%Y-%m-%d'
    if deltaT.total_seconds() < 0.5:
        # < 0.5 seconds
        # Locators don't locate at this resolution.
        # Need to do this manually. See comment above.
        warnings.warn(
            "Warning: Cannot create accurate time labels with this time resolution."
        )
        Mtick = mpld.MicrosecondLocator(interval=50000)
        mtick = mpld.MicrosecondLocator(interval=10000)
        from matplotlib.ticker import FuncFormatter
        fmt = FuncFormatter(millis)
        fmt2 = '%H:%M:%S\n%Y-%m-%d'
    if deltaT.total_seconds() < 1:
        # < 1 second
        # https://matplotlib.org/api/dates_api.html#matplotlib.dates.MicrosecondLocator
        # MircosecondLocator() does not have a "bymicrosecond" option. If
        # First point is not at zero microseconds, it won't be labeled.
        Mtick = mpld.MicrosecondLocator(interval=100000)
        mtick = mpld.MicrosecondLocator(interval=20000)
        from matplotlib.ticker import FuncFormatter
        fmt = FuncFormatter(millis)
        #fmt   = mpld.DateFormatter('%M:%S.%f')
        fmt2 = '%H:%M:%S\n%Y-%m-%d'
    elif deltaT.total_seconds() < 5:
        # < 5 seconds
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 1)))
        mtick = mpld.MicrosecondLocator(interval=200000)
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 10:
        # < 10 seconds
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 1)))
        mtick = mpld.MicrosecondLocator(interval=500000)
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 20:
        # < 20 seconds
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 2)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 1)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 30:
        # < 30 seconds
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 5)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 1)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60:
        # < 1 minute
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 10)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 2)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 2:
        # < 2 minutes
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 20)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 5)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 3:
        # < 3 minutes
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 20)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 5)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 5:
        # < 5 minutes
        Mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 30)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 10)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 10:
        # < 10 minutes
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 1)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 15)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 20:
        # < 20 minutes
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 2)))
        mtick = mpld.SecondLocator(bysecond=list(range(0, 60, 30)))
        fmt = mpld.DateFormatter('%M:%S')
        fmt2 = '%Y-%m-%dT%H'
    elif deltaT.total_seconds() < 60 * 30:
        # < 30 minutes
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 5)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 1)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif deltaT.total_seconds() < 60 * 60:
        # < 60 minutes
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 10)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 2)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif nHours < 2:
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 15)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 5)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif nHours < 4:
        Mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 20)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 5)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif nHours < 6:
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 1)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 10)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif nHours < 12:
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 2)))
        mtick = mpld.MinuteLocator(byminute=list(range(0, 60, 30)))
        fmt = mpld.DateFormatter('%H:%M')
        fmt2 = '%Y-%m-%d'
    elif nHours < 24:
        # < 1 day
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 3)))
        mtick = mpld.HourLocator(byhour=list(range(0, 24, 1)))
        fmt = mpld.DateFormatter('%H')
        fmt2 = '%Y-%m-%d'
    elif nHours < 48:
        # < 2 days
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 4)))
        mtick = mpld.HourLocator(byhour=list(range(0, 24, 2)))
        fmt = mpld.DateFormatter('%H')
        fmt2 = '%Y-%m-%d'
    elif nHours < 72:
        # < 3 days
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 6)))
        mtick = mpld.HourLocator(byhour=list(range(0, 24, 3)))
        fmt = mpld.DateFormatter('%H')
        fmt2 = '%Y-%m-%d'
    elif nHours < 96:
        # < 4 days
        Mtick = mpld.HourLocator(byhour=list(range(0, 24, 12)))
        mtick = mpld.HourLocator(byhour=list(range(0, 24, 3)))
        fmt = mpld.DateFormatter('%H')
        fmt2 = '%Y-%m-%d'
    elif deltaT.days < 8:
        Mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 1)))
        mtick = mpld.HourLocator(byhour=list(range(0, 24, 4)))
        fmt = mpld.DateFormatter('%d')
        fmt2 = '%Y-%m'
    elif deltaT.days < 16:
        Mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 1)))
        mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 1)))
        fmt = mpld.DateFormatter('%d')
        fmt2 = '%Y-%m'
    elif deltaT.days < 32:
        Mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 4)))
        mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 1)))
        fmt = mpld.DateFormatter('%d')
        fmt2 = '%Y-%m'
    elif deltaT.days < 60:
        Mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 7)))
        mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 1)))
        fmt = mpld.DateFormatter('%d')
        fmt2 = '%Y-%m'
    elif deltaT.days < 183:
        Mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 1)))
        mtick = mpld.DayLocator(bymonthday=list(range(1, 32, 7)))
        fmt = mpld.DateFormatter('%m')
        fmt2 = '%Y'
    elif deltaT.days < 367:
        Mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 1)))
        mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 1)))
        fmt = mpld.DateFormatter('%m')
        fmt2 = '%Y'
    elif deltaT.days < 366 * 2:
        Mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 2)))
        mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 1)))
        fmt = mpld.DateFormatter('%m')
        fmt2 = '%Y'
    elif deltaT.days < 366 * 8:
        Mtick = mpld.YearLocator(1)
        mtick = mpld.MonthLocator(bymonth=list(range(1, 13, 4)))
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''
    elif deltaT.days < 366 * 15:
        to = axes.lines[0].get_xdata()[0]
        tf = axes.lines[0].get_xdata()[-1]
        print(to)
        print(tf)
        # Ideally would set byyear=list(range(to.year, tf.year,2)) but
        # byyear is not a kwarg. Would need to something like
        # https://stackoverflow.com/questions/48428729/matplotlib-dates-yearlocator-with-odd-intervals
        Mtick = mpld.YearLocator(1)
        mtick = mpld.YearLocator(1)
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''
        if False:
            xl = axes.get_xlim()
            a = mpld.num2date(xl[0])
            print(a)
            import pdb
            pdb.set_trace()
            a = mpld.date2num(
                a.replace(month=1,
                          day=1,
                          hour=0,
                          minute=0,
                          second=0,
                          microsecond=0))
            b = mpld.num2date(xl[1])
            b = mpld.date2num(
                b.replace(year=(b.year + 1),
                          month=1,
                          day=1,
                          hour=0,
                          minute=0,
                          second=0,
                          microsecond=0))
            axes.set_xlim([a, b])

    elif deltaT.days < 366 * 40:
        Mtick = mpld.YearLocator(5)
        mtick = mpld.YearLocator(1)
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''
    elif deltaT.days < 366 * 100:
        Mtick = mpld.YearLocator(10)
        mtick = mpld.YearLocator(2)
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''
    elif deltaT.days < 366 * 200:
        Mtick = mpld.YearLocator(20)
        mtick = mpld.YearLocator(5)
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''
    else:
        Mtick = mpld.YearLocator(50)
        mtick = mpld.YearLocator(10)
        fmt = mpld.DateFormatter('%Y')
        fmt2 = ''

    xt = axes.get_xticks()
    xl = axes.get_xlim()

    if debug:
        print("Default xlim[0]:    %s" % mpld.num2date(xl[0]))
        print("Default xlim[1]:    %s" % mpld.num2date(xl[1]))
        print("Default xticks[0]:  %s" % mpld.num2date(xt[0]))
        print("Default xticks[-1]: %s" % mpld.num2date(xt[-1]))

    if debug:
        print("Start: %s" % mpld.num2date(xl[0]))
        print("Stop:  %s" % mpld.num2date(xl[1]))
        for i in range(0, len(xt)):
            print("Tick: %s" % mpld.num2date(xt[i]))

    draw(fig)  # Needed?

    if dir == 'x':
        axes.xaxis.set_major_locator(Mtick)
        axes.xaxis.set_minor_locator(mtick)
        axes.xaxis.set_major_formatter(fmt)
        draw(fig)  # Render new labels so updated for next line
        labels = [item.get_text() for item in axes.get_xticklabels()]
        ticks = axes.get_xticks()
        time = mpld.num2date(ticks)
    else:
        axes.yaxis.set_major_locator(Mtick)
        axes.yaxis.set_minor_locator(mtick)
        axes.yaxis.set_major_formatter(fmt)
        draw(fig)  # Render new labels so updated for next line
        labels = [item.get_text() for item in axes.get_yticklabels()]
        ticks = axes.get_yticks()
        time = mpld.num2date(ticks)

    if debug:
        xl = axes.get_xlim()
        print(mpld.num2date(xl[0]))
        print(mpld.num2date(ticks[0]))
        print(mpld.num2date(xl[1]))
        print(mpld.num2date(ticks[-1]))
        if ticks[0] < xl[0]:
            print('Left-most tick label will be clipped.')
        if ticks[-1] > xl[1]:
            print('Right-most tick label will be clipped.')
        for i in range(0, len(ticks)):
            print("Tick: %s" % mpld.num2date(ticks[i]))

    if fmt2 != '':
        first = 0
        if ticks[0] < xl[0]:
            # Work-around for bug in Matplotlib where left-most tick is less than
            # lower x-limit.
            first = 1

        # Always apply fmt2 to first tick label
        labels[first] = '%s\n%s' % (labels[first],
                                    datetime.strftime(time[first], fmt2))

        for i in range(first + 1, len(time)):
            # First label will always have fmt applied.
            # Modify labels after first under certain conditions.
            modify = False

            if time[i].year > time[i - 1].year:
                modify = True
            if nDays < 60 and time[i].month > time[i - 1].month:
                modify = True
            if nDays < 4 and time[i].day > time[i - 1].day:
                modify = True
            if nSecs < 60 * 30 and time[i].hour > time[i - 1].hour:
                modify = True
            if nSecs < 1 and time[i].minute > time[i - 1].minute:
                modify = True
            if nSecs < 1 and time[i].second > time[i - 1].second:
                modify = True

            if not modify: continue

            if i == first + 1 and dir == 'x':
                # If first two major tick labels have fmt2 applied, the will
                # likely run together. This keeps fmt2 label for second major
                # tick.
                #labels[i] = '%s\n%s' % (labels[i], datetime.strftime(mpld.num2date(ticks[i]), fmt2))
                pass
            else:
                labels[i] = '%s\n%s' % (labels[i],
                                        datetime.strftime(
                                            mpld.num2date(ticks[i]), fmt2))

    if dir == 'x':
        axes.set_xticklabels(labels)
    if dir == 'y':
        axes.set_yticklabels(labels)

    # Trigger update of ticks when limits change due to user interaction.
    if DOPTS['set_cb']:
        if dir == 'x':
            axes.callbacks.connect('xlim_changed', on_xlims_change)
        else:
            axes.callbacks.connect('ylim_changed', on_ylims_change)
Esempio n. 5
0
    def plot_data(self, start=None, stop=None, downsample_factor=1):
        """Plots hip and wrist data whichever/both is available.
            arguments:
                -start: timestamp for start of region. Format = "YYYY-MM-DD HH:MM:SS" OR integer for
                        minutes into collection
                -stop: timestamp for end of region. Format = "YYYY-MM-DD HH:MM:SS" OR integer for
                        minutes into collection
                -downsample: ratio by which data are downsampled. E.g. downsample=3 will downsample from 75 to 25 Hz
            If start and stop are not specified, data will be cropped to one of the following:
                -If no previous graphs have been generated, it will plot the entire data file
                -If a previous crop has occurred, it will 'remember' that region and plot it again.
            To clear the 'memory' of previously-plotted regions, enter "x.start_stamp=None"
            and "x.stop_stop=None" in console
        """

        print(
            "\n-----------------------------------------------------------------------------------------------------"
        )

        # Gets appropriate timestamps
        start_stamp, stop_stamp, data_type = self.get_timestamps(start, stop)

        self.start_stamp = start_stamp
        self.stop_stamp = stop_stamp

        # Crops dataframes to selected region -------------------------------------------------------------------------
        if self.hip_fname is not None:
            # Sets stop to end of collection if stop timestamp exceeds timestamp range
            try:
                if stop_stamp > self.df_hip.iloc[-1]["Timestamp"]:
                    stop_stamp = self.df_hip.iloc[-1]["Timestamp"]
            except TypeError:
                if datetime.strptime(stop_stamp, "%Y-%m-%d %H:%M:%S"
                                     ) > self.df_hip.iloc[-1]["Timestamp"]:
                    stop_stamp = self.df_hip.iloc[-1]["Timestamp"]

            df_hip = self.df_hip.loc[(self.df_hip["Timestamp"] > start_stamp)
                                     & (self.df_hip["Timestamp"] < stop_stamp)]

            if data_type == "absolute":
                df_hip["Timestamp"] = np.arange(
                    0, (stop_stamp - start_stamp).seconds,
                    1 / self.hip_samplerate)[0:df_hip.shape[0]]

            if downsample_factor != 1:
                df_hip = df_hip.iloc[::downsample_factor, :]

        # Window length in minutes
        window_len = (stop_stamp - start_stamp).total_seconds() / 60

        print("Plotting {} minute section from {} to {}.".format(
            round(window_len, 2),
            datetime.strftime(start_stamp, "%Y-%m-%d %H:%M:%S"),
            datetime.strftime(stop_stamp, "%Y-%m-%d %H:%M:%S")))

        # Downsampling information ------------------------------------------------------------------------------------
        if downsample_factor != 1:
            if self.hip_fname is not None:
                print("\nDownsampling {}Hz data by a factor of {}. "
                      "New data is {}Hz.".format(
                          self.hip_samplerate, downsample_factor,
                          round(self.hip_samplerate / downsample_factor, 1)))

        # Formatting x-axis ticks ------------------------------------------------------------------------------------
        if window_len >= .25:
            xfmt = mdates.DateFormatter("%a %b %d, %H:%M:%S")
            bottom_plot_crop_value = .17
        # Shows milliseconds if plotting less than 15-second window
        if window_len < .25:
            xfmt = mdates.DateFormatter("%a %b %d, %H:%M:%S.%f")
            bottom_plot_crop_value = .23

        # Generates ~15 ticks (1/15th of window length apart)
        locator = mdates.MinuteLocator(byminute=np.arange(
            0, 59, int(np.ceil(window_len / 15))),
                                       interval=1)

        # Two-second ticks if window length between 5 and 30 seconds
        if 1 / 12 < window_len <= .5:
            locator = mdates.SecondLocator(interval=2)

        # Plots ~15 ticks if window less than 5 seconds
        if window_len <= 1 / 12:
            locator = mdates.MicrosecondLocator(
                interval=int(1000000 * (window_len * 60 / 15)))

        # Plots depending on what data is available -------------------------------------------------------------------
        if self.hip_fname is not None:

            def plot_hip():
                fig, ax1 = plt.subplots(1,
                                        figsize=(self.fig_width,
                                                 self.fig_height))
                plt.subplots_adjust(bottom=bottom_plot_crop_value)

                ax1.set_title("{} ({} Hz)".format(
                    self.hip_fname.split("/")[-1],
                    int(self.hip_samplerate / downsample_factor)))
                ax1.plot(df_hip["Timestamp"],
                         df_hip["X"],
                         color='red',
                         label="Hip_X")
                ax1.plot(df_hip["Timestamp"],
                         df_hip["Y"],
                         color='black',
                         label="Hip_Y")
                ax1.plot(df_hip["Timestamp"],
                         df_hip["Z"],
                         color='dodgerblue',
                         label="Hip_Z")

                ax1.legend(loc='lower left')
                ax1.set_ylabel("G")

                # Timestamp axis formatting
                if data_type == "timestamp":
                    ax1.xaxis.set_major_formatter(xfmt)
                    ax1.xaxis.set_major_locator(locator)
                    plt.xticks(rotation=45, fontsize=8)

                if data_type == "absolute":
                    ax1.set_xlabel("Seconds into collection")

            plot_hip()

        f_name = self.check_file_overwrite("Hip_{}Hz_{} to {}".format(
            int(self.hip_samplerate / downsample_factor),
            datetime.strftime(start_stamp, "%Y-%m-%d %H_%M_%S"),
            datetime.strftime(stop_stamp, "%Y-%m-%d %H_%M_%S")))
        plt.savefig(f_name + ".png")
        print("Plot saved as png ({}.png)".format(f_name))
Esempio n. 6
0
              c='k')

    # Plot the fit
    current_date = hilt_filtered.index[0].floor('d')
    time_seconds = (hilt_filtered.index - current_date).total_seconds()
    popt = row.loc[['A', 't0', 'fwhm', 'y-int', 'slope']]
    popt[1] = (popt[1] - current_date).total_seconds()
    popt[2] = popt[2] / 2.355  # Convert the Gaussian FWHM to std
    y = SAMPEX_Microburst_Widths.gaus_lin_function(time_seconds, *popt)
    ax_i.plot(hilt_filtered.index,
              (count_rate_conversion / yaxis_scale_factor) * y,
              c='r',
              ls='--')

    # Format the time axis as seconds.
    ax_i.xaxis.set_minor_locator(mdates.MicrosecondLocator(interval=100_000))
    ax_i.xaxis.set_major_locator(mdates.SecondLocator())
    # Get the axis ticks first
    prev_ticks = mdates.num2date(ax_i.get_xticks())
    prev_ticks = [tick_i.replace(tzinfo=None) for tick_i in prev_ticks]
    sec_ticks = [
        int((tick_i - start_time_sec_floor).total_seconds())
        for tick_i in prev_ticks
    ]
    ax_i.set_xticklabels(sec_ticks)
    # Set the yticks to be at integer values.
    ax_i.yaxis.set_major_locator(ticker.MaxNLocator(integer=True))

    annotate_str = (
        f'({label_i})\n'
        f'FWHM = {round(row.fwhm*1000)} [ms]\n'