Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9cc4e30

Browse files
working PlayerAnimation with example
1 parentdf926b7 commit9cc4e30

File tree

3 files changed

+255
-15
lines changed

3 files changed

+255
-15
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
=====
3+
Decay
4+
=====
5+
6+
This example showcases:
7+
- using PlayerAnimation
8+
- using blitting
9+
- changing axes limits during an animation.
10+
"""
11+
12+
importitertools
13+
14+
importnumpyasnp
15+
importmatplotlib.pyplotasplt
16+
17+
frommatplotlib.animationimportPlayerAnimation,FuncAnimation
18+
importmath
19+
20+
defdata_gen():
21+
forcntinitertools.count():
22+
yieldcnt
23+
24+
definit(val):
25+
globalline
26+
print(f"init with val:{val}")
27+
ifnot"line"inglobals():
28+
line,=ax.plot([], [],lw=2)
29+
ax.grid()
30+
ax.set_ylim(-1.1,1.1)
31+
ax.set_xlim(0,1+math.floor(val/10))
32+
line.set_data([], [])
33+
return [line]
34+
35+
fig,ax=plt.subplots()
36+
37+
defupdate_plot(i):
38+
# update the data
39+
xdata=np.linspace(-10,10,1000)
40+
ydata=np.sin(xdata+i*0.1)
41+
_,xmax=ax.get_xlim()
42+
new_xmax=1+math.floor(i/10)
43+
ifxmax!=new_xmax:
44+
ax.set_xlim(0,new_xmax)
45+
ax.figure.canvas.draw_idle()
46+
line.set_data(xdata,ydata)
47+
48+
return [line]
49+
50+
animation=PlayerAnimation(fig=fig,func=update_plot,init_func=init,interval=100,blit=True,valstep=0.5)
51+
plt.show()

‎lib/matplotlib/animation.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
DISPLAY_TEMPLATE,INCLUDED_FRAMES,JS_INCLUDE,STYLE_INCLUDE)
4141
frommatplotlibimport_api,cbook
4242

43+
frommatplotlib.widgetsimportButton,Slider
44+
importmpl_toolkits.axes_grid1
45+
fromfunctoolsimportpartial
4346

4447
_log=logging.getLogger(__name__)
4548

@@ -1764,3 +1767,106 @@ def _draw_frame(self, framedata):
17641767

17651768
forainself._drawn_artists:
17661769
a.set_animated(self._blit)
1770+
1771+
classPlayerAnimation(FuncAnimation):
1772+
# inspired from https://stackoverflow.com/a/46327978/3949028
1773+
PLAY_SYMBOL="$\u25B6$"
1774+
STOP_SYMBOL="$\u25A0$"
1775+
PAUSE_SYMBOL="$\u23F8$"#TODO use instead of STOP_SYMBOL, but doesn't work in Button.label
1776+
ONE_BACK_SYMBOL="$\u29CF$"
1777+
ONE_FORWARD_SYMBOL="$\u29D0$"
1778+
1779+
def__init__(self,func,init_func,min_value=0,max_value=100,
1780+
pos=(0.125,0.92),valstep=1,**kwargs):
1781+
self.val=min_value
1782+
self.min=min_value
1783+
self.max=max_value
1784+
self.direction=1
1785+
self.caller_func=func
1786+
self.valstep=valstep
1787+
self._player_initiated=False
1788+
#https://github.com/matplotlib/matplotlib/issues/17685
1789+
1790+
definit_func_wrapper():
1791+
returninit_func(self.val)
1792+
1793+
super().__init__(func=self._func_wrapper,frames=self._frame_generator,
1794+
init_func=init_func_wrapper,**kwargs)
1795+
1796+
self._setup_player(pos)
1797+
1798+
def_setup_player(self,pos):
1799+
ifnotself._player_initiated:
1800+
self._player_initiated=True
1801+
playerax=self._fig.add_axes([pos[0],pos[1],0.64,0.04])
1802+
divider=mpl_toolkits.axes_grid1.make_axes_locatable(playerax)
1803+
sax=divider.append_axes("right",size="80%",pad=0.05)
1804+
ofax=divider.append_axes("right",size="100%",pad=0.05)
1805+
sliderax=divider.append_axes("right",size="500%",pad=0.07)
1806+
self.button_oneback=Button(playerax,label=self.ONE_BACK_SYMBOL,useblit=self._blit)
1807+
self.play_pause_button=Button(sax,label=self.STOP_SYMBOL,useblit=self._blit)
1808+
self.button_oneforward=Button(ofax,label=self.ONE_FORWARD_SYMBOL,useblit=self._blit)
1809+
self.button_oneback.on_clicked(self.onebackward)
1810+
self.play_pause_button.on_clicked(self.play_pause)
1811+
self.button_oneforward.on_clicked(self.oneforward)
1812+
self.slider=Slider(sliderax,'',self.min,self.max,valinit=self.min,valstep=self.valstep,useblit=self._blit)
1813+
self.slider.on_changed(self.set_pos)
1814+
1815+
def_frame_generator(self):
1816+
whileTrue:
1817+
next=self.val+self.direction*self.valstep
1818+
ifnext>=self.minandnext<=self.max:
1819+
self.val=next
1820+
print(f"yield:{self.val}")
1821+
yieldself.val
1822+
else:
1823+
self.pause()
1824+
print(f"pause, yield:{self.val}")
1825+
yieldself.val
1826+
1827+
defpause(self,event=None):
1828+
super().pause()
1829+
self.direction=0
1830+
self.play_pause_button.label.set_text(self.PLAY_SYMBOL)
1831+
self.play_pause_button._draw()
1832+
1833+
defresume(self,event=None):
1834+
self.direction=1
1835+
self.play_pause_button.label.set_text(self.STOP_SYMBOL)
1836+
self.play_pause_button._draw()
1837+
super().resume()
1838+
1839+
defplay_pause(self,event=None):
1840+
ifself.direction==0:
1841+
self.resume()
1842+
else:
1843+
self.pause()
1844+
1845+
defoneforward(self,event=None):
1846+
self.direction=1
1847+
self.trigger_step()
1848+
1849+
defonebackward(self,event=None):
1850+
self.direction=-1
1851+
self.trigger_step()
1852+
1853+
defset_pos(self,val):
1854+
ifisinstance(self.valstep,int):
1855+
val=int(val)# slider gives float event if valstep is int
1856+
ifself.val!=val:
1857+
print(f"slider set_pos:{val}")
1858+
self.val=val
1859+
self.direction=0
1860+
self.trigger_step()
1861+
1862+
deftrigger_step(self):
1863+
forainself._drawn_artists:
1864+
a.set_animated(True)
1865+
self._step()
1866+
self.pause()
1867+
1868+
def_func_wrapper(self,val):
1869+
print(f"player _func_wrapper:{val}")
1870+
self.slider.set_val(val)
1871+
returnself.caller_func(self.val)
1872+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp