The Python program below plots a random set of 3 points and circles around them according to the eps
slider value.
When changing the slider value, the circles change.
Also, if two circles touch each other, a segment connecting their centers is drawn.
My problem is: how to remove such segment if the eps
decreases so there is no intersection anymore?
In resume, how to remove the line collection from the plot?
MWE
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
from matplotlib import collections as mc
# create circles
circles = []
def create_circles(N):
for i in range(N):
circles.append(plt.Circle(pts[i], min_distance/10, ec="b", fill=False))
ax.add_patch(circles[i])
# create edges
def create_edges(eps):
edges = []
tmp = np.where(distance_matrix < 2 * eps)
edges_ij = zip(tmp[0], tmp[1])
for e in edges_ij:
if e[0] < e[1]:
edges.append([pts[e[0]], pts[e[1]]])
lc = mc.LineCollection(edges, colors='r', linewidths=1)
ax.add_collection(lc)
# create points
def create_points(N):
ptsx = np.random.random(N)
ptsy = np.random.random(N)
pts = zip(ptsx, ptsy)
return pts
# create distance matrix
def create_distance_matrix(pts):
N = len(pts)
distance_matrix = np.zeros((N, N))
for i in range(N-1):
for j in range(i+1,N):
P = pts[i]
Q = pts[j]
distance_matrix[i, j] = np.sqrt((P[0]-Q[0])**2 + (P[1]-Q[1])**2)
distance_matrix[j, i] = distance_matrix[i, j]
max_distance = np.max(distance_matrix)
min_distance = np.min(distance_matrix[distance_matrix > 0])
return min_distance, max_distance, distance_matrix
# when epsilon slider changes
def update_eps(val):
eps1 = eps_slider.val
create_edges(eps1)
for i in range(len(circles)):
circles[i].set_radius(eps1)
fig.canvas.draw_idle()
axis_color = 'lightgoldenrodyellow'
bullet_size = 4
xmin, xmax = 0, 1
ymin, ymax = 0, 1
delta = .2
xlim = [xmin-delta, xmax+delta]
ylim = [ymin-delta, ymax+delta]
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
ax.axis([xlim[0], xlim[1], ylim[0], ylim[1]])
ax.set_aspect("equal")
N_0 = 3
N_max = 10
pts = create_points(N_0)
min_distance, max_distance, distance_matrix = create_distance_matrix(pts)
create_circles(N_0)
eps_0 = min_distance / 3
# create sliders
eps_slider_ax = fig.add_axes([0.25, 0.15, .65, 0.03], facecolor=axis_color)
N_slider_ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], facecolor=axis_color)
eps_slider = Slider(eps_slider_ax, 'eps', min_distance/3, max_distance, valinit=eps_0)
N_slider = Slider(N_slider_ax, 'Num pts', 1, N_max, valinit=2, valfmt="%i")
eps_slider.on_changed(update_eps)
# Draw the initial plot
desenho = ax.scatter([x[0] for x in pts], [x[1] for x in pts], alpha=1, s=bullet_size)
plt.show()