Techno Blender
Digitally Yours.

Building a Medium Stats Tracker With Streamlit | by Andy McDonald | Feb, 2023

0 51


Photo by Markus Winkler on Unsplash

I have been a writer on Medium for a while and recently started tracking my statistics using Excel. But, more recently, I have been thinking of building an app using Streamlit to provide a better experience. So I thought why not give it a go and write an article as I build it?

Within this article, we are going to go through the process of building a simple Streamlit dashboard and provide a way for the end user to enter their latest statistics using forms. By the end of the article, we will have a basic dashboard that we can build upon and make even more robust at a later date.

Streamlit dashboard for viewing and analysing Medium statistics. Image by the author

If you are just getting started with Streamlit, you may want to check out my articles below.

The first step is to import our key python libraries: streamlit, pandas and plotly_express. Following that, we need to configure the app to default to a wide display, and we will also add a title for our app.

import streamlit as st
import pandas as pd
import plotly_express as px

st.set_page_config(layout='wide')

st.header('Medium Stats Dashboard')

Next, we need to create a new CSV file within the same directory as our app and assign it the name medium_stats.

We will need to open the file and write in four columns. We could do this through code, but this is a quick and easy way to set the file up for now.

CSV starting file for the Medium Stats Dashboard within Streamlit. Image by the author.

The first piece of functionality we will set up is the ability for a user to enter their stats within the dashboard and update the CSV file.

def update_stats_csv(date, followers, email_subs, ref_members):
with open('medium_stats.csv', 'a+') as f:
f.write(f'\n{date},{followers},{email_subs},{ref_members}')

This piece of code will open the CSV file, and append a new row onto it, where a comma separates each stat.

Next, we need to create a simple form allowing the user to input the stats. This is achieved using the st.form functionality within Streamlit. We can then use the with statement and begin adding the number of entry boxes for each key stat that we want to track in our dashboard.

We will also add this to the sidebar, so it doesn’t clutter up the main display.

with st.sidebar.form('Enter the latest stats from your Medium dashboard'):

date = st.date_input('Date')

follower_num = st.number_input('Followers', step=1)
email_subs = st.number_input('Email Subscribers', step=1)
ref_members = st.number_input('Referred Members', step=1)

submit_stats = st.form_submit_button('Write Stats to CSV')

if submit_stats:
update_stats_csv(date, follower_num, email_subs, ref_members)
st.info(f'Stats for {date} have been added to the csv file')

When we re-run our Streamlit app, we should see the following form appear in the sidebar.

Streamlit Medium Stats Entry form on the sidebar. Image by the author.

When we select a date and add a few numbers, we can then click on the Write Stats to CSV button to commit the values to the CSV file. We will also be prompted by a callout stating that the stats have been added to the file.

Streamlit Medium Stats Entry form after adding statistics for a month. Image by the author.

If we return to the CSV file, we will see a new line within the file with the stats we just added.

CSV file after stats have been written from the Streamlit app. Image by the author.

Great! We have confirmed we can add stats directly to the CSV file. Now we can move on to loading the CSV file and begin creating charts for all months.

Within the main part of the Streamlit app, we are going to add an expander. When this is clicked on and expanded, we will be able to see the raw data from the CSV file within a pandas dataframe.

df = pd.read_csv('medium_stats.csv')

with st.expander('View Raw Data'):
st.dataframe(df)

If we return to the Streamlit app, we will see the expander window and view all of the stats within the CSV file.

Using Streamlit’s st.expander to view the raw data from the stats CSV file. Image by the author.

Creating Plotly Charts to View Medium Stats

Now that we have loaded all of our stats data successfully into Streamlit, we can now begin making some interactive charts to help us understand the trends over time. For this app, we will use Plotly Express to create our plots.

It is very simple to use and requires very little code to get a powerful and interactive plot.

The first plot we will create is a line plot of the number of followers per month.

fig_followers = px.line(df, x=df.date, y='followers', title='Followers')
st.plotly_chart(fig_followers, use_container_width=True)

When we go back to our Streamlit app, we now have our plot.

Basic Plotly Express plot in Streamlit. Image by the author.

We only have one data point in our file, so we have nothing to view within the line plot. In order to fix that, we need to add more data to our CSV file.

In the example below, I have added multiple months from August until the end of February.

medium_stats CSV file after adding multiple dates. Image by the author.

