# -*- coding: utf-8 -*- """ Created on Tue May 29 07:53:58 2018 @author: Noah Snider """ import pandas as pd import matplotlib.pyplot as plt import numpy as np import time import os import datetime import matplotlib.dates as mdates ############################################################################### ''' Saved Constants''' ############################################################################### VRG1rate = 1.0115 #rate at which VRG1 samples in real time (minutes) VRG2rate = 0.9873 #rate at which VRG2 sampels in real time (minutes) #convert to ms in string form to be passed into datetime index VRG1ms = str(int(VRG1rate*60*1000)) VRG2ms = str(int(VRG2rate*60*1000)) tenMinuteLocator = [x for x in range(60)] thirtyMinuteLocator = [x*5 for x in range(12)] hourLocator = [x*15 for x in range(4)] #============================================================================== # line 32 - added list of tuples to reformat column widths from txt file #============================================================================== colspecs = [(0,11),(12,19),(20,27),(28,35),(36,43),(44,50),(51,58)] #2/19/2019 ############################################################################### ''' Helper Functions for the code that parse filename, save data and plot''' ############################################################################### #parses filename for start date/start time def start_datetime(filename): dates = filename.split('_')[1]#starting date times = filename.split('_')[2].replace('.txt','')#starting time startdate = pd.to_datetime('-'.join([dates[-4:],dates[0:2],dates[2:4]])) + pd.to_timedelta(':'.join([times[:2],times[2:5],'00'])) return startdate #saves the names of the two .txt files from the working directory def nameGrabber(): file_names = []#empty list to store file names for names in os.listdir(): #append file names from working directory if 'VRG' in names: file_names.append(names) return file_names file_names = nameGrabber()#save globally #collects data from VRG1/2, saves to dataframe def data_collection(): columns = ['Depth','Rate','Mass','Temp'] #names of columns #loop through file_names for name in file_names: #save VRG1 to dataframe if 'VRG1' in name: #============================================================================== #lines 64 - 65: added colspecs to the read_fwf call and adjusted which columns get picked #============================================================================== dataVRG1 = pd.read_fwf(name,header = None,colspecs=colspecs) dataVRG1 = dataVRG1[[1,2,4,5]] dataVRG1.columns = columns dataVRG1 = dataVRG1.set_index(pd.date_range(start_datetime(file_names[0]),freq = VRG1ms + 'L',periods = dataVRG1.shape[0])) #correct temp and convert to fahrenheit dataVRG1['Temp'] += 4 #drop last line in case it was partially written dataVRG1 = dataVRG1.drop(dataVRG1.index[-1]) #save VRG2 to dataframe if 'VRG2' in name: #============================================================================== #lines 80-81: added colspecs to the read_fwf call and adjusted which columns get picked #============================================================================== dataVRG2 = pd.read_fwf(name,header = None,colspecs=colspecs) dataVRG2 = dataVRG2[[1,2,4,5]] dataVRG2.columns = columns dataVRG2 = dataVRG2.set_index(pd.date_range(start_datetime(file_names[1]),freq = VRG2ms + 'L',periods = dataVRG2.shape[0])) dataVRG2['Temp'] -= 4 #drop last line in case it was partially written dataVRG2 = dataVRG2.drop(dataVRG2.index[-1]) #return dataframe return dataVRG1,dataVRG2 #plottedData(): returns the data of the current day within school hours def plottedData(currentdate,dataVRG1,dataVRG2): #grab data from the current day plotVRG1 = dataVRG1.loc[dataVRG1.index.date == currentdate] plotVRG2 = dataVRG2.loc[dataVRG2.index.date == currentdate] #return return plotVRG1,plotVRG2 def plotter(currentdate,plotVRG1,plotVRG2): fig.suptitle('Data for ' + str(currentdate),size = 20) #ax1 axis ax1.plot(plotVRG1['Temp'],label = 'VRG1',color = 'blue',linewidth = .5) ax1.plot(plotVRG2['Temp'],label = 'VRG2',color = 'orange',linewidth = .5) ax1.set_ylabel('Temperature \n' + str(chr(176)) + 'C',fontsize = 10) ax1.yaxis.labelpad = 30 ax1.legend() ax1.set_yticks([-20,-10,0,10]) ax1.set_ylim(ymax = 10,ymin = -20) #ax2 axis ax2.plot(plotVRG1['DepthCorrected'],label = 'VRG1',color = 'blue',linewidth = .5) ax2.plot(plotVRG2['DepthCorrected'],label = 'VRG2',color = 'orange',linewidth = .5) ax2.set_ylabel('Accumulation of Liquid \nmm', fontsize = 10) ax2.yaxis.labelpad = 35 ax2.set_yticks([0,10,20,30]) ax2.set_ylim(ymax = 30,ymin = -10) #ax3 axis ax3.plot(plotVRG1['Rate'],label = 'VRG1',color = 'blue',linewidth = .5) ax3.plot(plotVRG2['Rate'],label = 'VRG2',color = 'orange',linewidth = .5) ax3.set_ylabel('Precipitation Rate \nmm/hr', fontsize = 10) ax3.yaxis.labelpad = 40 ax3.set_yticks([0,3,6,9]) ax3.set_ylim(ymax = 9,ymin = -3) #ax4 axis ax4.plot(plotVRG1['Mass'],label = 'VRG1',color = 'blue',linewidth = .5) ax4.plot(plotVRG2['Mass'],label = 'VRG2',color = 'orange',linewidth = .5) ax4.ticklabel_format(axis = 'y',useOffset = False) ax4.set_ylabel('Container Mass \ngram', fontsize = 10) ax4.yaxis.labelpad = 20 ax4.set_yticks([11000,12000,13000]) ax4.set_ylim(ymax = 13000,ymin = 10000) #clear xticks ax1.set_xticks([]) ax2.set_xticks([]) ax3.set_xticks([]) ax4.set_xticks([]) if plotVRG1.shape[0] < 10: ax4.xaxis.set_major_locator(mdates.MinuteLocator(byminute = tenMinuteLocator, interval = 1)) ax4.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) if plotVRG1.shape[0] < 30: ax4.xaxis.set_major_locator(mdates.MinuteLocator(byminute = thirtyMinuteLocator, interval = 1)) ax4.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) if plotVRG1.shape[0] < 60: ax4.xaxis.set_major_locator(mdates.MinuteLocator(byminute = hourLocator, interval = 1)) ax4.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) else: ax4.xaxis.set_major_locator(mdates.HourLocator(interval=1)) ax4.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) def main(): while True: try: #if size of text file gets above 5 Mb, break size = os.stat(file_names[0]).st_mode if size > 5000000: break #else plot else: dataVRG1,dataVRG2 = data_collection() #save data globally currentdate = dataVRG1.index[-1].date() #find current day plotVRG1,plotVRG2 = plottedData(currentdate,dataVRG1,dataVRG2) #only data during a school day #check if plotted data is empty plotVRG1['DepthCorrected'] = plotVRG1['Depth'] - plotVRG1['Depth'][0] plotVRG2['DepthCorrected'] = plotVRG2['Depth'] - plotVRG2['Depth'][0] plotter(currentdate,plotVRG1,plotVRG2) #plot time.sleep(5) # plt.draw() plt.pause(.01) ax1.cla() ax2.cla() ax3.cla() ax4.cla() except pd.errors.EmptyDataError: text = plt.text(.5,2,'Waiting for data to write to disk...',color = 'red', horizontalalignment = 'center',verticalalignment = 'center', size = 20) plt.draw() plt.pause(.01) time.sleep(5) text.remove() except IndexError: print('IndexError at ' + str(datetime.datetime.now())) time.sleep(5) #set up plotting environment fig = plt.figure() ax1 = fig.add_subplot(411) ax2 = fig.add_subplot(412) ax3 = fig.add_subplot(413) ax4 = fig.add_subplot(414) main()