Hexbin Plot

Social Media Hexbin Analysis

Post reach vs engagement rate analysis for content optimization.

Output
Social Media Hexbin Analysis
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

# Social media data
np.random.seed(42)
n_posts = 12000

reach = np.random.lognormal(8, 1.2, n_posts)
reach = np.clip(reach, 100, 500000) / 1000

base_engagement = 8 - 1.5 * np.log10(reach + 1)
engagement = base_engagement + np.random.normal(0, 1.5, n_posts)
engagement = np.clip(engagement, 0.5, 15)

# Modern purple theme on white
fig, ax = plt.subplots(figsize=(10, 8), facecolor='#ffffff')
ax.set_facecolor('#faf5ff')

colors = ['#faf5ff', '#f3e8ff', '#e9d5ff', '#d8b4fe', '#c084fc', 
          '#a855f7', '#9333ea', '#7e22ce', '#6b21a8', '#581c87']
cmap = LinearSegmentedColormap.from_list('purple', colors, N=256)

hb = ax.hexbin(reach, engagement, gridsize=35, cmap=cmap, mincnt=1,
               edgecolors='white', linewidths=0.3)

ax.axhline(y=10, color='#9333ea', linestyle='--', alpha=0.7, linewidth=2, label='Viral Threshold')

from matplotlib.patches import Ellipse
sweet_spot = Ellipse((20, 6), 30, 4, fill=False, edgecolor='#22c55e', 
                      linewidth=2, linestyle='-', alpha=0.8)
ax.add_patch(sweet_spot)
ax.text(20, 6, 'Sweet Spot', fontsize=10, color='#22c55e', ha='center', fontweight='600')

cbar = plt.colorbar(hb, ax=ax, pad=0.02, shrink=0.85)
cbar.set_label('Post Count', fontsize=11, color='#581c87', labelpad=10)
cbar.ax.yaxis.set_tick_params(color='#7e22ce')
cbar.outline.set_edgecolor('#e9d5ff')
plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='#7e22ce', fontsize=9)

ax.set_xlabel('Reach (thousands)', fontsize=12, color='#581c87', fontweight='600', labelpad=12)
ax.set_ylabel('Engagement Rate (%)', fontsize=12, color='#581c87', fontweight='600', labelpad=12)
ax.set_title('Social Media Engagement Analysis', fontsize=16, color='#3b0764', 
             fontweight='700', pad=20)

ax.tick_params(colors='#7e22ce', labelsize=10, length=0)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_color('#e9d5ff')
ax.spines['bottom'].set_color('#e9d5ff')

ax.legend(loc='upper right', fontsize=10, frameon=True, facecolor='white', 
          edgecolor='#e9d5ff', labelcolor='#581c87')
ax.grid(True, alpha=0.3, color='#e9d5ff', linestyle='-', linewidth=0.5)
ax.set_axisbelow(True)

plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Pairwise Data

Did this help you?

Support PyLucid to keep it free & growing

Support