We can now go back to the Streamlit app and view the Plotly Express line plot.

Plotly Express line plot showing the change in Medium followers over time. Image by the author.

Within our dataset, we have two more stats we are tracking: the number of email subscribers and the number of referred members. We will display these data side by side in two bar charts.

To do this, we first need to create two columns using the st.columns() function, and then using px.barwe will set up the two bar charts.

To ensure that the charts fill each of the columns, we need to include the use_container_width parameter and set it to True.

plot_col1, plot_col2 = st.columns(2)

fig_subscribers = px.bar(df, x=df.date, y='email_subs', title='Email Subscribers')
plot_col1.plotly_chart(fig_subscribers, use_container_width=True)

fig_subscribers = px.bar(df, x=df.date, y='referred_members', title='Referred Members')
plot_col2.plotly_chart(fig_subscribers, use_container_width=True)

Our app now has two additional bar charts, and we have a good overview of how our Medium stats change over time.

Medium Stats Dashboard with charts to track follower count, email subscribers and referred members. Image by the author.

As we start to add more dates to our CSV file, we may want to consider introducing date filters or grouping data by years if we have been on the platform for a while.

Having interactive charts on our app is excellent, however, if we really want to find out the current month’s follower count or email subscriber count, then we have to look at the charts and try to work it out. We would have to do this for each chart.

An alternative and quicker way is to display the latest month’s stats as a prominent number on the dashboard using Streamlit’s metrics.

If we assume that the last row within the dataframe is the latest month, we can use the iloc function from pandas and extract the last values for each column.

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = df['followers'].iloc[-1]
latest_sub_count = df['email_subs'].iloc[-1]
latest_refs_count = df['referred_members'].iloc[-1]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

We could make this code more robust by making sure that the data is always sorted by date.

The next step is to get the latest stats by calling the get_latest_monthly_metrics() function and then passing those stats into Streamlit’s metric calls like so:

month, followers, subs, refs = get_latest_monthly_metrics(df)

st.write(f'### Medium Stats for {month}')

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers)
col2.metric('Email Subscribers', subs)
col3.metric('Referred Members', refs)

When we go back to the app, we can now see the latest stats prominently at the top of the app.

Medium Stats Dashboard after including Streamlit metrics. Image by the author.

One of the nice things about the Streamlit metric function is that we can include how much each metric has changed.

To prepare our data, we can create a function that will add a difference column to the dataframe for each of the stats like so:

def calculate_differences(df):
for x in ['followers', 'email_subs', 'referred_members']:
df[f'{x}_increase'] = df[x].diff()
return df

We then need to update the get_latest_monthly_metrics() function to account for the new columns. We will return each latest stat as a list with two values. One for the actual stat value and the other for the change or delta.

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = [df['followers'].iloc[-1],
df['followers_increase'].iloc[-1]]

latest_sub_count = [df['email_subs'].iloc[-1],
df['email_subs_increase'].iloc[-1]]

latest_refs_count = [df['referred_members'].iloc[-1],
df['referred_members_increase'].iloc[-1]]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

And finally, we update the call to the variables created by this function so it is referencing the correct value from each list:

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers[0], delta=round(followers[1]))
col2.metric('Email Subscribers', subs[0], delta=round(subs[1]))
col3.metric('Referred Members', refs[0], delta=round(refs[1]))

When we return to the Streamlit app, we will now have the deltas for each of the stats.

Medium Stats Dashboard with metrics correctly showing the differences between the past month and the current month. Image by the author.

And there we have it — a basic Streamlit Dashboard for visualising key statistics from our Medium account.

If you want to replicate the dashboard and play around with it, here is the full code for the app.

import streamlit as st
import pandas as pd
import plotly_express as px

st.set_page_config(layout='wide')

st.header('Medium Stats Dashboard')

#Main Functions
def update_stats_csv(date, followers, email_subs, ref_members):
with open('medium_stats.csv', 'a+') as f:
f.write(f'\n{date},{followers},{email_subs},{ref_members}')

def calculate_differences(df):
for x in ['followers', 'email_subs', 'referred_members']:
df[f'{x}_increase'] = df[x].diff()
return df

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = [df['followers'].iloc[-1],
df['followers_increase'].iloc[-1]]

latest_sub_count = [df['email_subs'].iloc[-1],
df['email_subs_increase'].iloc[-1]]

