Raincloud Plot
REST API Endpoint Latency Raincloud
Distribution of API response times across different endpoint types.
Output
Python
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
np.random.seed(1010)
# Response time in milliseconds
get_simple = np.random.lognormal(2.5, 0.4, 150)
get_complex = np.random.lognormal(3.5, 0.5, 140)
post_create = np.random.lognormal(3.2, 0.45, 130)
post_update = np.random.lognormal(3.0, 0.4, 135)
get_simple = np.clip(get_simple, 5, 50)
get_complex = np.clip(get_complex, 15, 150)
post_create = np.clip(post_create, 10, 100)
post_update = np.clip(post_update, 8, 80)
F_stat, p_value = stats.f_oneway(get_simple, get_complex, post_create, post_update)
BG_COLOR = "#0a0a0f"
COLOR_SCALE = ["#6CF527", "#F5276C", "#27D3F5", "#F5B027"]
fig, ax = plt.subplots(figsize=(10, 6), facecolor=BG_COLOR)
ax.set_facecolor(BG_COLOR)
y_data = [get_simple, get_complex, post_create, post_update]
positions = [0, 1, 2, 3]
labels = ["GET /simple", "GET /complex", "POST /create", "PUT /update"]
for h in [25, 50, 100]:
ax.axhline(h, color='#333333', ls=(0, (5, 5)), alpha=0.5, zorder=0)
# SLA thresholds
ax.axhline(y=50, color='#22c55e', ls='--', alpha=0.7, lw=2)
ax.axhline(y=100, color='#ef4444', ls='--', alpha=0.7, lw=2)
ax.text(3.55, 50, "P95 SLA", color='#22c55e', fontsize=9, va='center')
ax.text(3.55, 100, "P99 SLA", color='#ef4444', fontsize=9, va='center')
violins = ax.violinplot(y_data, positions=positions, widths=0.5,
bw_method="silverman", showmeans=False,
showmedians=False, showextrema=False)
for pc in violins["bodies"]:
pc.set_facecolor("none")
pc.set_edgecolor("white")
pc.set_linewidth(1.8)
bp = ax.boxplot(y_data, positions=positions, showfliers=False, showcaps=False,
medianprops=dict(linewidth=3, color='#F5D327'),
whiskerprops=dict(linewidth=2, color='#555555'),
boxprops=dict(linewidth=2, color='#555555'))
for i, (y, color) in enumerate(zip(y_data, COLOR_SCALE)):
x_jitter = np.array([i] * len(y)) + stats.t(df=6, scale=0.04).rvs(len(y))
ax.scatter(x_jitter, y, s=50, color=color, alpha=0.5, zorder=2)
means = [y.mean() for y in y_data]
for i, (mean, color) in enumerate(zip(means, COLOR_SCALE)):
ax.scatter(i, mean, s=180, color='#C82909', zorder=5, edgecolors='white', linewidths=2)
ax.plot([i, i + 0.28], [mean, mean], ls="dashdot", color="white", zorder=3, lw=1.5)
ax.text(i + 0.3, mean, f"μ={mean:.0f}ms", fontsize=10, va="center", color='white',
bbox=dict(facecolor=BG_COLOR, edgecolor=color, boxstyle="round,pad=0.15", lw=2))
# P99 percentiles
p99s = [np.percentile(y, 99) for y in y_data]
for i, (p99, color) in enumerate(zip(p99s, COLOR_SCALE)):
ax.text(i, -12, f"P99: {p99:.0f}ms", ha='center', fontsize=9, color=color)
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
ax.spines["left"].set_color('#444444')
ax.spines["bottom"].set_color('#444444')
ax.tick_params(colors='#888888', length=0)
xlabels = [f"{l}\n(n={len(y_data[i])})" for i, l in enumerate(labels)]
ax.set_xticks(positions)
ax.set_xticklabels(xlabels, size=10, color='white')
ax.set_ylabel("Response Time (ms)", size=14, color='white', fontweight='bold')
ax.set_title("REST API Endpoint Latency Analysis", fontsize=14, color="white", fontweight="bold", pad=20)
ax.set_ylim(-20, 160)
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Statistical
More Raincloud Plot examples
☕