def read_humon_file(file_name): humon_columns = [ 'POSIX Time [seconds]', 'Time [seconds]', 'smo2 [%]', 'hgb [g/dL]', 'zone [-]', 'heartRate [bpm]', 'altitude [meters]', 'speed [meters/sec]', 'latitude [degrees]', 'longitude [degrees]', 'distance [meters]', 'wrk_date', 'wrk_act', 'wrk_type', 'wrk_score' ] hr_ut2 = 137 hr_ut1 = 145 hr_at = 158 hr_tr = 164 hr_an = 178 hr_max = 185 # This section can be ignored. I needed to do some stuff to deal with bugs # in the way that Humon exported data. The key thing is it identified where the # real data started. f=open(file_name,'r') raw_data=f.readlines() found_header = False raw_data_index = 0 while not found_header: if "Workout UUID" in raw_data[raw_data_index]: workout_UUID = raw_data[raw_data_index][14:50] elif "GMT" in raw_data[raw_data_index]: workout_date_time = raw_data[raw_data_index][4:24] elif "Activity" in raw_data[raw_data_index]: workout_activity = raw_data[raw_data_index][15:len(raw_data[raw_data_index])-1] elif "Workout Type" in raw_data[raw_data_index]: workout_type = raw_data[raw_data_index][14:len(raw_data[raw_data_index])-1] elif "Effort" in raw_data[raw_data_index]: workout_effort = raw_data[raw_data_index][8:9] elif "Score" in raw_data[raw_data_index]: workout_score = raw_data[raw_data_index][7:9] elif "Threshold" in raw_data[raw_data_index]: workout_threshold = raw_data[raw_data_index][11:14] elif "POSIX" in raw_data[raw_data_index]: found_header = True raw_data_index = raw_data_index + 1 workout_name = file_name # End of weirdness df = pd.read_csv(file_name, skiprows=raw_data_index-1) # Instead of having data columns for each of the Humon zones, # I added a single field for zone_clr (zone color) and populated it by testing # for the recorded zone number df['zone_clr']='grey' df.loc[df['zone [-]']==2,'zone_clr']='blue' df.loc[df['zone [-]']==3,'zone_clr']='green' df.loc[df['zone [-]']==4,'zone_clr']='orange' df.loc[df['zone [-]']==5,'zone_clr']='red' # In the Humon data, the HR can either be present or not present. I start by # setting the zone to hr_ut2,'hr_clr'] = 'yellow' df.loc[df['heartRate [bpm]']>hr_ut1,'hr_clr'] = 'green' df.loc[df['heartRate [bpm]']>hr_at,'hr_clr'] = 'blue' df.loc[df['heartRate [bpm]']>hr_tr,'hr_clr'] = 'purple' df.loc[df['heartRate [bpm]']>hr_an,'hr_clr'] = 'red' return df; workout = './Documents/Humon_new_data/Humon-2019-06-09_18_53_59_UTC.csv' # This is the plotting routine. At this point, all workouts are in a data frame called # df_all. In this routine, I pick out a specific workout based on it's filename and then # move it into a temporary data frame (df) to work on. df = df_all[df_all['wrk_name']==workout] # This is setting up all the axes and labels fig = plt.figure() ax1=fig.add_axes([0.1,2.1,1.4,1.0]) plt.grid() plt.xlim(0,max(df['Time [seconds]'])) plt.ylim(min(df['smo2 [%]'])-10,max(df['smo2 [%]'])+10) plt.ylabel("smo2 [%]") ax2=fig.add_axes([0.1,1.1,1.4,1.0]) plt.grid() plt.xlim(0,max(df['Time [seconds]'])) plt.ylim(min(df["hgb [g/dL]"])-1,max(df["hgb [g/dL]"])+1) plt.ylabel("hgb [g/dL]") ax3=fig.add_axes([0.1,0.1,1.4,1.0]) plt.grid() plt.xlim(0,max(df['Time [seconds]'])) plt.ylim(min(df['heartRate [bpm]']),max(df['heartRate [bpm]'])+10) plt.ylabel("HR (bpm)") x_values = pd.to_numeric(df['Time [seconds]']) # smO2 plot. I create a field in the dataframe called "tempval" which gets filled and # and plotted by masking all values that are do not match the target fill color df.loc[:,'tempval'] = df['smo2 [%]'] df.loc[df.zone_clr!='green','tempval']=0 ax1.fill_between(x_values,df.tempval,color='green') df.loc[:,'tempval'] = df['smo2 [%]'] df.loc[df.zone_clr!='orange','tempval']=0 ax1.fill_between(x_values,df.tempval,color='orange') df.loc[:,'tempval'] = df['smo2 [%]'] df.loc[df.zone_clr!='red','tempval']=0 ax1.fill_between(x_values,df.tempval,color='red') df.loc[:,'tempval'] = df['smo2 [%]'] df.loc[df.zone_clr!='blue','tempval']=0 ax1.fill_between(x_values,df.tempval,color='blue') # hgb plot. This uses the same field (zone_clr) to color the hgb plot in the same way, # using the tempval field df.loc[:,'tempval'] = df["hgb [g/dL]"] df.loc[df.zone_clr!='green','tempval']=0 ax2.fill_between(x_values,df.tempval,color='green') df.loc[:,'tempval'] = df["hgb [g/dL]"] df.loc[df.zone_clr!='orange','tempval']=0 ax2.fill_between(x_values,df.tempval,color='orange') df.loc[:,'tempval'] = df["hgb [g/dL]"] df.loc[df.zone_clr!='red','tempval']=0 ax2.fill_between(x_values,df.tempval,color='red') df.loc[:,'tempval'] = df["hgb [g/dL]"] df.loc[df.zone_clr!='blue','tempval']=0 ax2.fill_between(x_values,df.tempval,color='blue') # hr plot. This plot uses the same method, but the hr_clr field as the masking variable df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='grey','tempval']=0 ax3.fill_between(x_values,df.tempval,color='grey') df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='yellow','tempval']=0 ax3.fill_between(x_values,df.tempval,color='yellow') df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='green','tempval']=0 ax3.fill_between(x_values,df.tempval,color='green') df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='blue','tempval']=0 ax3.fill_between(x_values,df.tempval,color='blue') df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='purple','tempval']=0 ax3.fill_between(x_values,df.tempval,color='purple') df.loc[:,'tempval'] = df['heartRate [bpm]'] df.loc[df.hr_clr!='red','tempval']=0 ax3.fill_between(x_values,df.tempval,color='red')