latest_refs_count = [df['referred_members'].iloc[-1],
df['referred_members_increase'].iloc[-1]]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

#Sidebar
with st.sidebar.form('Enter the latest stats from your Medium dashboard'):

date = st.date_input('Date')

follower_num = st.number_input('Followers', step=1)
email_subs = st.number_input('Email Subscribers', step=1)
ref_members = st.number_input('Referred Members', step=1)

submit_stats = st.form_submit_button('Write Stats to CSV')

if submit_stats:
update_stats_csv(date, follower_num, email_subs, ref_members)
st.info(f'Stats for {date} have been added to the csv file')

# Main page
df = pd.read_csv('medium_stats.csv')

with st.expander('View Raw Data'):
st.dataframe(df)

df = calculate_differences(df)

month, followers, subs, refs = get_latest_monthly_metrics(df)

st.write(f'### Medium Stats for {month}')

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers[0], delta=round(followers[1]))
col2.metric('Email Subscribers', subs[0], delta=round(subs[1]))
col3.metric('Referred Members', refs[0], delta=round(refs[1]))

fig_followers = px.line(df, x=df.date, y='followers', title='Followers')
st.plotly_chart(fig_followers, use_container_width=True)

plot_col1, plot_col2 = st.columns(2)

fig_subscribers = px.bar(df, x=df.date, y='email_subs', title='Email Subscribers')
plot_col1.plotly_chart(fig_subscribers, use_container_width=True)

fig_subscribers = px.bar(df, x=df.date, y='referred_members', title='Referred Members')
plot_col2.plotly_chart(fig_subscribers, use_container_width=True)

Within this article, we have seen how we can take our Medium stats and use them to create interactive charts directly within Streamlit. This is a basic app, but it could be made much nicer with styling and more functionality, such as including Medium Membership earnings.

It would be really nice to have the values updated automatically through the Medium API. However, I do not believe all statistics are available to access through the API.


Photo by Markus Winkler on Unsplash

I have been a writer on Medium for a while and recently started tracking my statistics using Excel. But, more recently, I have been thinking of building an app using Streamlit to provide a better experience. So I thought why not give it a go and write an article as I build it?

Within this article, we are going to go through the process of building a simple Streamlit dashboard and provide a way for the end user to enter their latest statistics using forms. By the end of the article, we will have a basic dashboard that we can build upon and make even more robust at a later date.

Streamlit dashboard for viewing and analysing Medium statistics. Image by the author

If you are just getting started with Streamlit, you may want to check out my articles below.

The first step is to import our key python libraries: streamlit, pandas and plotly_express. Following that, we need to configure the app to default to a wide display, and we will also add a title for our app.

import streamlit as st
import pandas as pd
import plotly_express as px

st.set_page_config(layout='wide')

st.header('Medium Stats Dashboard')

Next, we need to create a new CSV file within the same directory as our app and assign it the name medium_stats.

We will need to open the file and write in four columns. We could do this through code, but this is a quick and easy way to set the file up for now.

CSV starting file for the Medium Stats Dashboard within Streamlit. Image by the author.

The first piece of functionality we will set up is the ability for a user to enter their stats within the dashboard and update the CSV file.

def update_stats_csv(date, followers, email_subs, ref_members):
with open('medium_stats.csv', 'a+') as f:
f.write(f'\n{date},{followers},{email_subs},{ref_members}')

This piece of code will open the CSV file, and append a new row onto it, where a comma separates each stat.

Next, we need to create a simple form allowing the user to input the stats. This is achieved using the st.form functionality within Streamlit. We can then use the with statement and begin adding the number of entry boxes for each key stat that we want to track in our dashboard.

We will also add this to the sidebar, so it doesn’t clutter up the main display.

with st.sidebar.form('Enter the latest stats from your Medium dashboard'):

date = st.date_input('Date')

follower_num = st.number_input('Followers', step=1)
email_subs = st.number_input('Email Subscribers', step=1)
ref_members = st.number_input('Referred Members', step=1)

submit_stats = st.form_submit_button('Write Stats to CSV')

if submit_stats:
update_stats_csv(date, follower_num, email_subs, ref_members)
st.info(f'Stats for {date} have been added to the csv file')

When we re-run our Streamlit app, we should see the following form appear in the sidebar.

Streamlit Medium Stats Entry form on the sidebar. Image by the author.

