File size: 7,188 Bytes
64e353a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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)