6.7.23
Don't miss anomalies with a control chart When you need to monitor variation in inquiries or yield rates, control charts are effective. Plotting statistical control limits helps detect anomalies immediately.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import matplotlib.pyplot as plt
rng = np . random . default_rng ( 5 )
values = 45 + rng . normal ( 0 , 3 , size = 28 )
values [[ 6 , 18 ]] += np . array ([ 12 , - 10 ]) # Inject anomalies
mean = values . mean ()
std = values . std ( ddof = 1 )
ucl = mean + 3 * std
lcl = mean - 3 * std
fig , ax = plt . subplots ( figsize = ( 6.4 , 3.6 ))
ax . plot ( values , marker = "o" , color = "#0ea5e9" )
ax . axhline ( mean , color = "#334155" , linewidth = 1.3 , label = "Mean" )
ax . axhline ( ucl , color = "#ef4444" , linestyle = "--" , label = "UCL" )
ax . axhline ( lcl , color = "#ef4444" , linestyle = "--" , label = "LCL" )
ax . set_xticks ( range ( 0 , len ( values ), 4 ), labels = [ f "W { i + 1 } " for i in range ( 0 , len ( values ), 4 )])
ax . set_title ( "Control chart of call handling time" )
ax . set_ylabel ( "Average handling time (sec)" )
ax . grid ( alpha = 0.2 )
for idx , val in enumerate ( values ):
if val > ucl or val < lcl :
ax . annotate (
"Anomaly" ,
( idx , val ),
xytext = ( idx + 0.5 , val + 4 ),
arrowprops = dict ( arrowstyle = "->" , color = "#ef4444" ),
color = "#ef4444" ,
)
ax . legend ( loc = "upper right" )
fig . tight_layout ()
plt . show ()
Reading tips
# Draw control limits (±3σ) around the mean to flag statistically abnormal points. If anomalies persist, the process may have shifted; investigate root causes. Adjust line style and markers to match the tone of your report.