From 806fdaad4dfd05355ae699ae2a47dd95c8180a03 Mon Sep 17 00:00:00 2001 From: Thies Lennart Alff Date: Sat, 29 Jul 2023 23:06:10 +0200 Subject: [PATCH] updated hrv plot --- hrv_trends.py | 305 +++++++++++++++++++++++++++++--------------------- 1 file changed, 179 insertions(+), 126 deletions(-) diff --git a/hrv_trends.py b/hrv_trends.py index be4000f..bd3f47b 100644 --- a/hrv_trends.py +++ b/hrv_trends.py @@ -25,6 +25,181 @@ HRV_CV = 'HrvCv' HRV_VAR_BASE = 'HrvVarBase' +def plot_plotly(): + lts_trace = Scatter(x=pmc_data['date'], + y=pmc_data['lts'], + name='Fitness (LTS)', + fill='tozeroy', + line=dict(color='#1f77b4')) + sts_trace = Scatter(x=pmc_data['date'], + y=pmc_data['sts'], + name='Fatigue (STS)', + fill='tozeroy', + line=dict(color='#FF6692')) + + sb_trace = Scatter(x=pmc_data['date'], y=pmc_data['sb'], name='Form (TSB)') + + hr_trace = Scatter(x=hrv_data['date'], + y=hrv_data[HR_BASE], + mode='lines', + name=f'{BASELINE_DAYS}-day HR Baseline') + + hrv_ceiling_trace = Scatter(x=hrv_data['date'], + y=hrv_data[HRV_CEILING], + fill=None, + mode='lines', + name=f"{NORMALRANGE_DAYS}-day Top Normal", + line=dict(color='#b3f6d1', )) + hrv_floor_trace = Scatter(x=hrv_data['date'], + y=hrv_data[HRV_FLOOR], + fill='tonexty', + mode='lines', + name=f'{NORMALRANGE_DAYS}-day Bottom Normal', + line=dict(color='#b3f6d1', )) + + hrv_base_trace = Scatter(x=hrv_data['date'], + y=hrv_data[HRV_BASE], + mode='lines', + name=f"{BASELINE_DAYS}-day Baseline", + line=dict(color='red', )) + + hrv_trace = Bar(x=hrv_data['date'], + y=hrv_data[HRV], + name="Recovery Points", + marker=dict(color='gray', )) + + hrv_cv_trace = Scatter(x=hrv_data['date'], + y=hrv_data[HRV_CV], + name='CV', + mode='lines', + line=dict(color='yellow')) + + # session_rpe_trace = Bar(x=rpe['date'], + # y=rpe['Session_RPE'], + # name='RPE', + # marker=dict(color='lightgray', )) + rpe_trace = Bar(x=rpe['date'], + y=rpe['RPE'], + name='RPE', + marker=dict(color='red', )) + + layout = Layout( + template='plotly_dark', + # paper_bgcolor='rgba(0,0,0,0)', + # plot_bgcolor='rgba(0,0,0,0)', + yaxis=dict(title="HRV Recovery Points", range=[5.5, 10]), + yaxis2=dict(title="Coeffient of Variation", range=[0, 20]), + yaxis3=dict(title=f'{TRAINING_STRESS}'), + yaxis4=dict(title='HRV (ln(RMSSD)'), + yaxis5=dict(title='HR (BPM)'), + legend=dict(orientation="h")) + + fig = make_subplots( + 4, + 1, + subplot_titles=[ + 'HRV', + 'Coefficient of Variaton', + 'Stress', + 'HRV vs. HR', + ], + specs=[ + [dict(secondary_y=False)], + [dict(secondary_y=False)], + [dict(secondary_y=False)], + [dict(secondary_y=True)], + # [dict(secondary_y=True)], + ], + # horizontal_spacing=0.2, + # vertical_spacing=0.2 + ) + fig.update_layout(template='plotly_dark') + fig.add_trace(hrv_trace, 1, 1) + fig.add_trace(hrv_ceiling_trace, 1, 1) + fig.add_trace(hrv_floor_trace, 1, 1) + fig.add_trace(hrv_base_trace, 1, 1) + # fig.add_trace(sb_trace, 1, 1, secondary_y=True) + fig.add_trace(hrv_cv_trace, 2, 1) + fig.add_trace(sts_trace, 3, 1) + fig.add_trace(lts_trace, 3, 1) + fig.add_trace(hr_trace, 4, 1, secondary_y=True) + fig.add_trace(hrv_base_trace, 4, 1) + # fig.add_trace(session_rpe_trace, 2, 2) + # fig.add_trace(rpe_trace, 5, 1) + fig.update_layout(layout) + fig.update_layout( + dict( + yaxis=dict(showline=True, mirror=True, ticks='inside'), + yaxis2=dict(showline=True, mirror=True, ticks='inside'), + yaxis3=dict(showline=True, mirror=True, ticks='inside'), + yaxis4=dict(showline=True, mirror=True, ticks='inside'), + yaxis5=dict(showline=True, mirror=True, ticks='inside'), + yaxis6=dict(showline=True, mirror=True, ticks='inside'), + yaxis7=dict(showline=True, mirror=True, ticks='inside'), + yaxis8=dict(showline=True, mirror=True, ticks='inside'), + xaxis=dict(showline=True, mirror=True, ticks='inside'), + xaxis2=dict(showline=True, mirror=True, ticks='inside'), + xaxis3=dict(showline=True, mirror=True, ticks='inside'), + xaxis4=dict(showline=True, mirror=True, ticks='inside'), + xaxis5=dict(showline=True, mirror=True, ticks='inside'), + xaxis6=dict(showline=True, mirror=True, ticks='inside'), + xaxis7=dict(showline=True, mirror=True, ticks='inside'), + xaxis8=dict(showline=True, mirror=True, ticks='inside'), + )) + fig.update_xaxes(showline=True, + linewidth=1, + linecolor='black', + mirror=True) + fig.update_yaxes(showline=True, + linewidth=1, + linecolor='black', + mirror=True) + + f = plotly.offline.plot(fig, + auto_open=False, + filename=tempfile.gettempdir() + "/temp-plot.html") + + GC.webpage("file://" + f) + + +def plot_native(): + GC.setChart(title='test', + type=GC.CHART_LINE, + orientation=GC_VERTICAL, + legpos=GC_ALIGN_TOP, + stack=False, + animate=False) + hrv_data['date_internal'] = (hrv_data['date'] - + pd.to_datetime('1900-01-01').date()).dt.days + xx = hrv_data['date_internal'] + settings = dict(symbol=GC_SYMBOL_NONE, + line=GC_LINE_SOLID, + color='red', + opacity=100, + xaxis='Date', + yaxis='lnRMSSD', + size=3, + opengl=False) + GC.addCurve(name='HRV', x=xx, y=hrv_data[HRV_BASE], **settings) + + settings['color'] = 'green' + settings['opacity'] = 50 + settings['line'] = GC_LINE_DASH + GC.addCurve(name='Normal Top', x=xx, y=hrv_data[HRV_CEILING], **settings) + GC.addCurve(name='Normal Bot', x=xx, y=hrv_data[HRV_FLOOR], **settings) + + settings['color'] = 'yellow' + settings['opacity'] = 100 + settings['line'] = GC_LINE_SOLID + settings['yaxis'] = 'Coefficient of Variation' + GC.addCurve(name='Variation', x=xx, y=hrv_data[HRV_CV], **settings) + + GC.setAxis('Date', type=GC.AXIS_DATE) + GC.setAxis('Coefficient of Variation', + type=GC.AXIS_CONTINUOUS, + min=0, + max=50) + def get_hrv_measures(): history = pd.DataFrame(GC.seasonMeasures( @@ -46,7 +221,8 @@ def compute_hrv_trends(df: pd.DataFrame): df[HR_BASE] = df[HR].rolling(window=BASELINE_DAYS, min_periods=BASELINE_DAYS // 2).mean() - df[HRV_VAR_BASE] = df[HRV].rolling(window=BASELINE_DAYS, min_periods=BASELINE_DAYS // 2).std() + df[HRV_VAR_BASE] = df[HRV].rolling(window=BASELINE_DAYS, + min_periods=BASELINE_DAYS // 2).std() df[HRV_CV] = df[HRV_VAR_BASE] / df[HRV_BASE] * 100.0 return df @@ -94,128 +270,5 @@ rpe = get_rpe() stress = get_stress() pmc_data = get_pmc_data(stress.iloc[-1]['date']) -lts_trace = Scatter(x=pmc_data['date'], - y=pmc_data['lts'], - name='Fitness (LTS)', - fill='tozeroy', - line=dict(color='#1f77b4')) -sts_trace = Scatter(x=pmc_data['date'], - y=pmc_data['sts'], - name='Fatigue (STS)', - fill='tozeroy') - -sb_trace = Scatter(x=pmc_data['date'], y=pmc_data['sb'], name='Form (TSB)') - -hr_trace = Scatter(x=hrv_data['date'], - y=hrv_data[HR_BASE], - mode='lines', - name=f'{BASELINE_DAYS}-day HR Baseline') - -hrv_ceiling_trace = Scatter(x=hrv_data['date'], - y=hrv_data[HRV_CEILING], - fill=None, - mode='lines', - name=f"{NORMALRANGE_DAYS}-day Top Normal", - line=dict(color='#b3f6d1', )) -hrv_floor_trace = Scatter(x=hrv_data['date'], - y=hrv_data[HRV_FLOOR], - fill='tonexty', - mode='lines', - name=f'{NORMALRANGE_DAYS}-day Bottom Normal', - line=dict(color='#b3f6d1', )) - -hrv_base_trace = Scatter(x=hrv_data['date'], - y=hrv_data[HRV_BASE], - mode='lines', - name=f"{BASELINE_DAYS}-day Baseline", - line=dict(color='red', )) - -hrv_trace = Bar(x=hrv_data['date'], - y=hrv_data[HRV], - name="Recovery Points", - marker=dict(color='lightgray', )) - -hrv_cv_trace = Scatter(x=hrv_data['date'], - y=hrv_data[HRV_CV], - name='CV', - mode='lines', - line=dict(color='black')) - -# session_rpe_trace = Bar(x=rpe['date'], -# y=rpe['Session_RPE'], -# name='RPE', -# marker=dict(color='lightgray', )) -rpe_trace = Bar(x=rpe['date'], - y=rpe['RPE'], - name='RPE', - marker=dict(color='red', )) - -layout = Layout(template='none', - paper_bgcolor='rgba(0,0,0,0)', - plot_bgcolor='rgba(0,0,0,0)', - yaxis=dict(title="HRV Recovery Points", range=[5.5, 10]), - yaxis2=dict(title="Coeffient of Variation", range=[0, 20]), - yaxis3=dict(title=f'{TRAINING_STRESS}'), - yaxis4=dict(title='HRV (ln(RMSSD)'), - yaxis5=dict(title='HR (BPM)'), - legend=dict(orientation="h")) - -fig = make_subplots( - 4, - 1, - subplot_titles=[ - 'HRV', - 'Stress', - 'HRV vs. HR', - 'RPE', - ], - specs=[ - [dict(secondary_y=False)], - [dict(secondary_y=False)], - [dict(secondary_y=False)], - [dict(secondary_y=True)], - # [dict(secondary_y=True)], - ], - # horizontal_spacing=0.2, - # vertical_spacing=0.2 -) -fig.add_trace(hrv_trace, 1, 1) -fig.add_trace(hrv_ceiling_trace, 1, 1) -fig.add_trace(hrv_floor_trace, 1, 1) -fig.add_trace(hrv_base_trace, 1, 1) -# fig.add_trace(sb_trace, 1, 1, secondary_y=True) -fig.add_trace(hrv_cv_trace, 2, 1) -fig.add_trace(sts_trace, 3, 1) -fig.add_trace(lts_trace, 3, 1) -fig.add_trace(hr_trace, 4, 1, secondary_y=True) -fig.add_trace(hrv_base_trace, 4, 1) -# fig.add_trace(session_rpe_trace, 2, 2) -# fig.add_trace(rpe_trace, 5, 1) -fig.update_layout(layout) -fig.update_layout( - dict( - yaxis=dict(showline=True, mirror=True, ticks='inside'), - yaxis2=dict(showline=True, mirror=True, ticks='inside'), - yaxis3=dict(showline=True, mirror=True, ticks='inside'), - yaxis4=dict(showline=True, mirror=True, ticks='inside'), - yaxis5=dict(showline=True, mirror=True, ticks='inside'), - yaxis6=dict(showline=True, mirror=True, ticks='inside'), - yaxis7=dict(showline=True, mirror=True, ticks='inside'), - yaxis8=dict(showline=True, mirror=True, ticks='inside'), - xaxis=dict(showline=True, mirror=True, ticks='inside'), - xaxis2=dict(showline=True, mirror=True, ticks='inside'), - xaxis3=dict(showline=True, mirror=True, ticks='inside'), - xaxis4=dict(showline=True, mirror=True, ticks='inside'), - xaxis5=dict(showline=True, mirror=True, ticks='inside'), - xaxis6=dict(showline=True, mirror=True, ticks='inside'), - xaxis7=dict(showline=True, mirror=True, ticks='inside'), - xaxis8=dict(showline=True, mirror=True, ticks='inside'), - )) -fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True) -fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True) - -f = plotly.offline.plot(fig, - auto_open=False, - filename=tempfile.gettempdir() + "/temp-plot.html") - -GC.webpage("file://" + f) +plot_native() +plot_plotly()