#!/usr/bin/env python # coding: utf-8 # Visualizing my step data, from a Garmin [vívofit](https://buy.garmin.com/en-US/US/p/143405) (until about May 2016), a [Forerunner 235](https://buy.garmin.com/en-US/US/p/529988) (May 2016 - June 2019) and a [Forerunner 935](https://buy.garmin.com/en-US/US/p/564291) (since June 2019). # The data has been recorded to the [Apples Health](https://www.apple.com/ios/health/) app by [Garmin Connect](https://connect.garmin.com/). # I exported the data from Apple Health to a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) file with the [QS Access](http://quantifiedself.com/qs-access-app/) app. # In[1]: # Load some modules we need import pandas # for data manipulation import matplotlib.pylab as plt # for plotting import seaborn # for plot styling import dateutil.relativedelta # for date calculations import calendar # for easy day and month names in the tick labels # In[2]: # Set some defaults seaborn.set_style('dark') plt.rcParams['figure.figsize'] = (16, 9) # Size up figures a bit # In[3]: # Read in data data = pandas.read_csv('steps.csv') # In[4]: # How does it look like? data.head() # In[5]: data.tail() # In[6]: # Massage data data.rename(columns={'Start': 'Date'}, inplace=True) data.rename(columns={'Steps (count)': 'Steps'}, inplace=True) data.Steps = data.Steps.astype(int) data.drop('Finish', axis=1, inplace=True) # In[7]: # How doed it look now? data.head() # In[8]: data.tail() # In[9]: # Make us a proper date column, based on https://stackoverflow.com/a/26763793 data['Date'] = pandas.to_datetime(data['Date']) # In[10]: # Make us a year, month and weekday colum, based on https://stackoverflow.com/q/48623332 data['Year'] = data.Date.dt.year data['Month'] = data.Date.dt.month data['Day'] = data.Date.dt.day data['Weekday'] = data.Date.dt.dayofweek # In[11]: # How doed it look now? data.head() # In[12]: yearwelookat = 2021 # In[13]: # Give out totals to see if we have approximately the same as shown in Garmin Connect print('In %s I made a total of %0.2f Million steps' % (yearwelookat, data[(data.Year == yearwelookat)]['Steps'].sum() * 1e-6)) # In[14]: if calendar.isleap(yearwelookat): dpy = 366 else: dpy = 365 # In[15]: # Give out totals to see if we have approximately the same as shown in Garmin Connect print('In %s I made %s steps per day' % (yearwelookat, int(round(data[(data.Year == yearwelookat)]['Steps'].sum() / dpy)))) # In[16]: # Give out totals to see if we have approximately the same as shown in Garmin Connect # In Garmin connect, go go 'Reports' in the sidebar, then 'Health & Fitness' > 'Steps'¨ # You can also try to mangle the export of *all* the Garmin data you get from 'Export your Data' here: https://www.garmin.com/en-US/account/datamanagement/ for month in sorted(data.Date.dt.month.unique()): print('In %s %s I made a total of %s steps' % (calendar.month_name[month], yearwelookat, data[(data.Year == yearwelookat) & (data.Month == month)]['Steps'].sum())) # In[17]: # When were the five highest step counts? data[data.Year == yearwelookat].sort_values('Steps', ascending=False).head() # In[18]: # When were the five lowest step counts? data[data.Year == yearwelookat].sort_values('Steps').head() # In[19]: # Generate us a nice plot title, with help from https://stackoverflow.com/a/32083946/323100 Duration = dateutil.relativedelta.relativedelta(data[data.Year == yearwelookat].Date.max(), data[data.Year == yearwelookat].Date.min()) # In[20]: # Generate us some nice tick labels Ticklabels_weekday = ['%s\n~%g steps' % (d, round(s / 1e3, 1) * 1e3) for (s, d) in zip(data[data.Year == yearwelookat].groupby('Weekday').Steps.mean(), list(calendar.day_name))] # Generate us some nice tick labels Ticklabels_month = ['%s\n~%g steps' % (m, round(s / 1e3, 1) * 1e3) for (s, m) in zip(data[data.Year == yearwelookat].groupby('Month').Steps.mean(), list(calendar.month_name[1:]))] # Generate us some nice tick labels Ticklabels_year = ['%s\n~%g steps' % (y, round(s / 1e3, 1) * 1e3) for (s, y) in zip(data[data.Year == yearwelookat].groupby('Year').Steps.mean(), data[data.Year == yearwelookat].Year.unique())] # In[21]: # Plot the steps per weekday seaborn.boxplot(data=data[data.Year == yearwelookat], x='Weekday', y='Steps', fliersize=0) seaborn.stripplot(data=data[data.Year == yearwelookat], x='Weekday', y='Steps', jitter=True, linewidth=1) plt.gca().set_xticklabels(Ticklabels_weekday) plt.title('Weekday steps for %s months and %s days in %s' % (Duration.months, Duration.days, yearwelookat)) plt.gca().xaxis.label.set_visible(False) seaborn.despine() plt.show() # In[22]: # Plot the steps per month seaborn.boxplot(data=data[data.Year == yearwelookat], x='Month', y='Steps', fliersize=0) seaborn.stripplot(data=data[data.Year == yearwelookat], x='Month', y='Steps', jitter=True, linewidth=1) plt.gca().set_xticklabels(Ticklabels_month) plt.title('Monthly steps for %s months and %s days in %s' % (Duration.months, Duration.days, yearwelookat)) plt.gca().xaxis.label.set_visible(False) seaborn.despine() plt.show() # In[ ]: