Torn.com-ActivityTracker/app/analysis/plotly_heat_user-activity.py

83 lines
2.8 KiB
Python
Raw Permalink Normal View History

2025-02-22 16:55:41 +01:00
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from .basePlotlyAnalysis import BasePlotlyAnalysis
from flask import current_app, url_for
class PlotlyActivityHeatmap(BasePlotlyAnalysis):
"""
Class for analyzing user activity trends over multiple days and generating an interactive heatmap.
Attributes:
name (str): The name of the analysis.
description (str): A brief description of the analysis.
plot_filename (str): The filename for the output plot.
note (str): Additional notes for the analysis.
"""
name = "Activity Heatmap (Interactive)"
description = "Displays user activity trends over multiple days using an interactive heatmap."
plot_filename = "activity_heatmap.html"
note = ""
def transform_data(self, df: pd.DataFrame) -> pd.DataFrame:
"""
Transform data for the heatmap.
Parameters:
df (pd.DataFrame): The input DataFrame containing user activity data.
Returns:
pd.DataFrame: The transformed DataFrame with activity counts by hour.
"""
df['hour'] = df['timestamp'].dt.hour
active_counts = df[df['was_active']].pivot_table(
index='name',
columns='hour',
values='was_active',
aggfunc='sum',
fill_value=0
).reset_index()
# Ensure all hours are represented
all_hours = pd.DataFrame({'hour': range(24)})
active_counts = active_counts.melt(id_vars='name', var_name='hour', value_name='activity_count')
active_counts = active_counts.merge(all_hours, on='hour', how='right').fillna(0)
active_counts['hour'] = active_counts['hour'].astype(int) # Ensure hour is treated as numeric
return active_counts
def plot_data(self, df: pd.DataFrame):
"""
Generate heatmap plot.
Parameters:
df (pd.DataFrame): The transformed DataFrame containing activity counts by hour.
"""
df = df.pivot(index='name', columns='hour', values='activity_count').fillna(0)
# Create a Plotly heatmap
self.fig = go.Figure(data=go.Heatmap(
z=df.values,
x=df.columns,
y=df.index,
colorscale='Viridis',
colorbar=dict(title='Count of was_active == True')
))
# Update layout
self.fig.update_layout(
title='User Activity Heatmap',
xaxis_title='Hour of Day',
yaxis_title='User ID',
xaxis=dict(tickmode='linear', dtick=1, range=[0, 23]), # Ensure x-axis covers all hours
template='plotly_white'
)
self.fig.update_traces(
hovertemplate="<br>".join([
"Hour: %{x}",
"Name: %{y}",
"Activity: %{z}",
])
)