Skip to content

Commit 46d6568

Browse files
committed
Add benchmark test for handling large number of annotations
1 parent 8e53361 commit 46d6568

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Licensed under the terms of the BSD 3-Clause
4+
# (see plotpy/LICENSE for details)
5+
6+
"""Large number of annotations test"""
7+
8+
# guitest: show
9+
10+
import timeit
11+
12+
import numpy as np
13+
from guidata.qthelpers import qt_app_context
14+
15+
from plotpy.builder import make
16+
from plotpy.tests import data as ptd
17+
from plotpy.tests import vistools as ptv
18+
19+
WIN_REFS = []
20+
21+
22+
def plot(items, title):
23+
"""Plot items"""
24+
global WIN_REFS
25+
title = f"{title} - #refs: {len(WIN_REFS) + 1}"
26+
win = ptv.show_items(items, plot_type="image", wintitle=title, title=title)
27+
WIN_REFS.append(win)
28+
return win
29+
30+
31+
def create_polygon_vertices(
32+
x0: float, y0: float, nb_points: int, radius_mean: float, radius_variation: float
33+
) -> list[tuple[float, float]]:
34+
"""Generate points for a polygon around (x0, y0)
35+
36+
Args:
37+
x0: x coordinate of the polygon center
38+
y0: y coordinate of the polygon center
39+
nb_points: number of points to generate
40+
radius_mean: mean radius of the polygon
41+
radius_variation: variation in radius
42+
43+
Returns:
44+
List of (x, y) points representing the polygon vertices
45+
"""
46+
points = []
47+
# Calculate number of NaNs to append (random numbers between 0 and nb_points-10):
48+
num_nans = np.random.randint(0, nb_points - 10)
49+
for j in range(nb_points - num_nans):
50+
angle = j * (2 * np.pi / (nb_points - num_nans))
51+
radius = radius_mean + radius_variation * np.random.rand()
52+
x = x0 + radius * np.cos(angle)
53+
y = y0 + radius * np.sin(angle)
54+
points.append((x, y))
55+
for _ in range(num_nans):
56+
points.append((np.nan, np.nan))
57+
return points
58+
59+
60+
def create_random_polygons(
61+
size: int, nb_polygons: int, nb_points_per_polygon: int
62+
) -> np.ndarray:
63+
"""Create random polygons
64+
65+
Args:
66+
size: size of the area in which to create polygons
67+
nb_polygons: number of polygons to create
68+
nb_points_per_polygon: number of points per polygon
69+
70+
Returns:
71+
Array of shape (nb_polygons, nb_points_per_polygon, 2)
72+
"""
73+
polygons = []
74+
for _ in range(nb_polygons):
75+
x0 = size * np.random.rand()
76+
y0 = size * np.random.rand()
77+
points = create_polygon_vertices(
78+
x0, y0, nb_points_per_polygon, radius_mean=20, radius_variation=30
79+
)
80+
# Append the flattened points:
81+
polygons.append(points)
82+
return np.array(polygons)
83+
84+
85+
def test_large_number_of_annotations(measure_execution_time: bool = False):
86+
"""Test large number of annotations
87+
88+
Args:
89+
measure_execution_time: if True, measure and print the execution time, then
90+
quit the application immediately.
91+
"""
92+
title = "Large number of annotations test"
93+
size = 2000
94+
nb_polygons = 100
95+
nb_points_per_polygon = 120
96+
with qt_app_context(exec_loop=not measure_execution_time):
97+
data = ptd.gen_image4(size, size)
98+
x = np.linspace(0, size - 1, size)
99+
y = np.linspace(0, size - 1, size)
100+
item = make.xyimage(x, y, data)
101+
item.set_readonly(True)
102+
item.set_selectable(False)
103+
items = [item]
104+
polygons = create_random_polygons(size, nb_polygons, nb_points_per_polygon)
105+
for i, points in enumerate(polygons):
106+
polygon = make.annotated_polygon(np.array(points), title=f"Polygon {i + 1}")
107+
polygon.set_closed(False)
108+
items.append(polygon)
109+
if measure_execution_time:
110+
exec_time = timeit.timeit(lambda: plot(items, title), number=10) / 10
111+
print(
112+
f"Execution time with {nb_polygons} polygons "
113+
f"({nb_points_per_polygon} points per polygon): "
114+
f"{exec_time:.3f} seconds/plot"
115+
)
116+
else:
117+
win = plot(items, title)
118+
win.register_annotation_tools()
119+
120+
121+
if __name__ == "__main__":
122+
test_large_number_of_annotations(measure_execution_time=True)

0 commit comments

Comments
 (0)