Skip to content

Commit 7e1598d

Browse files
committed
applied rewiews
1 parent 0e0b7e1 commit 7e1598d

File tree

1 file changed

+78
-60
lines changed

1 file changed

+78
-60
lines changed

examples/misc/packed_bubbles.py

Lines changed: 78 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,19 @@ def __init__(self, r=None, a=None, bubble_distance=0):
2121
"""
2222
setup for bubble collapse
2323
24-
Args:
25-
r (list, optional): radius of the bubbles. Defaults to None.
26-
a (list, optional): area of the bubbles. Defaults to None.
27-
Note: If r or a is sorted, the results might look weird
28-
bubble_distance (int, optional): minimal distance the bubbles
29-
should have after collapsing. Defaults to 0.
24+
Parameters
25+
----------
26+
r : list, optional
27+
radius of the bubbles. Defaults to None.
28+
a : list, optional
29+
area of the bubbles. Defaults to None.
30+
bubble_distance : int, optional
31+
minimal distance the bubbles should
32+
have after collapsing. Defaults to 0.
33+
34+
Notes
35+
-----
36+
If r or a is sorted, the results might look weird
3037
"""
3138
if r is None:
3239
r = np.sqrt(a / np.pi)
@@ -59,8 +66,8 @@ def center_of_mass(self):
5966
)
6067

6168
def center_distance(self, bubble, bubbles):
62-
return np.sqrt(np.power(bubble[0] - bubbles[:, 0], 2) +
63-
np.power(bubble[1] - bubbles[:, 1], 2))
69+
return np.hypot(bubble[0] - bubbles[:, 0],
70+
bubble[1] - bubbles[:, 1])
6471

6572
def outline_distance(self, bubble, bubbles):
6673
center_distance = self.center_distance(bubble, bubbles)
@@ -76,59 +83,73 @@ def collides_with(self, bubble, bubbles):
7683
idx_min = np.argmin(distance)
7784
return idx_min if type(idx_min) == np.ndarray else [idx_min]
7885

79-
def collapse(self):
80-
moves = 0
81-
for i in range(len(self)):
82-
rest_bub = np.delete(self.bubbles, i, 0)
83-
# try to move directly towoards the center of mass
84-
# dir_vec from bubble to com
85-
dir_vec = self.com - self.bubbles[i, :2]
86-
87-
# shorten dir_vec to have length of 1
88-
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
89-
90-
# calculate new bubble position
91-
new_point = self.bubbles[i, :2] + dir_vec * self.step_dist
92-
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
93-
94-
# check whether new bubble collides with oder bubbles
95-
if not self.check_collisions(new_bubble, rest_bub):
96-
self.bubbles[i, :] = new_bubble
97-
self.com = self.center_of_mass()
98-
moves += 1
99-
else:
100-
# try to move around a bubble that you collide with
101-
# find colliding bubble
102-
for colliding in self.collides_with(new_bubble, rest_bub):
103-
# calculate dir vec
104-
dir_vec = rest_bub[colliding, :2] - self.bubbles[i, :2]
105-
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
106-
# calculate orthagonal vec
107-
orth = np.array([dir_vec[1], -dir_vec[0]])
108-
# test which dir to go
109-
new_point1 = self.bubbles[i, :2] + orth * self.step_dist
110-
new_point2 = self.bubbles[i, :2] - orth * self.step_dist
111-
dist1 = self.center_distance(
112-
self.com, np.array([new_point1]))
113-
dist2 = self.center_distance(
114-
self.com, np.array([new_point2]))
115-
new_point = new_point1 if dist1 < dist2 else new_point2
116-
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
117-
if not self.check_collisions(new_bubble, rest_bub):
118-
self.bubbles[i, :] = new_bubble
119-
self.com = self.center_of_mass()
120-
121-
if moves / len(self) < 0.1:
122-
self.step_dist = self.step_dist / 2
86+
def collapse(self, n_iterations=50):
87+
"""
88+
Move bubbles to the center of mass
89+
90+
Parameters
91+
----------
92+
n_iterations :int, optional
93+
number of moves to perform. Defaults to 50.
94+
"""
95+
for _i in range(n_iterations):
96+
moves = 0
97+
for i in range(len(self)):
98+
rest_bub = np.delete(self.bubbles, i, 0)
99+
# try to move directly towoards the center of mass
100+
# dir_vec from bubble to com
101+
dir_vec = self.com - self.bubbles[i, :2]
102+
103+
# shorten dir_vec to have length of 1
104+
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
105+
106+
# calculate new bubble position
107+
new_point = self.bubbles[i, :2] + dir_vec * self.step_dist
108+
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
109+
110+
# check whether new bubble collides with other bubbles
111+
if not self.check_collisions(new_bubble, rest_bub):
112+
self.bubbles[i, :] = new_bubble
113+
self.com = self.center_of_mass()
114+
moves += 1
115+
else:
116+
# try to move around a bubble that you collide with
117+
# find colliding bubble
118+
for colliding in self.collides_with(new_bubble, rest_bub):
119+
# calculate dir vec
120+
dir_vec = rest_bub[colliding, :2] - self.bubbles[i, :2]
121+
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
122+
# calculate orthagonal vec
123+
orth = np.array([dir_vec[1], -dir_vec[0]])
124+
# test which dir to go
125+
new_point1 = (self.bubbles[i, :2] + orth *
126+
self.step_dist)
127+
new_point2 = (self.bubbles[i, :2] - orth *
128+
self.step_dist)
129+
dist1 = self.center_distance(
130+
self.com, np.array([new_point1]))
131+
dist2 = self.center_distance(
132+
self.com, np.array([new_point2]))
133+
new_point = new_point1 if dist1 < dist2 else new_point2
134+
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
135+
if not self.check_collisions(new_bubble, rest_bub):
136+
self.bubbles[i, :] = new_bubble
137+
self.com = self.center_of_mass()
138+
139+
if moves / len(self) < 0.1:
140+
self.step_dist = self.step_dist / 2
123141

124142
def plot(self, ax, labels, colors):
125143
"""
126144
draw the bubble plot
127145
128-
Args:
129-
ax (matplotlib.axes._subplots.AxesSubplot)
130-
labels (list): labels of the bubbles
131-
colors (list): colors of the bubbles
146+
Parameters
147+
----------
148+
ax : matplotlib.axes._subplots.AxesSubplot
149+
labels : list
150+
labels of the bubbles
151+
colors : list
152+
colors of the bubbles
132153
"""
133154
for i in range(len(self)):
134155
circ = plt.Circle(
@@ -142,10 +163,7 @@ def plot(self, ax, labels, colors):
142163
bubble_plot = BubbleChart(a=np.array(
143164
browser_market_share['market_share']), bubble_distance=1)
144165

145-
# collapse plot 50 times. In some cases it might be useful
146-
# to do this more or less often
147-
for i in range(50):
148-
bubble_plot.collapse()
166+
bubble_plot.collapse()
149167

150168
fig, ax = plt.subplots(subplot_kw=dict(aspect="equal"))
151169
bubble_plot.plot(

0 commit comments

Comments
 (0)