When we select a date and add a few numbers, we can then click on the Write Stats to CSV button to commit the values to the CSV file. We will also be prompted by a callout stating that the stats have been added to the file.

Streamlit Medium Stats Entry form after adding statistics for a month. Image by the author.

If we return to the CSV file, we will see a new line within the file with the stats we just added.

CSV file after stats have been written from the Streamlit app. Image by the author.

Great! We have confirmed we can add stats directly to the CSV file. Now we can move on to loading the CSV file and begin creating charts for all months.

Within the main part of the Streamlit app, we are going to add an expander. When this is clicked on and expanded, we will be able to see the raw data from the CSV file within a pandas dataframe.

df = pd.read_csv('medium_stats.csv')

with st.expander('View Raw Data'):
st.dataframe(df)

If we return to the Streamlit app, we will see the expander window and view all of the stats within the CSV file.

Using Streamlit’s st.expander to view the raw data from the stats CSV file. Image by the author.

Creating Plotly Charts to View Medium Stats

Now that we have loaded all of our stats data successfully into Streamlit, we can now begin making some interactive charts to help us understand the trends over time. For this app, we will use Plotly Express to create our plots.

It is very simple to use and requires very little code to get a powerful and interactive plot.

The first plot we will create is a line plot of the number of followers per month.

fig_followers = px.line(df, x=df.date, y='followers', title='Followers')
st.plotly_chart(fig_followers, use_container_width=True)

When we go back to our Streamlit app, we now have our plot.

Basic Plotly Express plot in Streamlit. Image by the author.

We only have one data point in our file, so we have nothing to view within the line plot. In order to fix that, we need to add more data to our CSV file.

In the example below, I have added multiple months from August until the end of February.

medium_stats CSV file after adding multiple dates. Image by the author.

We can now go back to the Streamlit app and view the Plotly Express line plot.

Plotly Express line plot showing the change in Medium followers over time. Image by the author.

Within our dataset, we have two more stats we are tracking: the number of email subscribers and the number of referred members. We will display these data side by side in two bar charts.

To do this, we first need to create two columns using the st.columns() function, and then using px.barwe will set up the two bar charts.

To ensure that the charts fill each of the columns, we need to include the use_container_width parameter and set it to True.

plot_col1, plot_col2 = st.columns(2)

fig_subscribers = px.bar(df, x=df.date, y='email_subs', title='Email Subscribers')
plot_col1.plotly_chart(fig_subscribers, use_container_width=True)

fig_subscribers = px.bar(df, x=df.date, y='referred_members', title='Referred Members')
plot_col2.plotly_chart(fig_subscribers, use_container_width=True)

Our app now has two additional bar charts, and we have a good overview of how our Medium stats change over time.

Medium Stats Dashboard with charts to track follower count, email subscribers and referred members. Image by the author.

As we start to add more dates to our CSV file, we may want to consider introducing date filters or grouping data by years if we have been on the platform for a while.

Having interactive charts on our app is excellent, however, if we really want to find out the current month’s follower count or email subscriber count, then we have to look at the charts and try to work it out. We would have to do this for each chart.

An alternative and quicker way is to display the latest month’s stats as a prominent number on the dashboard using Streamlit’s metrics.

If we assume that the last row within the dataframe is the latest month, we can use the iloc function from pandas and extract the last values for each column.

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = df['followers'].iloc[-1]
latest_sub_count = df['email_subs'].iloc[-1]
latest_refs_count = df['referred_members'].iloc[-1]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

We could make this code more robust by making sure that the data is always sorted by date.

The next step is to get the latest stats by calling the get_latest_monthly_metrics() function and then passing those stats into Streamlit’s metric calls like so:

month, followers, subs, refs = get_latest_monthly_metrics(df)

st.write(f'### Medium Stats for {month}')

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers)
col2.metric('Email Subscribers', subs)
col3.metric('Referred Members', refs)

When we go back to the app, we can now see the latest stats prominently at the top of the app.

Medium Stats Dashboard after including Streamlit metrics. Image by the author.

One of the nice things about the Streamlit metric function is that we can include how much each metric has changed.

To prepare our data, we can create a function that will add a difference column to the dataframe for each of the stats like so:

def calculate_differences(df):
for x in ['followers', 'email_subs', 'referred_members']:
df[f'{x}_increase'] = df[x].diff()
return df

