- Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathlissajous.py
94 lines (75 loc) · 2.36 KB
/
lissajous.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
==========================
An animated lissajous ball
==========================
Inspired by https://twitter.com/_brohrer_/status/1584681864648065027
An animated scatter plot using a custom container and :class:`.wrappers.PathCollectionWrapper`
"""
importtime
fromtypingimportDict, Tuple, Any, Union
fromfunctoolsimportpartial
importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlib.markersasmmarkers
frommatplotlib.animationimportFuncAnimation
fromdata_prototype.conversion_edgeimportGraph
fromdata_prototype.descriptionimportDesc
fromdata_prototype.wrappersimportPathCollectionWrapper
classLissajous:
N=1024
# cycles per minutes
scale=2
defdescribe(self):
return {
"x": Desc((self.N,)),
"y": Desc((self.N,)),
"time": Desc(()),
"sizes": Desc(()),
"paths": Desc(()),
"edgecolors": Desc(()),
"facecolors": Desc((self.N,)),
}
defquery(
self,
graph: Graph,
parent_coordinates: str="axes",
) ->Tuple[Dict[str, Any], Union[str, int]]:
defnext_time():
cur_time=time.time()
cur_time=np.array(
[cur_time, cur_time-0.1, cur_time-0.2, cur_time-0.3]
)
phase=15*np.pi* (self.scale*cur_time%60) /150
marker_obj=mmarkers.MarkerStyle("o")
return {
"x": np.cos(5*phase),
"y": np.sin(3*phase),
"sizes": np.array([256]),
"paths": [
marker_obj.get_path().transformed(marker_obj.get_transform())
],
"edgecolors": "k",
"facecolors": ["#4682b4ff", "#82b446aa", "#46b48288", "#8246b433"],
"time": cur_time[0],
}, hash(cur_time[0])
returnnext_time()
defupdate(frame, art):
returnart
sot_c=Lissajous()
fig, ax=plt.subplots()
ax.set_xlim(-1.1, 1.1)
ax.set_ylim(-1.1, 1.1)
lw=PathCollectionWrapper(sot_c, offset_transform=ax.transData)
ax.add_artist(lw)
# ax.set_xticks([])
# ax.set_yticks([])
ax.set_aspect(1)
ani=FuncAnimation(
fig,
partial(update, art=(lw,)),
frames=60,
interval=1000/100*15,
# TODO: blitting does not work because wrappers do not inherent from Artist
# blit=True,
)
plt.show()