tiktok_analytics / pages /followers.py
harrychangjr
clone to hf
64e353a
raw
history blame
7.19 kB
import streamlit as st
import pandas as pd
import numpy as np
import datetime
import plotly.express as px
import plotly.graph_objects as go
import statsmodels.api as sm
from millify import millify
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from st_aggrid import AgGrid
import io
import openpyxl
#from st_pages import Page, show_pages, add_page_title
# Set page title
st.set_page_config(page_title="Followers - Tiktok Analytics Dashboard", page_icon = "📊", layout = "centered", initial_sidebar_state = "auto")
st.header("Followers")
st.markdown("""Upload your files here to load your data!
*'Follower activity', 'Top territories', 'Gender', 'Total followers' (xlsx or csv format)*
""")
uploaded_files = st.file_uploader(
"Choose CSV or Excel files to upload",
accept_multiple_files=True,
type=['csv', 'xlsx'])
if uploaded_files:
data_list = []
# read the file
with st.expander("View uploaded data"):
for uploaded_file in uploaded_files:
st.write("▾ Filename:", uploaded_file.name)
bytes_data = uploaded_file.read()
data = None
if uploaded_file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
data = pd.read_excel(io.BytesIO(bytes_data))
AgGrid(data)
else:
data = pd.read_csv(io.StringIO(bytes_data.decode('utf-8')))
AgGrid(data)
data_list.append(data)
tab1, tab2, tab3, tab4, tab5 = st.tabs(["Follower Activity", "Gender", "Top Territories", "Followers", "Difference in Daily Followers"])
for data in data_list:
#st.write(data.columns)
#st.write(data)
with tab1:
if 'Active followers' in data.columns:
# create a list of all unique dates in the data
unique_dates = data['Date'].unique()
# Add a date filter widget
filter_type = st.sidebar.radio("Select filter type for Follower Activity", ["Individual date", "Total date range"])
if filter_type == "Individual date":
selected_date = st.sidebar.selectbox("Select a date", unique_dates)
# Filter the data to only include the selected date
filtered_data = data[data['Date'] == selected_date]
# Calculate the average number of followers for the selected date
avg_followers = filtered_data['Active followers'].mean()
elif filter_type == "Total date range":
# Filter the data to include the entire date range
filtered_data = data
# Calculate the average number of followers for the entire date range
avg_followers = filtered_data['Active followers'].mean()
#else:
# Get the start and end dates using st.date_input
#start_date = st.sidebar.date_input("Select start date", data['Date'].min(), data['Date'].max())
#end_date = st.sidebar.date_input("Select end date", data['Date'].min(), data['Date'].max())
# Filter the data based on the start and end dates
#filtered_data = data[(data['Date'] >= start_date) & (data['Date'] <= end_date)]
# create a datetime column from the date and hour columns
filtered_data['Datetime'] = pd.to_datetime(filtered_data['Date'] + ' ' + (filtered_data['Hour'] - 1).astype(str) + ':00:00')
# group the data by the datetime column and calculate the sum of active followers
grouped_data = filtered_data.groupby("Datetime")["Active followers"].sum().reset_index()
# create a line chart using Plotly Express
fig = px.line(filtered_data, x="Datetime", y="Active followers", title="Follower Activity")
# Add average line
fig.add_shape(type='line', x0=filtered_data['Datetime'].min(), y0=avg_followers, x1=filtered_data['Datetime'].max(), y1=avg_followers, line=dict(color='red', width=3, dash='dash'))
# Annotate average value onto average line
fig.add_annotation(x=filtered_data['Datetime'].max(), y=avg_followers, text=f"Average: {avg_followers:.0f}", showarrow=True, arrowhead=2)
st.plotly_chart(fig)
with tab2:
if 'Gender' in data.columns:
#st.write("Pie chart for 'Gender'")
gender_data = data.groupby('Gender')['Distribution'].apply(lambda x: pd.to_numeric(x.str.replace('%', ''), errors='coerce').dropna().mean()).reset_index()
fig = px.pie(gender_data, values='Distribution', names='Gender', title='Gender Distribution (%)',
color_discrete_sequence=['#1f77b4', '#ff7f0e'])
st.plotly_chart(fig)
with tab3:
if 'Top territories' in data.columns:
territories_data = data.groupby('Top territories')['Distribution'].apply(lambda x: pd.to_numeric(x.str.replace('%', ''), errors='coerce').dropna().mean()).reset_index()
territories_data = territories_data.sort_values(by='Distribution', ascending=True)
#st.write("Top 5 territories by distribution")
fig = px.bar(territories_data, x='Distribution', y='Top territories', title='Distribution (%) of Top 5 Countries',
color_discrete_sequence=px.colors.qualitative.Dark2)
st.plotly_chart(fig)
with tab4:
if 'Followers' in data.columns:
fig = px.line(data, x="Date", y="Followers", title="Total Followers", markers=True,
hover_data={'Followers': ':.2f'})
st.plotly_chart(fig)
with tab5:
if 'Difference in followers from previous day' in data.columns:
# Create a custom color scale
def custom_color_scale(val):
if val >= 0:
return 'rgba(54, 164, 235, 0.8)'
else:
return 'rgba(255, 77, 77, 0.8)'
fig = px.bar(data, x="Date", y="Difference in followers from previous day", title="Difference in Daily Followers",
text='Difference in followers from previous day', color='Difference in followers from previous day',
hover_data={'Difference in followers from previous day': ':.2f'}, color_discrete_map={val: custom_color_scale(val) for val in data['Difference in followers from previous day']})
# Customize the layout
fig.update_layout(
title="Difference in Daily Followers",
xaxis_title="Date",
yaxis_title="Difference in Daily Followers",
showlegend=False,
plot_bgcolor="white",
yaxis=dict(zeroline=True, zerolinewidth=2, zerolinecolor="black"), # Add a line at y=0
)
st.plotly_chart(fig)