Lesson 59 · Social Media Content Analytics
Best Practices for Visualizing Engagement Data
In this lesson, we will learn how to visualize and analyze engagement metrics from real-world social media datasets. Understanding engagement is important…
- CourseSocial Media Content Analytics
- Lesson59 of 41
- Video29 min
- FormatJupyter notebook · 18 code cells
What you'll learn
- Core Social Media Analytics Concepts
- Example 1: Calculate Engagement Rate for Each Post
- Example 2: Visualize Engagement Rates by Platform
- Example 3: Identify Top-Performing Posts
- Example 4: Engagement Trends Over Time (Beginner)
- Example 5: Audience Behavior by Post Time
- Example 6: Heatmap of Engagement by Platform and Hour (Intermediate)
- Example 7: Compare Engagement Metrics with PairPlot (Intermediate)
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbBest Practices for Visualizing Engagement Data#
- In this lesson, we will learn how to visualize and analyze engagement metrics from real-world social media datasets.
- Understanding engagement is important for content creators and businesses to improve content and connect with the audience.
- You will learn to extract actionable insights for content strategy using best practices in data visualization.
- We will cover engagement rate, trends, benchmarking, error detection, and create practical, clear social media reports.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
Core Social Media Analytics Concepts#
- Social media datasets often represent content items like videos or posts, each with engagement metrics.
- Key metrics include: views, likes, comments, shares, click-through rate (CTR), watch time, and engagement rate.
- Engagement rate is usually (likes + comments + shares) divided by views or followers, showing relative interaction.
- Beginners may confuse total counts for performance without adjusting for audience size.
- Ratios like CTR and engagement rate help standardize comparisons across content or creators.
- Consistent metric definitions and grouping logic are critical for accurate analysis.
# Load Social Media Content Dataset for Engagement Examples
np.random.seed(42)
n_posts = 500
views = np.random.randint(100, 100000, n_posts)
df = pd.DataFrame({
'post_id': range(1, n_posts+1),
'platform': np.random.choice(['YouTube','Instagram','TikTok'], n_posts),
'date': pd.date_range('2023-01-01', periods=n_posts, freq='6h'),
'views': views,
'likes': (views * np.random.uniform(0.02, 0.15, n_posts)).astype(int),
'comments': (views * np.random.uniform(0.001, 0.05, n_posts)).astype(int),
'shares': (views * np.random.uniform(0.001, 0.03, n_posts)).astype(int)
})
print(df.head(3))
Example 1: Calculate Engagement Rate for Each Post#
- Engagement rate is a standard way to compare how well content performs relative to its reach.
- For posts, a basic engagement rate formula is:
- (likes + comments + shares) / views * 100
- This shows the percentage of viewers who interacted with a post in any way.
df['engagement_rate'] = ((df['likes'] + df['comments'] + df['shares']) / df['views']) * 100
df['engagement_rate'] = df['engagement_rate'].round(2)
print(df[['post_id', 'platform', 'views', 'likes', 'comments', 'shares', 'engagement_rate']].head(5))
Example 2: Visualize Engagement Rates by Platform#
- A common mistake is to compare engagement rates across platforms using absolute counts.
- Visualization helps highlight differences in audience behavior between YouTube, Instagram, and TikTok.
plt.figure(figsize=(8,5))
sns.boxplot(x='platform', y='engagement_rate', data=df, palette='Set2')
plt.title('Engagement Rate Distribution by Platform')
plt.ylabel('Engagement Rate (%)')
plt.xlabel('Platform')
plt.show()
Example 3: Identify Top-Performing Posts#
- To find what works best, we can look at the top 10 posts by engagement rate.
- Visualizing these can reveal what type of content drives high interaction.
top_posts = df.sort_values('engagement_rate', ascending=False).head(10)
plt.figure(figsize=(10,6))
sns.barplot(x='engagement_rate', y='post_id', data=top_posts, hue='platform', dodge=False)
plt.title('Top 10 Posts by Engagement Rate')
plt.ylabel('Post ID')
plt.xlabel('Engagement Rate (%)')
plt.legend(title='Platform')
plt.show()
Example 4: Engagement Trends Over Time (Beginner)#
- Tracking engagement metrics across time reveals trends, cycles, or spikes.
- Line plots quickly show changes and help spot patterns like growth or sudden viral events.
daily = df.set_index('date').resample('D').agg({'views':'sum','likes':'sum','comments':'sum','shares':'sum'})
daily['engagement_rate'] = ((daily['likes'] + daily['comments'] + daily['shares']) / daily['views'] * 100).round(2)
plt.figure(figsize=(12,5))
plt.plot(daily.index, daily['engagement_rate'], marker='o')
plt.title('Engagement Rate Over Time')
plt.ylabel('Engagement Rate (%)')
plt.xlabel('Date')
plt.grid(True, alpha=0.2)
plt.show()
Example 5: Audience Behavior by Post Time#
- The time a post is published can impact engagement.
- Let us see if certain hours of day have higher engagement rates.
df['hour'] = df['date'].dt.hour
hourly = df.groupby('hour')['engagement_rate'].mean()
plt.figure(figsize=(10,5))
sns.lineplot(x=hourly.index, y=hourly.values, marker='o')
plt.title('Average Engagement Rate by Posting Hour')
plt.xlabel('Hour of Day')
plt.ylabel('Avg Engagement Rate (%)')
plt.xticks(np.arange(0,24,2))
plt.show()
Example 6: Heatmap of Engagement by Platform and Hour (Intermediate)#
- Heatmaps help visualize patterns along two categorical axes, like platform and posting hour.
- This can reveal platform-specific timing strategies.
pivot = df.pivot_table(values='engagement_rate', index='platform', columns='hour', aggfunc='mean')
plt.figure(figsize=(12,5))
sns.heatmap(pivot, annot=True, fmt='.1f', cmap='coolwarm', cbar_kws={'label': 'Engagement Rate (%)'})
plt.title('Engagement Rate Heatmap by Platform and Posting Hour')
plt.xlabel('Hour of Day')
plt.ylabel('Platform')
plt.show()
Example 7: Compare Engagement Metrics with PairPlot (Intermediate)#
- Sometimes, exploring relationships among metrics helps explain why some posts succeed.
- Pair plots can reveal connections between likes, comments, shares, and engagement rate.
sns.pairplot(df, vars=['views','likes','comments','shares','engagement_rate'], hue='platform', diag_kind='kde')
plt.suptitle('Pairwise Relationships Among Engagement Metrics', y=1.02)
plt.show()
Example 8: Platform Benchmarking (Intermediate)#
- Benchmarking compares your posts to a platform's typical performance.
- Let us compute and visualize the median engagement rate by platform for a fairer comparison.
bench = df.groupby('platform')['engagement_rate'].median().reset_index()
plt.figure(figsize=(7,4))
sns.barplot(x='platform', y='engagement_rate', data=bench, palette='pastel')
plt.title('Median Engagement Rate Benchmark by Platform')
plt.ylabel('Median Engagement Rate (%)')
plt.xlabel('Platform')
plt.show()
Example 9: Error - Missing Engagement Values#
- Real datasets sometimes have missing likes, comments, or shares.
- Let us simulate this problem and show how to handle it in a visual context.
df_missing = df.copy()
rand_idx = np.random.choice(df_missing.index, size=20, replace=False)
df_missing.loc[rand_idx, 'likes'] = np.nan
df_missing['engagement_rate'] = ((df_missing['likes'].fillna(0) + df_missing['comments'] + df_missing['shares']) / df_missing['views']) * 100
plt.figure(figsize=(8,5))
sns.histplot(df['engagement_rate'], color='blue', label='Original', kde=True, stat='density')
sns.histplot(df_missing['engagement_rate'], color='red', label='Missing likes', kde=True, stat='density', alpha=0.5)
plt.legend()
plt.title('Effect of Missing Values on Engagement Rate Distribution')
plt.xlabel('Engagement Rate (%)')
plt.show()
Example 10: Error - Incorrect Aggregation of Engagement Data#
- Beginners sometimes sum likes, comments, and shares across all posts and divide by total views.
- This can mislead if platforms or time periods behave differently.
- Let us compare the wrong method to the recommended one.
# Incorrect: aggregate then calculate
incorrect = ((df['likes'].sum() + df['comments'].sum() + df['shares'].sum()) / df['views'].sum()) * 100
# Recommended: average post engagement rate
correct = df['engagement_rate'].mean()
print(f"Incorrect total-based engagement rate: {incorrect:.2f}%")
print(f"Correct average post engagement rate: {correct:.2f}%")
Example 11: Error - Misinterpreting CTR or Engagement Rate Ratios#
- CTR and engagement rates should be compared only among similar content or periods.
- Mixing unrelated categories or inconsistent definitions can produce misleading results.
# Suppose we mix platforms: TikTok and YouTube have very different engagement patterns.
df_grouped = df.groupby('platform')['engagement_rate'].mean()
plt.figure(figsize=(7,4))
df_grouped.plot(kind='bar', color=['red','blue','green'])
plt.title('Mean Engagement Rate (Be Cautious Mixing Platforms!)')
plt.ylabel('Engagement Rate (%)')
plt.xlabel('Platform')
plt.show()
Example 12: Error - Incorrect Grouping by Content Categories#
- Grouping by the wrong content attribute can mix up insights.
- Let us see what happens if we group by post ID instead of platform, and then correct it.
# Wrong: aggregates each post (no aggregation)
by_post = df.groupby('post_id')['engagement_rate'].mean()
print('Median engagement rate per post:', by_post.median())
# Correct: group by platform
by_platform = df.groupby('platform')['engagement_rate'].median()
print('Median engagement rate per platform:')
print(by_platform)
Best Practices: Visualization Patterns for Social Media Engagement#
- Use ratio-based metrics (engagement rate, CTR) to compare fairly across posts, platforms, and creators.
- Always handle missing or zero values explicitly in calculations and plots.
- Benchmark performance: compare results against platform medians or quartiles, not just absolute numbers.
- Segment data by relevant categories like platform, time, or content type for clearer insights.
- Use clear axis labels, legends, and chart titles to communicate findings.
- Avoid visual clutter. Show reference lines or highlights for goals or benchmarks.
- Visualize trends over time, optimal posting times, and outlier performances.
Example 13: Growth Trend Analysis (Advanced)#
- To understand long-term content success, analyze growth in engagement over weeks or months.
- Visualize rolling averages to smooth day-to-day noise and reveal real trends.
daily['rolling_engagement'] = daily['engagement_rate'].rolling(14, min_periods=1).mean()
plt.figure(figsize=(12,5))
plt.plot(daily.index, daily['engagement_rate'], alpha=0.4, label='Daily Engagement Rate')
plt.plot(daily.index, daily['rolling_engagement'], color='red', label='14-day Rolling Avg')
plt.title('Long-Term Engagement Trend (14-day Rolling Average)')
plt.xlabel('Date')
plt.ylabel('Engagement Rate (%)')
plt.legend()
plt.show()
Example 14: Content Optimization - Detect Viral Posts (Advanced)#
- Posts far above the engagement benchmark are candidates for deeper analysis.
- Let us flag and review such viral posts.
benchmark = df['engagement_rate'].median()
viral = df[df['engagement_rate'] > benchmark * 2]
print(f"Engagement median: {benchmark:.2f}%, Viral threshold: {benchmark*2:.2f}%")
print(f"Found {len(viral)} viral posts out of {len(df)}.")
print(viral[['post_id','platform','engagement_rate']].head())
Example 15: Consistent Visualization for Content Strategy#
- Always use the same metric definitions and chart types across reports.
- This allows teams and stakeholders to compare results over time and make informed decisions.
# Here is a reusable function for visualizing engagement rate across categories
def plot_engagement_rate_by_category(df, category):
means = df.groupby(category)['engagement_rate'].mean()
plt.figure(figsize=(7,4))
sns.barplot(x=means.index, y=means.values, palette='muted')
plt.title(f'Average Engagement Rate by {category.capitalize()}')
plt.ylabel('Avg Engagement Rate (%)')
plt.xlabel(category.capitalize())
plt.show()
plot_engagement_rate_by_category(df, 'platform')
Example 16: End-to-End Strategy Recommendation (Mini Project)#
- Scenario: You are consulting for a brand wanting to boost Instagram engagement.
- Use all the steps above to analyze where, when, and how to post for maximum effect.
insta = df[df['platform']=='Instagram']
best_hour = insta.groupby('hour')['engagement_rate'].mean().idxmax()
best_posts = insta.sort_values('engagement_rate', ascending=False).head(5)
print(f"Best posting hour on Instagram: {best_hour}:00")
print("Top 5 engaging Instagram posts:")
print(best_posts[['post_id','date','views','likes','engagement_rate']])
YouTube Call-to-Action Example#
- For more tutorials, subscribe to the data science YouTube channel and leave a comment with your most valuable visualization insight!
Practice: Build Your Own Social Media Engagement Dashboard#
- Try combining line charts, barplots, and heatmaps with customized colors and labels.
- Summarize your findings with clear recommendations for content strategy.
- Share your best practice visualizations with a study group or in a classroom demo.
- Thank you for learning! For more, visit our YouTube series.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



