Gauge Chart

Security Threat Level

Cybersecurity risk assessment with dark red warning theme

Output
Security Threat Level
Python
import matplotlib.pyplot as plt
from matplotlib.patches import Wedge, Circle, Polygon
import numpy as np

threat = 23
bg_color = '#0a0a0f'
track_color = '#1a1a2e'

if threat < 30:
    arc_color = '#27F5B0'
    status = 'LOW'
elif threat < 60:
    arc_color = '#F5B027'
    status = 'MEDIUM'
else:
    arc_color = '#C82909'
    status = 'HIGH'

text_color = '#ffffff'
dim_color = '#6b7280'

start_angle, end_angle = -30, 210
sweep = end_angle - start_angle

fig, ax = plt.subplots(figsize=(10, 8), facecolor=bg_color)
ax.set_facecolor(bg_color)
ax.set_xlim(-1.4, 1.4)
ax.set_ylim(-0.5, 1.4)
ax.set_aspect('equal')
ax.axis('off')

zones = [(0, 30, '#27F5B0'), (30, 60, '#F5B027'), (60, 100, '#C82909')]
for z_start, z_end, z_color in zones:
    ax.add_patch(Wedge((0, 0), 1.0, end_angle - (z_end/100)*sweep, end_angle - (z_start/100)*sweep, width=0.15, facecolor=z_color, edgecolor='none', alpha=0.15))

value_pct = threat / 100
value_angle = start_angle + (1 - value_pct) * sweep
for r_off, w_off, alpha in [(0.05, 0.06, 0.1), (0.03, 0.04, 0.2), (0.015, 0.02, 0.4), (0, 0, 0.95)]:
    ax.add_patch(Wedge((0, 0), 1.0 + r_off, value_angle, end_angle, width=0.15 + w_off, facecolor=arc_color, edgecolor='none', alpha=alpha))

for i in range(11):
    pct = i / 10
    angle = np.radians(end_angle - pct * sweep)
    r1, r2 = (0.87, 0.80) if i % 5 == 0 else (0.87, 0.83)
    ax.plot([r1*np.cos(angle), r2*np.cos(angle)], [r1*np.sin(angle), r2*np.sin(angle)], color='#3a3a4a', linewidth=2 if i%5==0 else 1)
    if i % 5 == 0:
        ax.text(0.72*np.cos(angle), 0.72*np.sin(angle), f'{int(pct*100)}', fontsize=11, color=dim_color, ha='center', va='center')

needle_angle = np.radians(end_angle - value_pct * sweep)
nx, ny = 0.62 * np.cos(needle_angle), 0.62 * np.sin(needle_angle)
perp = needle_angle + np.pi/2
bx1, by1 = 0.035 * np.cos(perp), 0.035 * np.sin(perp)

for scale, alpha in [(1.6, 0.1), (1.3, 0.2)]:
    ax.add_patch(Polygon([(nx*scale, ny*scale), (bx1*2, by1*2), (-bx1*2, -by1*2)], facecolor=arc_color, edgecolor='none', alpha=alpha))
ax.add_patch(Polygon([(nx, ny), (bx1, by1), (-bx1, -by1)], facecolor='#ffffff', edgecolor='none'))

for r, c, a in [(0.11, arc_color, 0.3), (0.09, arc_color, 0.5), (0.07, bg_color, 1), (0.05, arc_color, 0.9)]:
    ax.add_patch(Circle((0, 0), r, facecolor=c, edgecolor='none', alpha=a))

ax.text(0, -0.22, f'{threat}', fontsize=56, fontweight='bold', color=text_color, ha='center', va='center')
ax.text(0, -0.40, 'THREAT SCORE', fontsize=12, color=dim_color, ha='center', va='center', fontweight='500')
ax.text(0, -0.56, f'STATUS: {status}', fontsize=13, color=arc_color, ha='center', va='center', fontweight='bold')
ax.text(0, 1.22, 'Security Assessment', fontsize=18, fontweight='bold', color=text_color, ha='center', va='center')

plt.tight_layout()
plt.show()
Library

Matplotlib

Category

Part-to-Whole

Did this help you?

Support PyLucid to keep it free & growing

Support