Skip to content

Commit d845664

Browse files
Batch draw commands (#225)
* added experimental batch api * wip * cleaned batch drawing api * added documentation * fixed flake8 issues * removed old example * Update examples/batch_drawing.ipynb Co-authored-by: martinRenou <[email protected]> * Update examples/batch_drawing.ipynb Co-authored-by: martinRenou <[email protected]> * Update examples/batch_drawing.ipynb Co-authored-by: martinRenou <[email protected]> Co-authored-by: martinRenou <[email protected]>
1 parent b1cc2de commit d845664

File tree

6 files changed

+766
-5
lines changed

6 files changed

+766
-5
lines changed

examples/Interaction during animation.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@
358358
],
359359
"metadata": {
360360
"kernelspec": {
361-
"display_name": "Python 3",
361+
"display_name": "Python 3 (ipykernel)",
362362
"language": "python",
363363
"name": "python3"
364364
},
@@ -372,7 +372,7 @@
372372
"name": "python",
373373
"nbconvert_exporter": "python",
374374
"pygments_lexer": "ipython3",
375-
"version": "3.7.6"
375+
"version": "3.9.7"
376376
}
377377
},
378378
"nbformat": 4,

examples/batch_drawing.ipynb

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "3ad9d78d-8bb6-4d4b-ab5f-fd7bc8ec11ca",
6+
"metadata": {},
7+
"source": [
8+
"## Fast Batch Drawing:\n",
9+
"To speed up the drawing of many objects ipycanvas offers a batch api to draw many items to the canvas quickly"
10+
]
11+
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": 1,
15+
"id": "3ea1b15d-478b-41a2-83a1-3e66e5ff5d24",
16+
"metadata": {},
17+
"outputs": [],
18+
"source": [
19+
"import numpy as np\n",
20+
"from ipycanvas import Canvas, hold_canvas"
21+
]
22+
},
23+
{
24+
"cell_type": "markdown",
25+
"id": "2117b808-65d2-44dd-a780-dd9100809a68",
26+
"metadata": {},
27+
"source": [
28+
"## Batch Draw Circles\n",
29+
"draw many circles each cirlcle has the same color"
30+
]
31+
},
32+
{
33+
"cell_type": "code",
34+
"execution_count": 2,
35+
"id": "82b532b6-06b0-4255-b4fa-e03a6363ddf0",
36+
"metadata": {
37+
"tags": []
38+
},
39+
"outputs": [
40+
{
41+
"data": {
42+
"application/vnd.jupyter.widget-view+json": {
43+
"model_id": "92b6da42c15842298d3faf678a6381fa",
44+
"version_major": 2,
45+
"version_minor": 0
46+
},
47+
"text/plain": [
48+
"Canvas(height=300, width=800)"
49+
]
50+
},
51+
"metadata": {},
52+
"output_type": "display_data"
53+
}
54+
],
55+
"source": [
56+
"canvas = Canvas(width=800, height=300)\n",
57+
"# draw n circles with and random radii, random colors, and random alpha values\n",
58+
"n_circles = 100\n",
59+
"x = np.random.randint(0, canvas.width, size=(n_circles))\n",
60+
"y = np.random.randint(0, canvas.width, size=(n_circles))\n",
61+
"r = np.random.randint(10, 20, size=(n_circles))\n",
62+
"canvas.fill_style = 'red'\n",
63+
"alphas = np.random.random(n_circles)\n",
64+
"with hold_canvas(canvas):\n",
65+
" # the filled circles\n",
66+
" canvas.fill_circles(x,y,r)\n",
67+
" # the outlines\n",
68+
" canvas.stroke_style = 'blue'\n",
69+
" canvas.stroke_circles(x,y,r)\n",
70+
"canvas"
71+
]
72+
},
73+
{
74+
"cell_type": "markdown",
75+
"id": "7851edd8-2a84-4493-b331-a7cff5a08079",
76+
"metadata": {},
77+
"source": [
78+
"## Batch Draw Styled Circles\n",
79+
"draw many circles where each circle can have a diferent color and alpha channel"
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": 3,
85+
"id": "ce545eee-d9c0-47ab-afb7-274fa22389cd",
86+
"metadata": {},
87+
"outputs": [
88+
{
89+
"data": {
90+
"application/vnd.jupyter.widget-view+json": {
91+
"model_id": "e209d607b8de4226a5dbff72536b0ec7",
92+
"version_major": 2,
93+
"version_minor": 0
94+
},
95+
"text/plain": [
96+
"Canvas(height=300, width=800)"
97+
]
98+
},
99+
"metadata": {},
100+
"output_type": "display_data"
101+
}
102+
],
103+
"source": [
104+
"canvas = Canvas(width=800, height=300)\n",
105+
"n_circles = 1000\n",
106+
"x = np.random.randint(0, canvas.width, size=(n_circles))\n",
107+
"y = np.random.randint(0, canvas.width, size=(n_circles))\n",
108+
"r = np.random.randint(10, 20, size=(n_circles))\n",
109+
"colors_fill = np.random.randint(0, 255, size=(n_circles,3))\n",
110+
"colors_outline = np.random.randint(0, 255, size=(n_circles,3))\n",
111+
"alphas = np.random.random(n_circles)\n",
112+
"with hold_canvas(canvas):\n",
113+
" canvas.fill_styled_circles(x,y,r,color=colors_fill,alpha=alphas)\n",
114+
" canvas.line_width = 2\n",
115+
" canvas.stroke_styled_circles(x,y,r,color=colors_outline,alpha=1)\n",
116+
"canvas"
117+
]
118+
},
119+
{
120+
"cell_type": "markdown",
121+
"id": "afea33c6-c6a8-4528-a1d9-7535a6810e9a",
122+
"metadata": {},
123+
"source": [
124+
"# Batch Draw Polygons / LineSegments\n",
125+
"## Case 1: All Polygons / LineSegments have the same number of points"
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": 4,
131+
"id": "885a5ec6-06a8-4430-815e-63c06f6fa2cb",
132+
"metadata": {},
133+
"outputs": [
134+
{
135+
"data": {
136+
"application/vnd.jupyter.widget-view+json": {
137+
"model_id": "f0bfa8a9abe541059c8f0898e913b652",
138+
"version_major": 2,
139+
"version_minor": 0
140+
},
141+
"text/plain": [
142+
"Canvas(height=300, width=800)"
143+
]
144+
},
145+
"metadata": {},
146+
"output_type": "display_data"
147+
}
148+
],
149+
"source": [
150+
"canvas = Canvas(width=800, height=300)\n",
151+
"n_polygons = 50\n",
152+
"\n",
153+
"# each polygon has 4 points\n",
154+
"n_points_per_polygon = 4\n",
155+
"\n",
156+
"polygons = np.zeros([n_polygons, n_points_per_polygon, 2])\n",
157+
"\n",
158+
"polygons[:,0,0] = 0.0\n",
159+
"polygons[:,0,1] = 0.0\n",
160+
"\n",
161+
"polygons[:,1,0] = 1.0\n",
162+
"polygons[:,1,1] = 0.0\n",
163+
"\n",
164+
"polygons[:,2,0] = 1.0\n",
165+
"polygons[:,2,1] = 1.0\n",
166+
"\n",
167+
"polygons[:,3,0] = 0.0\n",
168+
"polygons[:,3,1] = 1.0\n",
169+
"\n",
170+
"colors_fill = np.random.randint(0, 255, size=(n_polygons,3))\n",
171+
"colors_outline = np.random.randint(0, 255, size=(n_polygons,3))\n",
172+
"\n",
173+
"# scale each polygon\n",
174+
"polygons *= np.linspace(1.0, 200.0, num=n_polygons)[:,None,None]\n",
175+
"\n",
176+
"# translate each polygon\n",
177+
"polygons += np.linspace(1.0, 100.0, num=n_polygons)[:,None,None]\n",
178+
"\n",
179+
"points_per_polygon = np.ones([n_polygons]) * n_points_per_polygon\n",
180+
"with hold_canvas(canvas):\n",
181+
" canvas.stroke_styled_polygons(polygons, color=colors_fill, alpha=1)\n",
182+
"canvas"
183+
]
184+
},
185+
{
186+
"cell_type": "code",
187+
"execution_count": 5,
188+
"id": "6bf31d36-01af-484c-9360-b97f504532a2",
189+
"metadata": {},
190+
"outputs": [
191+
{
192+
"data": {
193+
"application/vnd.jupyter.widget-view+json": {
194+
"model_id": "08ef9e57eb5f493697fc6aa2c63c32ac",
195+
"version_major": 2,
196+
"version_minor": 0
197+
},
198+
"text/plain": [
199+
"Canvas(height=300, width=800)"
200+
]
201+
},
202+
"metadata": {},
203+
"output_type": "display_data"
204+
}
205+
],
206+
"source": [
207+
"canvas = Canvas(width=800, height=300)\n",
208+
"\n",
209+
"n_line_segments = 20\n",
210+
"\n",
211+
"n_points_per_line_segment = 500\n",
212+
"\n",
213+
"line_segments = np.zeros([n_line_segments, n_points_per_line_segment, 2])\n",
214+
"\n",
215+
"x = np.linspace(0,canvas.width, num=n_points_per_line_segment)[None,:]\n",
216+
"line_segments[:,:,0] = np.linspace(0,canvas.width, num=n_points_per_line_segment)[None,:]\n",
217+
"line_segments[:,:,1] = (30.0*np.sin(x*0.1))[None,:]\n",
218+
"\n",
219+
"colors_outline = np.random.randint(0, 255, size=(n_polygons,3))\n",
220+
"\n",
221+
"# translate line segments in y direction\n",
222+
"line_segments[:,:,1] += np.linspace(1.0, canvas.height, num=n_line_segments)[:,None]\n",
223+
"\n",
224+
"with hold_canvas(canvas):\n",
225+
" canvas.stroke_styled_line_segments(line_segments, color=colors_fill, alpha=1)\n",
226+
"canvas"
227+
]
228+
},
229+
{
230+
"cell_type": "markdown",
231+
"id": "3fb21075-bb46-41a1-b001-5d90f72ebebd",
232+
"metadata": {
233+
"tags": []
234+
},
235+
"source": [
236+
"# Batch Draw Polygons / LineSegments\n",
237+
"## Case 2: Polygons / LineSegments can have different number of Points. Points are specified as list of arrays"
238+
]
239+
},
240+
{
241+
"cell_type": "code",
242+
"execution_count": 6,
243+
"id": "34643bf9-d9d9-4296-aa02-67531e6f500f",
244+
"metadata": {
245+
"tags": []
246+
},
247+
"outputs": [
248+
{
249+
"data": {
250+
"application/vnd.jupyter.widget-view+json": {
251+
"model_id": "219e9b29162d4d5897d53a461c97c232",
252+
"version_major": 2,
253+
"version_minor": 0
254+
},
255+
"text/plain": [
256+
"Canvas(height=400, width=400)"
257+
]
258+
},
259+
"metadata": {},
260+
"output_type": "display_data"
261+
}
262+
],
263+
"source": [
264+
"canvas = Canvas(width=400, height=400)\n",
265+
"\n",
266+
"triangle = [(0,0),(0,40),(30,40)] # triangle\n",
267+
"rectangle = [(100,100),(300,100),(300,200),(100,200)] # rectangle\n",
268+
"irregular = np.random.randint(0, 400,size=(5,2)) # irregular with 5 sides\n",
269+
"polygons = [\n",
270+
" triangle,\n",
271+
" rectangle,\n",
272+
" irregular\n",
273+
"]\n",
274+
"colors = [\n",
275+
" (255,0,0),\n",
276+
" (0,255,0),\n",
277+
" (0,0,255)\n",
278+
"]\n",
279+
"\n",
280+
"with hold_canvas(canvas):\n",
281+
" canvas.fill_styled_polygons(polygons, color=colors_fill, alpha=1)\n",
282+
"canvas"
283+
]
284+
},
285+
{
286+
"cell_type": "markdown",
287+
"id": "24ac4301-a9c5-473f-bff1-376e62cc01f1",
288+
"metadata": {
289+
"tags": []
290+
},
291+
"source": [
292+
"# Batch Draw Polygons / LineSegments\n",
293+
"## Case 2: Polygons / LineSegments can have different number of Points. Points given as a flat array"
294+
]
295+
},
296+
{
297+
"cell_type": "code",
298+
"execution_count": 8,
299+
"id": "272deb5a-fc18-44b0-af01-04f3afb28247",
300+
"metadata": {},
301+
"outputs": [
302+
{
303+
"data": {
304+
"application/vnd.jupyter.widget-view+json": {
305+
"model_id": "aa24d7e01ad04540be42d2702cb3ff74",
306+
"version_major": 2,
307+
"version_minor": 0
308+
},
309+
"text/plain": [
310+
"Canvas(height=400, width=400)"
311+
]
312+
},
313+
"metadata": {},
314+
"output_type": "display_data"
315+
}
316+
],
317+
"source": [
318+
"canvas = Canvas(width=400, height=400)\n",
319+
"n_polygons = 20\n",
320+
"points_per_polygon = np.random.randint(3, 6, size=n_polygons)\n",
321+
"total_points = np.sum(points_per_polygon)\n",
322+
"polygons = np.random.randint(0, 400, size=[total_points, 2])\n",
323+
"alpha = np.random.random(n_polygons)\n",
324+
"colors_fill = np.random.randint(0, 255, size=(n_polygons,3))\n",
325+
"colors_outline = np.random.randint(0, 255, size=(n_polygons,3))\n",
326+
"\n",
327+
"with hold_canvas(canvas):\n",
328+
" # the filling\n",
329+
" canvas.fill_styled_polygons(polygons, points_per_polygon=points_per_polygon, color=colors_fill, alpha=alpha)\n",
330+
" \n",
331+
" # draw outlines ontop where each line has the same style\n",
332+
" canvas.stroke_style = \"black\"\n",
333+
" canvas.line_width = 2\n",
334+
" canvas.stroke_polygons(polygons, points_per_polygon=points_per_polygon)\n",
335+
"canvas"
336+
]
337+
}
338+
],
339+
"metadata": {
340+
"kernelspec": {
341+
"display_name": "Python 3 (ipykernel)",
342+
"language": "python",
343+
"name": "python3"
344+
},
345+
"language_info": {
346+
"codemirror_mode": {
347+
"name": "ipython",
348+
"version": 3
349+
},
350+
"file_extension": ".py",
351+
"mimetype": "text/x-python",
352+
"name": "python",
353+
"nbconvert_exporter": "python",
354+
"pygments_lexer": "ipython3",
355+
"version": "3.9.7"
356+
}
357+
},
358+
"nbformat": 4,
359+
"nbformat_minor": 5
360+
}

examples/particle_system.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
],
192192
"metadata": {
193193
"kernelspec": {
194-
"display_name": "Python 3",
194+
"display_name": "Python 3 (ipykernel)",
195195
"language": "python",
196196
"name": "python3"
197197
},
@@ -205,7 +205,7 @@
205205
"name": "python",
206206
"nbconvert_exporter": "python",
207207
"pygments_lexer": "ipython3",
208-
"version": "3.9.0"
208+
"version": "3.9.7"
209209
}
210210
},
211211
"nbformat": 4,

0 commit comments

Comments
 (0)