diff --git a/habits.py b/habits.py deleted file mode 100644 index 3325597..0000000 --- a/habits.py +++ /dev/null @@ -1,214 +0,0 @@ -import pandas as pd -import vobject -import requests -from datetime import datetime, date -import matplotlib.pyplot as plt -import calmap -import streamlit as st -import plotly.express as px -import plotly.graph_objects as go -import json -import os - - - -# Function to load data from a JSON file -def load_data(file_path): - try: - with open(file_path, 'r') as file: - if os.path.getsize(file_path) == 0: return {} - return json.load(file) - except FileNotFoundError: - print("settings file not found") - return {} - except : - print("settings file invalid") - return {} - - -# Function to save data to a JSON file -def save_data(file_path, data): - with open(file_path, 'w') as file: - json.dump(data, file) - - -# Function to create a calendar heatmap for a specific year -def create_calendar_heatmap(event_series, year): - # Filter the series to include only the specific year - event_series_year = event_series[event_series.index.year == year] - - # Create a complete date range for the year - all_dates_year = pd.date_range(start=f'{year}-01-01', end=f'{year}-12-31') - - # Reindex the Series to include all dates in the year and fill missing dates with zero - event_series_year = event_series_year.reindex(all_dates_year, fill_value=0) - - # Create a DataFrame for Plotly - df_year = pd.DataFrame({'Date': event_series_year.index, 'Events': event_series_year.values}) - - # Generate day of the week and week of the year - df_year['DayOfWeek'] = df_year['Date'].dt.dayofweek - df_year['WeekOfYear'] = df_year['Date'].dt.isocalendar().week - df_year['Month'] = df_year['Date'].dt.strftime('%b') - - # Create the Plotly figure - fig = go.Figure(data=go.Heatmap( - z=df_year['Events'], - x=df_year['WeekOfYear'], - y=df_year['DayOfWeek'], - colorscale='YlGn', - showscale=True, - colorbar=dict( - title='# of Events', - orientation='h', # Set the color scale to horizontal - len=0.3, # Adjust the length of the color scale - thickness=10, - x=0.98, - y=1, - xanchor="right", - yanchor="bottom", # Position the color scale at the bottom - ), - hoverinfo='z+x+y' - )) - - # Set the aspect ratio to ensure square boxes - fig.update_yaxes(scaleanchor="x", scaleratio=1, constrain="domain") - - # Update the layout with the axes - fig.update_layout( - title=f'Calendar Heatmap for {year}', - yaxis=dict( - tickmode='array', - tickvals=[0, 1, 2, 3, 4, 5, 6], - ticktext=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], - range=[-1.2, 6.5], # Adjust the range to eliminate space - automargin=True, # Adjust margins automatically - domain=[0.1,0.95] # Use available space effectively - ), - xaxis=dict( - tickmode='array', - tickvals=list(range(1, 54)), - ticktext=list(range(1, 54)), - title=dict( - text='Weeks of the Year', - standoff=0 - ), - title_standoff=0, # Adjust the distance of the title from the axis - tickangle=-90, # Adjust the angle of the week numbers - ticklen=2, - side='top', # Display x-axis ticks above the heatmap - automargin=True, # Adjust margins automatically - ), - autosize=True, - margin=dict( - l=50, - r=50, - b=30, # Increase bottom margin to fit month names - t=30, # Increase top margin to fit week numbers - pad=0 - ), - height=450, # Fixed height to avoid excessive space - ) - - # Add month annotations with arrows at the bottom - month_starts = df_year.iloc[:-10].groupby('Month')['WeekOfYear'].min().to_dict() - for month, week in month_starts.items(): - fig.add_annotation( - x=week, - y=-0.5, # Position below the x-axis - text=month, - showarrow=False, - arrowhead=2, - ax=week, - ay=0, # Position the arrow closer - xref="x", - yref="y", - #font=dict(size=12, color="black"), - xanchor='left', - yanchor='top' - ) - - return fig - - -def save_load(): - st.session_state['options'].pop("New") - save_data(settings_file, st.session_state['options']) - st.session_state['options'] = load_data(settings_file) - -def update_params(): - st.session_state['cal_url'] = st.session_state['options'][st.session_state['setup']]['cal_url'] - st.session_state['number_of_years'] = st.session_state['options'][st.session_state['setup']]['number_of_years'] - - -# set webpage title -st.title("Yearly Activity Heatmaps") - -# File path for data storage -settings_file = 'settings.json' -# Load persisted data if it exists; set default values otherwise -st.session_state['options'] = load_data(settings_file) -st.session_state['options']["New"] = { - 'cal_url':"https://canada-holidays.ca/ics?cd=true", - 'number_of_years': 3 - } - -# Get the Calendar Export link and number of years from sidebar menu -st.sidebar.header("Settings") -st.session_state['setup'] = st.sidebar.selectbox("Choose a Setup:", st.session_state['options'].keys()) -st.session_state['cal_url'] = st.sidebar.text_input("Enter The Calendar Export Link:", value=st.session_state['options'][st.session_state['setup']]['cal_url']) -st.session_state['number_of_years'] = st.sidebar.number_input("Enter the number of years:", min_value=1, max_value=10, value=st.session_state['options'][st.session_state['setup']]['number_of_years']) -update_params() -if(st.session_state['setup'] == "New"): - setup_save_name = st.sidebar.text_input("Setup Save Name:", value='yahoo') - st.session_state['options'][setup_save_name] = { - 'cal_url': st.session_state['cal_url'], - 'number_of_years': st.session_state['number_of_years'] - } - st.sidebar.button("Save",on_click=save_load) - - -response = requests.get(st.session_state['cal_url']) -if response.status_code == 200: - # Parse the .ics file - cal = vobject.readOne(response.text) -else: - print("Failed to download the file") - - - - -# Create a dictionary to store event counts by date -event_counts = {} -for component in cal.components(): - if component.name == "VEVENT": - event_date = component.dtstart.value - if isinstance(event_date, datetime): - event_date = event_date.date() - if event_date in event_counts: - event_counts[event_date] += 1 - else: - event_counts[event_date] = 1 - - - -# Convert the dictionary to a pandas Series -event_series = pd.Series(event_counts) -# Ensure the index is in datetime format -event_series.index = pd.to_datetime(event_series.index) - - -# Get the current year -current_year = datetime.now().year -# Create a list of years to plot -years_to_plot = [current_year - i for i in range(st.session_state['number_of_years'])] - - - -# Plot each year's data -for year in years_to_plot: - fig = create_calendar_heatmap(event_series, year) - st.plotly_chart(fig) - - -