We then need to update the get_latest_monthly_metrics() function to account for the new columns. We will return each latest stat as a list with two values. One for the actual stat value and the other for the change or delta.

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = [df['followers'].iloc[-1],
df['followers_increase'].iloc[-1]]

latest_sub_count = [df['email_subs'].iloc[-1],
df['email_subs_increase'].iloc[-1]]

latest_refs_count = [df['referred_members'].iloc[-1],
df['referred_members_increase'].iloc[-1]]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

And finally, we update the call to the variables created by this function so it is referencing the correct value from each list:

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers[0], delta=round(followers[1]))
col2.metric('Email Subscribers', subs[0], delta=round(subs[1]))
col3.metric('Referred Members', refs[0], delta=round(refs[1]))

When we return to the Streamlit app, we will now have the deltas for each of the stats.

Medium Stats Dashboard with metrics correctly showing the differences between the past month and the current month. Image by the author.

And there we have it — a basic Streamlit Dashboard for visualising key statistics from our Medium account.

If you want to replicate the dashboard and play around with it, here is the full code for the app.

import streamlit as st
import pandas as pd
import plotly_express as px

st.set_page_config(layout='wide')

st.header('Medium Stats Dashboard')

#Main Functions
def update_stats_csv(date, followers, email_subs, ref_members):
with open('medium_stats.csv', 'a+') as f:
f.write(f'\n{date},{followers},{email_subs},{ref_members}')

def calculate_differences(df):
for x in ['followers', 'email_subs', 'referred_members']:
df[f'{x}_increase'] = df[x].diff()
return df

def get_latest_monthly_metrics(df):
# Assumes the last row is the latest entry

df['date'] = pd.to_datetime(df['date'])
df['month'] = df['date'].dt.month_name()
latest_month = df['month'].iloc[-1]
latest_follower_count = [df['followers'].iloc[-1],
df['followers_increase'].iloc[-1]]

latest_sub_count = [df['email_subs'].iloc[-1],
df['email_subs_increase'].iloc[-1]]

latest_refs_count = [df['referred_members'].iloc[-1],
df['referred_members_increase'].iloc[-1]]

return latest_month, latest_follower_count, latest_sub_count, latest_refs_count

#Sidebar
with st.sidebar.form('Enter the latest stats from your Medium dashboard'):

date = st.date_input('Date')

follower_num = st.number_input('Followers', step=1)
email_subs = st.number_input('Email Subscribers', step=1)
ref_members = st.number_input('Referred Members', step=1)

submit_stats = st.form_submit_button('Write Stats to CSV')

if submit_stats:
update_stats_csv(date, follower_num, email_subs, ref_members)
st.info(f'Stats for {date} have been added to the csv file')

# Main page
df = pd.read_csv('medium_stats.csv')

with st.expander('View Raw Data'):
st.dataframe(df)

df = calculate_differences(df)

month, followers, subs, refs = get_latest_monthly_metrics(df)

st.write(f'### Medium Stats for {month}')

col1, col2, col3 = st.columns(3)
col1.metric('Followers', followers[0], delta=round(followers[1]))
col2.metric('Email Subscribers', subs[0], delta=round(subs[1]))
col3.metric('Referred Members', refs[0], delta=round(refs[1]))

fig_followers = px.line(df, x=df.date, y='followers', title='Followers')
st.plotly_chart(fig_followers, use_container_width=True)

plot_col1, plot_col2 = st.columns(2)

fig_subscribers = px.bar(df, x=df.date, y='email_subs', title='Email Subscribers')
plot_col1.plotly_chart(fig_subscribers, use_container_width=True)

fig_subscribers = px.bar(df, x=df.date, y='referred_members', title='Referred Members')
plot_col2.plotly_chart(fig_subscribers, use_container_width=True)

Within this article, we have seen how we can take our Medium stats and use them to create interactive charts directly within Streamlit. This is a basic app, but it could be made much nicer with styling and more functionality, such as including Medium Membership earnings.

It would be really nice to have the values updated automatically through the Medium API. However, I do not believe all statistics are available to access through the API.

FOLLOW US ON GOOGLE NEWS

Read original article here

Denial of responsibility! Techno Blender is an automatic aggregator of the all world’s media. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials, please contact us by email – [email protected]. The content will be deleted within 24 hours.

Leave a comment