Skip to content
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# Read in the data for subscribers
subscribers = pd.read_csv('MEDIUM_rblancha-subscriber-stats.csv', parse_dates=['period_start'], skiprows=0)

# Read in the data for Article Views and Reads
medium_stats = pd.read_csv('medium_stats.csv', parse_dates=['Date'], skiprows=1)
medium_stats.head(7)
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# Read in the data
medium_stats = pd.read_csv('medium_stats.csv', parse_dates=['Date'], skiprows=1)

# Ensure the 'date' column is in datetime format
medium_stats['Date'] = pd.to_datetime(medium_stats['Date'])

# Create columns for week number and day of the week
medium_stats['week'] = medium_stats['Date'].dt.isocalendar().week
medium_stats['day'] = medium_stats['Date'].dt.dayofweek

# Create a DataFrame to ensure all days and weeks are represented
all_weeks = range(1, 53)  # Weeks 1 to 52
all_days = range(0, 7)    # Days 0 (Monday) to 6 (Sunday)
full_index = pd.MultiIndex.from_product([all_days, all_weeks], names=['day', 'week'])

# Highlight publications with box in the heatmap
highlight_day = 6  # Saturday
highlight_week = 1  # Week 1
highlight2_day = 4  # Thursday
highlight2_week = 5  # Week 5
highlight3_day = 3  # Wednesday
highlight3_week = 6  # Week 1
highlight4_day = 3  # Wednesday
highlight4_week = 7  # Week 1
highlight5_day = 6  # Saturday
highlight5_week = 7  # Week 1

# Sum XP earned for each day and week, reindex to fill missing values with 0
heatmap_data = medium_stats.pivot_table(index='day', columns='week', values='Views', aggfunc='sum', fill_value=0)
heatmap_data = heatmap_data.reindex(index=all_days, columns=all_weeks, fill_value=0)

# Create the heatmap
plt.figure(figsize=(20, 4))
ax = sns.heatmap(heatmap_data, cmap='Greens', linewidths=.5, linecolor='gray', cbar_kws={'label': 'Views'})

# Highlight the specific box
ax.add_patch(plt.Rectangle((highlight_week-1, highlight_day-1), 1, 1, fill=False, edgecolor='red', lw=3))
ax.add_patch(plt.Rectangle((highlight2_week-1, highlight2_day-1), 1, 1, fill=False, edgecolor='red', lw=3))
ax.add_patch(plt.Rectangle((highlight3_week-1, highlight3_day-1), 1, 1, fill=False, edgecolor='blue', lw=3))
ax.add_patch(plt.Rectangle((highlight4_week-1, highlight4_day-1), 1, 1, fill=False, edgecolor='blue', lw=3))
ax.add_patch(plt.Rectangle((highlight5_week-1, highlight5_day-1), 1, 1, fill=False, edgecolor='yellow', lw=3))

# Set the labels
plt.title('Views All Articles Heatmap', loc='center')
plt.xlabel('Week of the Year')
plt.ylabel('Day of the Week')
plt.yticks(ticks=np.arange(7) + 0.5, labels=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], rotation=0)

# Create a legend for the highlighted boxes
import matplotlib.patches as mpatches
red_patch = mpatches.Patch(color='red', label='Goals')
blue_patch = mpatches.Patch(color='blue', label='Geology')
yellow_patch = mpatches.Patch(color='yellow', label='AI')
plt.legend(handles=[red_patch, blue_patch, yellow_patch], loc='upper right')

# Display the heatmap
plt.show()
plt.savefig("heatmap_plot.png")
plt.close()

Explore subscribers and Views

# Set the aesthetic style of the plots
sns.set_style("whitegrid")

# Filter data for the year 2024
medium_stats_2024 = medium_stats[medium_stats['Date'].dt.year == 2024]
subscribers_2024 = subscribers[subscribers['period_start'].dt.year == 2024]

# Aggregate data to monthly sums
medium_stats_2024['month'] = medium_stats_2024['Date'].dt.to_period('M')
subscribers_2024['month'] = subscribers_2024['period_start'].dt.to_period('M')

monthly_views = medium_stats_2024.groupby('month')['Views'].sum().reset_index()
monthly_followers = subscribers_2024.groupby('month')['followers_total'].sum().reset_index()

# Convert 'month' back to datetime for plotting
monthly_views['month'] = monthly_views['month'].dt.to_timestamp()
monthly_followers['month'] = monthly_followers['month'].dt.to_timestamp()

# Create a figure and axis
fig, ax1 = plt.subplots(figsize=(14, 7))

# Plot the total views data with a fancy style
sns.lineplot(data=monthly_views, x='month', y='Views', ax=ax1, marker='o', color='b', linewidth=2.5, markersize=8, label='Total Views')

# Create a second y-axis to plot the follower count
ax2 = ax1.twinx()
sns.lineplot(data=monthly_followers, x='month', y='followers_total', ax=ax2, marker='s', color='g', linewidth=2.5, markersize=8, label='Total Followers')

# Set the title and labels with a fancy font
ax1.set_title('Total Views and Follower Count Over Time (2024)', fontsize=20, fontweight='bold', color='darkblue')
ax1.set_xlabel('Date', fontsize=16, fontweight='bold', color='darkblue')
ax1.set_ylabel('Views', fontsize=16, fontweight='bold', color='darkblue')
ax2.set_ylabel('Followers', fontsize=16, fontweight='bold', color='darkgreen')

# Set y-axis limit for Total Views
ax1.set_ylim(0, 160)

# Set y-axis limit for followers
ax2.set_ylim(0, 80)

# Rotate x-axis labels for better readability
plt.xticks(rotation=45, fontsize=12, fontweight='bold', color='darkblue')
ax1.tick_params(axis='y', labelcolor='darkblue')
ax2.tick_params(axis='y', labelcolor='darkgreen')

# Add gridlines for better readability
ax1.grid(True, which='both', linestyle='--', linewidth=0.5)

# Add legends
ax1.legend(loc='upper left', fontsize=12)
ax2.legend(loc='upper right', fontsize=12)

# Show the plot
plt.show()