full upload so not to lose anything important
This commit is contained in:
93
tools/anomaly_scatter_plot.py
Normal file
93
tools/anomaly_scatter_plot.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
# Fix the random seed for reproducibility
|
||||
np.random.seed(0)
|
||||
|
||||
# 1. Generate NORMAL DATA (e.g. points roughly around the origin)
|
||||
# We'll keep them relatively close together so that a circle can enclose them easily.
|
||||
normal_data = np.random.randn(50, 2) * 0.75
|
||||
|
||||
# 2. Generate ANOMALOUS DATA
|
||||
# - Cluster 1: 3 points close together
|
||||
anomaly_cluster_1 = np.array([[3.0, 3.0], [3.2, 3.1], [2.8, 2.9], [0.4, 4.0]])
|
||||
|
||||
# - Cluster 2: A single point
|
||||
|
||||
# 3. Compute the center and radius for a boundary circle around normal data
|
||||
center = normal_data.mean(axis=0)
|
||||
distances = np.linalg.norm(normal_data - center, axis=1)
|
||||
radius = (
|
||||
np.max(distances) + 0.2
|
||||
) # Add a small margin to ensure all normal points are inside
|
||||
|
||||
# Create coordinates for plotting the circular boundary
|
||||
theta = np.linspace(0, 2 * np.pi, 200)
|
||||
circle_x = center[0] + radius * np.cos(theta)
|
||||
circle_y = center[1] + radius * np.sin(theta)
|
||||
|
||||
# 4. Plot the data
|
||||
plt.figure(figsize=(7, 7))
|
||||
|
||||
# Scatter normal points with 'o'
|
||||
plt.scatter(
|
||||
normal_data[:, 0], normal_data[:, 1], marker="o", color="blue", label="Normal Data"
|
||||
)
|
||||
|
||||
# Scatter anomalous points with 'x', but separate them by cluster for clarity
|
||||
plt.scatter(
|
||||
anomaly_cluster_1[:, 0],
|
||||
anomaly_cluster_1[:, 1],
|
||||
marker="x",
|
||||
color="red",
|
||||
label="Anomalies",
|
||||
)
|
||||
|
||||
# Plot the boundary (circle) around the normal data
|
||||
plt.plot(circle_x, circle_y, linestyle="--", color="black", label="Boundary")
|
||||
|
||||
# 5. Annotate/label the clusters
|
||||
# Label the normal cluster near its center
|
||||
# plt.text(center[0], center[1],
|
||||
# 'Normal Cluster',
|
||||
# horizontalalignment='center',
|
||||
# verticalalignment='center',
|
||||
# fontsize=9,
|
||||
# bbox=dict(facecolor='white', alpha=0.7))
|
||||
#
|
||||
# # Label anomaly cluster 1 near its centroid
|
||||
# ac1_center = anomaly_cluster_1.mean(axis=0)
|
||||
# plt.text(ac1_center[0], ac1_center[1],
|
||||
# 'Anomaly Cluster 1',
|
||||
# horizontalalignment='center',
|
||||
# verticalalignment='center',
|
||||
# fontsize=9,
|
||||
# bbox=dict(facecolor='white', alpha=0.7))
|
||||
#
|
||||
# # Label anomaly cluster 2
|
||||
# ac2_point = anomaly_cluster_2[0]
|
||||
# plt.text(ac2_point[0]+0.2, ac2_point[1],
|
||||
# 'Anomaly Cluster 2',
|
||||
# horizontalalignment='left',
|
||||
# verticalalignment='center',
|
||||
# fontsize=9,
|
||||
# bbox=dict(facecolor='white', alpha=0.7))
|
||||
|
||||
# Add legend and make plot look nice
|
||||
plt.legend(loc="upper left")
|
||||
# plt.title('2D Scatter Plot Showing Normal and Anomalous Clusters')
|
||||
plt.xlabel("x")
|
||||
plt.ylabel("y")
|
||||
plt.tick_params(
|
||||
axis="both", # changes apply to the x-axis
|
||||
which="both", # both major and minor ticks are affected
|
||||
bottom=False, # ticks along the bottom edge are off
|
||||
top=False, # ticks along the top edge are off
|
||||
left=False, # ticks along the top edge are off
|
||||
right=False, # ticks along the top edge are off
|
||||
labelbottom=False,
|
||||
labelleft=False,
|
||||
) #
|
||||
# plt.grid(True)
|
||||
plt.axis("equal") # Makes circles look circular rather than elliptical
|
||||
plt.savefig("scatter_plot.png")
|
||||
Reference in New Issue
Block a user