updated plot headlines, updates pace_bar_plot avg-line calculation
This commit is contained in:
53
fit_app.py
53
fit_app.py
@@ -114,7 +114,7 @@ def process_fit(file_path):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
fit_file = FitFile(file_path)
|
fit_file = FitFile(file_path)
|
||||||
print(f"Verarbeite FIT-Datei: {file_path}")
|
print(f"\nVerarbeite FIT-Datei: {file_path}")
|
||||||
|
|
||||||
# Sammle alle record-Daten
|
# Sammle alle record-Daten
|
||||||
records = []
|
records = []
|
||||||
@@ -134,11 +134,11 @@ def process_fit(file_path):
|
|||||||
print(f"DataFrame erstellt mit {len(df)} Zeilen und Spalten: {list(df.columns)}")
|
print(f"DataFrame erstellt mit {len(df)} Zeilen und Spalten: {list(df.columns)}")
|
||||||
|
|
||||||
# Debugging: Schaue welche Spalten verfügbar sind
|
# Debugging: Schaue welche Spalten verfügbar sind
|
||||||
print(f"Verfügbare Spalten: {df.columns.tolist()}")
|
# print(f"Verfügbare Spalten: {df.columns.tolist()}") # Uncomment if needed - DEBUG purpose!
|
||||||
|
|
||||||
# Suche nach Heart Rate in verschiedenen Formaten
|
# Suche nach Heart Rate in verschiedenen Formaten
|
||||||
possible_hr_cols = [col for col in df.columns if 'heart' in col.lower() or 'hr' in col.lower()]
|
possible_hr_cols = [col for col in df.columns if 'heart' in col.lower() or 'hr' in col.lower()]
|
||||||
print(f"Mögliche Heart Rate Spalten: {possible_hr_cols}")
|
# print(f"Mögliche Heart Rate Spalten: {possible_hr_cols}") # Uncomment if needed - DEBUG purpose!
|
||||||
|
|
||||||
# Standard-Spaltennamen für verschiedene FIT-Formate
|
# Standard-Spaltennamen für verschiedene FIT-Formate
|
||||||
lat_cols = ['position_lat', 'lat', 'latitude']
|
lat_cols = ['position_lat', 'lat', 'latitude']
|
||||||
@@ -241,12 +241,13 @@ def process_fit(file_path):
|
|||||||
df = safe_add_column_to_dataframe(df, 'heart_rate', heart_rate)
|
df = safe_add_column_to_dataframe(df, 'heart_rate', heart_rate)
|
||||||
# ##############
|
# ##############
|
||||||
|
|
||||||
# MY DEBUG:
|
# ######################################
|
||||||
|
# IF issues with heart_rate values, usw these DEBUG prints:
|
||||||
#print(heart_rate)
|
#print(heart_rate)
|
||||||
if 'heart_rate' in df.columns:
|
if 'heart_rate' in df.columns:
|
||||||
df['heart_rate'] = pd.to_numeric(df['heart_rate'], errors='coerce')
|
df['heart_rate'] = pd.to_numeric(df['heart_rate'], errors='coerce')
|
||||||
df['hr_smooth'] = df['heart_rate'].rolling(window=5, center=True).mean()
|
df['hr_smooth'] = df['heart_rate'].rolling(window=5, center=True).mean()
|
||||||
print(f"Heart rate range: {df['heart_rate'].min():.0f} - {df['heart_rate'].max():.0f} bpm")
|
# print(f"Heart rate range: {df['heart_rate'].min():.0f} - {df['heart_rate'].max():.0f} bpm") # Uncomment if needed - DEBUG purpose!
|
||||||
else:
|
else:
|
||||||
print("Keine Heart Rate Daten gefunden!")
|
print("Keine Heart Rate Daten gefunden!")
|
||||||
df['heart_rate'] = np.nan
|
df['heart_rate'] = np.nan
|
||||||
@@ -255,6 +256,7 @@ def process_fit(file_path):
|
|||||||
print(f"Verarbeitete FIT-Datei: {len(df)} Datenpunkte")
|
print(f"Verarbeitete FIT-Datei: {len(df)} Datenpunkte")
|
||||||
print(f"Distanz: {df['cum_dist_km'].iloc[-1]:.2f} km")
|
print(f"Distanz: {df['cum_dist_km'].iloc[-1]:.2f} km")
|
||||||
print(f"Dauer: {df['duration_hms'].iloc[-1]}")
|
print(f"Dauer: {df['duration_hms'].iloc[-1]}")
|
||||||
|
# ######################################
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
@@ -359,7 +361,7 @@ def create_map_plot(df):
|
|||||||
df,
|
df,
|
||||||
lat='lat',
|
lat='lat',
|
||||||
lon='lon',
|
lon='lon',
|
||||||
zoom=13,
|
zoom=13.5,
|
||||||
height=800
|
height=800
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -697,7 +699,7 @@ def create_speed_plot(df):
|
|||||||
line=dict(color='royalblue')
|
line=dict(color='royalblue')
|
||||||
))
|
))
|
||||||
fig.update_layout(
|
fig.update_layout(
|
||||||
title=dict(text=f'Tempo über die Zeit (geglättet) - Durchschnittstempo: {mean_speed_kmh:.2f} km/h', font=dict(size=16)),
|
title=dict(text=f'Tempo über die Zeit (geglättet) - Ø {mean_speed_kmh:.2f} km/h', font=dict(size=16)),
|
||||||
xaxis=dict(title='Zeit', tickformat='%H:%M', type='date'),
|
xaxis=dict(title='Zeit', tickformat='%H:%M', type='date'),
|
||||||
yaxis=dict(title='Geschwindigkeit (km/h)', rangemode='tozero'),
|
yaxis=dict(title='Geschwindigkeit (km/h)', rangemode='tozero'),
|
||||||
template='plotly_dark',
|
template='plotly_dark',
|
||||||
@@ -862,7 +864,7 @@ def create_heart_rate_plot(df):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_pace_bars_plot(df):
|
def create_pace_bars_plot(df, formatted_pace=None):
|
||||||
# Ensure time column is datetime
|
# Ensure time column is datetime
|
||||||
if not pd.api.types.is_datetime64_any_dtype(df['time']):
|
if not pd.api.types.is_datetime64_any_dtype(df['time']):
|
||||||
df['time'] = pd.to_datetime(df['time'], errors='coerce')
|
df['time'] = pd.to_datetime(df['time'], errors='coerce')
|
||||||
@@ -920,45 +922,38 @@ def create_pace_bars_plot(df):
|
|||||||
|
|
||||||
|
|
||||||
# #########
|
# #########
|
||||||
# Add horizontal reference line - X-Werte für gesamte Breite
|
# Calculate average pace if not provided from Info-Banner function
|
||||||
# Calculate average pace
|
|
||||||
total_distance_km = df['cum_dist_km'].iloc[-1]
|
total_distance_km = df['cum_dist_km'].iloc[-1]
|
||||||
total_seconds = df['time_diff_sec'].iloc[-1]
|
total_seconds = df['time_diff_sec'].iloc[-1]
|
||||||
|
|
||||||
# Average pace (min/km) - KORRIGIERT
|
# Average pace (min/km) - KORRIGIERT
|
||||||
if total_distance_km > 0:
|
if total_distance_km > 0:
|
||||||
pace_sec_per_km = total_seconds / total_distance_km
|
pace_sec_per_km = total_seconds / total_distance_km
|
||||||
pace_min_per_km = pace_sec_per_km / 60 # Konvertiere zu Minuten pro km
|
pace_min = int(pace_sec_per_km // 60)
|
||||||
|
pace_sec = int(pace_sec_per_km % 60)
|
||||||
|
formatted_pace = f"{pace_min}:{pace_sec:02d} min/km"
|
||||||
|
# Numerischen Wert für die dash'ed Linie berechnen
|
||||||
|
avg_pace_numeric = pace_sec_per_km / 60
|
||||||
else:
|
else:
|
||||||
pace_min_per_km = 0
|
formatted_pace = "N/A"
|
||||||
|
avg_pace_numeric = 0
|
||||||
|
|
||||||
|
# Add horizontal dash'ed reference line (avg_pace_numeric)
|
||||||
fig.add_shape(
|
fig.add_shape(
|
||||||
type='line',
|
type='line',
|
||||||
x0=0, # Start bei 0
|
x0=0, # Start bei 0
|
||||||
x1=total_distance_km, # Ende bei maximaler Distanz
|
x1=total_distance_km, # Ende bei maximaler Distanz
|
||||||
y0=pace_min_per_km,
|
y0=avg_pace_numeric,
|
||||||
y1=pace_min_per_km,
|
y1=avg_pace_numeric,
|
||||||
line=dict(color='gray', width=1, dash='dash'),
|
line=dict(color='gray', width=1, dash='dash'),
|
||||||
)
|
)
|
||||||
|
|
||||||
## Optional: Text-Annotation für die durchschnittliche Pace
|
|
||||||
#fig.add_annotation(
|
|
||||||
# x=total_distance_km * 0.8, # Position bei 80% der Distanz
|
|
||||||
# y=pace_min_per_km,
|
|
||||||
# text=f"Ø {pace_min_per_km:.1f} min/km",
|
|
||||||
# showarrow=True,
|
|
||||||
# arrowhead=2,
|
|
||||||
# arrowcolor="gray",
|
|
||||||
# bgcolor="rgba(255,0,0,0.1)",
|
|
||||||
# bordercolor="gray",
|
|
||||||
# font=dict(color="white")
|
|
||||||
#)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
title_text = f'Tempo je Kilometer'
|
||||||
|
title_text += f' - Ø {formatted_pace}'
|
||||||
|
|
||||||
fig.update_layout(
|
fig.update_layout(
|
||||||
title=dict(text='Tempo (min/km) je Kilometer', font=dict(size=16)),
|
title=dict(text=title_text, font=dict(size=16, color='white')),
|
||||||
xaxis_title='Distanz (km)',
|
xaxis_title='Distanz (km)',
|
||||||
yaxis_title='Minuten pro km',
|
yaxis_title='Minuten pro km',
|
||||||
barmode='overlay',
|
barmode='overlay',
|
||||||
|
|||||||
Reference in New Issue
Block a user