import getopt import random import sys from typing import List import numpy as np import matplotlib.pyplot as plt from scipy.spatial import ConvexHull from scipy.spatial.qhull import QhullError from kmeans.algorithms import k_means from kmeans.clustering.cluster import Cluster from kmeans.clustering.point import Point def generate_points(x_bound: int, y_bound: int, count: int) -> List: """ Generates random points without replacement bounded by (x_bound, y_bound) @param x_bound The x direction boundary. @param y_bound The y direction boundary. @param count The count of points. """ xs = random.sample(range(0, x_bound), count) ys = random.sample(range(0, y_bound), count) points = list(zip(xs, ys)) result = [] for p in points: result.append(Point(p[0], p[1])) return result def main(): try: opts, args = getopt.getopt(sys.argv[1:], "x:y:r:", ['x=', 'y=', 'random=']) except getopt.GetoptError as err: print('Option not recognized') sys.exit(-1) x = None y = None random = None for o, a in opts: if o in ('-x', '--x'): x = int(a) elif o in ('-y', '--y'): y = int(a) elif o in ('-r', '--random'): random = int(a) else: print(f'Unknown option {o}\n') sys.exit(-1) if x is None or y is None or random is None: print('x, y, and r must be specified\n') sys.exit(-1) points = generate_points(x, y, random) print('--- INITIAL POINT PLOT ---') xs = [p.x for p in points] ys = [p.y for p in points] plt.plot(xs, ys, 'o') plt.show() clusters = k_means(points, 4, 0.001) # Color clusters assigned_colors = plt.cm.gist_ncar(np.linspace(0, 1, 4)) for i, cluster in enumerate(clusters): cluster.color = assigned_colors[i] print('--- CLUSTER PLOT ---') for cluster in clusters: xs = [p.x for p in cluster.points] ys = [p.y for p in cluster.points] plt.plot(xs, ys, 'o', cluster.color) plt.show() print('--- CLUSTER PLOT WITH CONVEX HULL BOUNDARIES ---') for cluster in clusters: xs = [p.x for p in cluster.points] ys = [p.y for p in cluster.points] plt.plot(xs, ys, 'o', cluster.color) # Convex hull plot if len(cluster.points) >= 4: points = np.array([p.array() for p in cluster.points]) try: hull = ConvexHull(points) except QhullError as e: print(str(e)) continue plt.plot(points[hull.vertices, 0], points[hull.vertices, 1], 'r--', lw=2) plt.plot(points[hull.vertices[0], 0], points[hull.vertices[0], 1], 'ro') plt.show() if __name__ == '__main__': main()