gc_plots/weight_trend.py
2025-05-03 20:54:38 +02:00

90 lines
2.4 KiB
Python

import pandas as pd
import numpy as np
WEIGHT_RANGE = [75, 85]
def to_date(date):
return (date - pd.to_datetime("1900-01-01").date()).days
def get_weight_measures():
# query non-zero
data = pd.DataFrame(GC.seasonMeasures(group="Body")).query("WEIGHTKG != 0.0")[
["date", "WEIGHTKG"]
]
data.reset_index(inplace=True)
print(data)
weight = data["WEIGHTKG"].to_numpy().flatten()
weight_shifted = data["WEIGHTKG"].shift(periods=1).to_numpy().flatten()
weight_shifted[0] = 0.0
change = weight - weight_shifted
indices = np.argwhere(change != 0.0).flatten()
weight = weight[indices]
print(data["date"])
print(indices)
date = (
data["date"].loc[indices] - pd.to_datetime("1900-01-01").date()
).dt.days.to_numpy()
return pd.DataFrame(
np.hstack([date.reshape([-1, 1]), weight.reshape([-1, 1])]),
columns=["date", "WEIGHTKG"],
)
def trendline(weight_data, start, end):
weight = weight_data["WEIGHTKG"]
date = weight_data["date"]
y = weight.to_numpy()
x = date.to_numpy()
coeffs = np.polyfit(x[1:], y[1:], 1)
poly = np.poly1d(coeffs)
trend = poly([start, end])
trend_x = np.array([start, end])
return pd.DataFrame(
np.hstack([trend_x.reshape([-1, 1]), trend.reshape([-1, 1])]),
columns=["date", "trend"],
), (trend[0], (trend[-1] - trend[0]) / (trend_x[-1] - trend_x[0]))
season = GC.season()
t_min = to_date(season["start"][0])
t_max = to_date(season["end"][0])
weight_data = get_weight_measures()
trend_data, trend_coeffs = trendline(weight_data, t_min, t_max)
GC.setChart(
type=GC.CHART_LINE,
orientation=GC_VERTICAL,
legpos=GC_ALIGN_RIGHT,
stack=False,
animate=True,
)
settings = {
"symbol": GC_SYMBOL_CIRCLE,
"line": GC_LINE_SOLID,
"color": "red",
"opacity": 100,
"xaxis": "Date",
"yaxis": "Weight",
"size": 3,
"opengl": False,
}
GC.addCurve(name="Weight", x=weight_data["date"], y=weight_data["WEIGHTKG"], **settings)
settings["symbol"] = GC_SYMBOL_NONE
settings["line"] = GC_LINE_SOLID
settings["color"] = "yellow"
GC.addCurve(
name=f"Trend: {trend_coeffs[0]:.2f} {trend_coeffs[1]*7:+.2f}/week",
x=trend_data["date"],
y=trend_data["trend"],
**settings,
)
GC.setAxis("Date", type=GC.AXIS_DATE, min=t_min, max=t_max)
GC.setAxis(
"Weight",
type=GC.AXIS_CONTINUOUS,
min=WEIGHT_RANGE[0],
max=WEIGHT_RANGE[1],
color="red",
)