Sankey Diagram

University Student Flow

Student progression through academic years showing graduation, transfers, and dropout rates.

Output
University Student Flow
Python
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.path import Path

def draw_flow(ax, x0, y0, x1, y1, w0, w1, color, alpha=0.6):
    cx = (x0 + x1) / 2
    verts = [
        (x0, y0 + w0/2), (cx, y0 + w0/2), (cx, y1 + w1/2), (x1, y1 + w1/2),
        (x1, y1 - w1/2), (cx, y1 - w1/2), (cx, y0 - w0/2), (x0, y0 - w0/2),
        (x0, y0 + w0/2)
    ]
    codes = [Path.MOVETO] + [Path.CURVE4]*3 + [Path.LINETO] + [Path.CURVE4]*3 + [Path.CLOSEPOLY]
    ax.add_patch(mpatches.PathPatch(Path(verts, codes), fc=color, alpha=alpha, ec='none'))

def draw_node(ax, x, y, w, h, color, label):
    ax.add_patch(mpatches.FancyBboxPatch((x-w/2, y-h/2), w, h, boxstyle="round,pad=0.02",
                                          fc=color, ec='#374151', lw=1.5))
    ax.text(x, y, label, ha='center', va='center', fontsize=8, color='white', fontweight='bold')

fig, ax = plt.subplots(figsize=(14, 8), facecolor='#ffffff')
ax.set_facecolor('#ffffff')

s = 0.005

# Freshman to Sophomore
draw_flow(ax, 0.5, 5, 2.5, 5, 1000*s, 1000*s, '#4927F5', 0.6)

# Soph split
draw_flow(ax, 3.5, 5.5, 5.5, 7.5, 80*s, 80*s, '#C82909', 0.6)  # Dropout
draw_flow(ax, 3.5, 4.5, 5.5, 4, 920*s, 920*s, '#27D3F5', 0.6)  # Continue

# Junior to Senior
draw_flow(ax, 6.5, 4.5, 8.5, 6.5, 50*s, 50*s, '#F5B027', 0.6)  # Transfer
draw_flow(ax, 6.5, 3.5, 8.5, 3, 870*s, 870*s, '#6CF527', 0.6)  # Graduate

# Nodes
draw_node(ax, 0, 5, 0.6, 1000*s*1.2, '#4927F5', 'Freshman\n1000')
draw_node(ax, 3, 5, 0.6, 1000*s*1.2, '#276CF5', 'Sophomore\n1000')
draw_node(ax, 6, 7.5, 0.6, 80*s*3, '#C82909', 'Dropout\n80')
draw_node(ax, 6, 4, 0.6, 920*s*1.2, '#27D3F5', 'Junior\n920')
draw_node(ax, 9, 6.5, 0.6, 50*s*4, '#F5B027', 'Transfer\n50')
draw_node(ax, 9, 3, 0.6, 870*s*1.2, '#6CF527', 'Graduate\n870')

ax.set_title('University Student Progression Flow', fontsize=16, color='#1f2937', fontweight='bold', pad=20)
ax.set_xlim(-1, 10)
ax.set_ylim(0, 9)
ax.axis('off')
plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Part-to-Whole

Did this help you?

Support PyLucid to keep it free & growing

Support