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
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()
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()
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)
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))
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'