You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1
(3) |
2
(2) |
3
(6) |
4
(4) |
5
(1) |
6
|
7
|
8
|
9
|
10
|
11
(1) |
12
(1) |
13
(1) |
14
(4) |
15
|
16
(8) |
17
(7) |
18
(5) |
19
|
20
|
21
(2) |
22
|
23
(2) |
24
|
25
(2) |
26
(6) |
27
(3) |
28
(2) |
29
(2) |
30
(2) |
31
|
|
|
|
|
Revision: 8663 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8663&view=rev Author: ryanmay Date: 2010年08月26日 03:49:17 +0000 (2010年8月26日) Log Message: ----------- Hide old animation examples under the animation/ subdir. Added Paths: ----------- trunk/matplotlib/examples/animation/old_animation/ Removed Paths: ------------- trunk/matplotlib/examples/old_animation/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 8662 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8662&view=rev Author: ryanmay Date: 2010年08月26日 03:40:09 +0000 (2010年8月26日) Log Message: ----------- Add another set of basic examples. Added Paths: ----------- trunk/matplotlib/examples/animation/basic_example.py Added: trunk/matplotlib/examples/animation/basic_example.py =================================================================== --- trunk/matplotlib/examples/animation/basic_example.py (rev 0) +++ trunk/matplotlib/examples/animation/basic_example.py 2010年08月26日 03:40:09 UTC (rev 8662) @@ -0,0 +1,34 @@ +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +def update_line(num, data, line): + line.set_data(data[...,:num]) + return line, + +fig1 = plt.figure() + +data = np.random.rand(2, 25) +l, = plt.plot([], [], 'r-') +plt.xlim(0, 1) +plt.ylim(0, 1) +plt.xlabel('x') +plt.title('test') +line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l), + interval=50, blit=True) +#line_ani.save('lines.mp4') + +fig2 = plt.figure() + +x = np.arange(-9, 10) +y = np.arange(-9, 10).reshape(-1, 1) +base = np.hypot(x, y) +ims = [] +for add in np.arange(15): + ims.append((plt.pcolor(x, y, base + add, norm=plt.Normalize(0, 30)),)) + +im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, + blit=True) +#im_ani.save('im.mp4') + +plt.show() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 8661 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8661&view=rev Author: ryanmay Date: 2010年08月26日 03:30:38 +0000 (2010年8月26日) Log Message: ----------- Update examples to use proper imports. Modified Paths: -------------- trunk/matplotlib/examples/animation/animate_decay.py trunk/matplotlib/examples/animation/dynamic_image.py trunk/matplotlib/examples/animation/dynamic_image2.py trunk/matplotlib/examples/animation/histogram.py trunk/matplotlib/examples/animation/random_data.py trunk/matplotlib/examples/animation/simple_3danim.py trunk/matplotlib/examples/animation/simple_anim.py trunk/matplotlib/examples/animation/strip_chart_demo.py trunk/matplotlib/examples/animation/subplots.py Modified: trunk/matplotlib/examples/animation/animate_decay.py =================================================================== --- trunk/matplotlib/examples/animation/animate_decay.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/animate_decay.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -1,6 +1,6 @@ import numpy as np import matplotlib.pyplot as plt -from animation import FuncAnimation +import matplotlib.animation as animation def data_gen(): t = data_gen.t @@ -32,5 +32,6 @@ return line, -ani = FuncAnimation(fig, run, data_gen, blit=True, interval=10, repeat=False) +ani = animation.FuncAnimation(fig, run, data_gen, blit=True, interval=10, + repeat=False) plt.show() Modified: trunk/matplotlib/examples/animation/dynamic_image.py =================================================================== --- trunk/matplotlib/examples/animation/dynamic_image.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/dynamic_image.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -4,7 +4,7 @@ """ import numpy as np import matplotlib.pyplot as plt -from animation import FuncAnimation +import matplotlib.animation as animation fig = plt.figure() @@ -23,5 +23,5 @@ im.set_array(f(x,y)) return im, -ani = FuncAnimation(fig, updatefig, interval=50, blit=True) +ani = animation.FuncAnimation(fig, updatefig, interval=50, blit=True) plt.show() Modified: trunk/matplotlib/examples/animation/dynamic_image2.py =================================================================== --- trunk/matplotlib/examples/animation/dynamic_image2.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/dynamic_image2.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -4,7 +4,7 @@ """ import numpy as np import matplotlib.pyplot as plt -from animation import ArtistAnimation +import matplotlib.animation as animation fig = plt.figure() @@ -20,5 +20,6 @@ y += np.pi / 20. ims.append([plt.imshow(f(x, y), cmap=plt.get_cmap('jet'))]) -ani = ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) +ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, + repeat_delay=1000) plt.show() Modified: trunk/matplotlib/examples/animation/histogram.py =================================================================== --- trunk/matplotlib/examples/animation/histogram.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/histogram.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -7,7 +7,7 @@ import matplotlib.pyplot as plt import matplotlib.patches as patches import matplotlib.path as path -from animation import FuncAnimation +import matplotlib.animation as animation fig = plt.figure() ax = fig.add_subplot(111) @@ -58,5 +58,5 @@ verts[1::5,1] = top verts[2::5,1] = top -ani = FuncAnimation(fig, animate, 100, repeat=False) +ani = animation.FuncAnimation(fig, animate, 100, repeat=False) plt.show() Modified: trunk/matplotlib/examples/animation/random_data.py =================================================================== --- trunk/matplotlib/examples/animation/random_data.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/random_data.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -1,6 +1,6 @@ import numpy as np import matplotlib.pyplot as plt -from animation import FuncAnimation +import matplotlib.animation as animation fig = plt.figure() ax = fig.add_subplot(111) @@ -14,5 +14,5 @@ def data_gen(): while True: yield np.random.rand(10) -ani = FuncAnimation(fig, update, data_gen, interval=100) +ani = animation.FuncAnimation(fig, update, data_gen, interval=100) plt.show() Modified: trunk/matplotlib/examples/animation/simple_3danim.py =================================================================== --- trunk/matplotlib/examples/animation/simple_3danim.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/simple_3danim.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -4,9 +4,8 @@ import numpy as np import matplotlib.pyplot as plt import mpl_toolkits.mplot3d.axes3d as p3 +import matplotlib.animation as animation -from animation import FuncAnimation - def Gen_RandLine(length, dims=2) : """ Create a line using a random walk algorithm @@ -57,7 +56,7 @@ ax.set_title('3D Test') # Creating the Animation object -line_ani = FuncAnimation(fig, update_lines, 25, fargs=(data, lines), +line_ani = animation.FuncAnimation(fig, update_lines, 25, fargs=(data, lines), interval=50, blit=False) plt.show() Modified: trunk/matplotlib/examples/animation/simple_anim.py =================================================================== --- trunk/matplotlib/examples/animation/simple_anim.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/simple_anim.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -3,7 +3,7 @@ """ import numpy as np import matplotlib.pyplot as plt -from animation import FuncAnimation +import matplotlib.animation as animation fig = plt.figure() ax = fig.add_subplot(111) @@ -20,6 +20,6 @@ line.set_ydata(np.ma.array(x, mask=True)) return line, -ani = FuncAnimation(fig, animate, np.arange(1, 200), init_func=init, +ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init, interval=25, blit=True) plt.show() Modified: trunk/matplotlib/examples/animation/strip_chart_demo.py =================================================================== --- trunk/matplotlib/examples/animation/strip_chart_demo.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/strip_chart_demo.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -6,7 +6,7 @@ import numpy as np from matplotlib.lines import Line2D import matplotlib.pyplot as plt -from animation import FuncAnimation +import matplotlib.animation as animation class Scope: def __init__(self, ax, maxt=10, dt=0.01): @@ -45,5 +45,6 @@ fig = plt.figure() ax = fig.add_subplot(111) scope = Scope(ax) -ani = FuncAnimation(fig, scope.update, emitter, interval=10, blit=True) +ani = animation.FuncAnimation(fig, scope.update, emitter, interval=10, + blit=True) plt.show() Modified: trunk/matplotlib/examples/animation/subplots.py =================================================================== --- trunk/matplotlib/examples/animation/subplots.py 2010年08月26日 03:23:25 UTC (rev 8660) +++ trunk/matplotlib/examples/animation/subplots.py 2010年08月26日 03:30:38 UTC (rev 8661) @@ -1,14 +1,14 @@ import numpy as np import matplotlib.pyplot as plt from matplotlib.lines import Line2D -from animation import TimedAnimation +import matplotlib.animation as animation # This example uses subclassing, but there is no reason that the proper function # couldn't be set up and then use FuncAnimation. The code is long, but not # really complex. The length is due solely to the fact that there are a total # of 9 lines that need to be changed for the animation as well as 3 subplots # that need initial set up. -class SubplotAnimation(TimedAnimation): +class SubplotAnimation(animation.TimedAnimation): def __init__(self): fig = plt.figure() ax1 = fig.add_subplot(1, 2, 1) @@ -54,7 +54,7 @@ ax3.set_xlim(-1, 1) ax3.set_ylim(0, 800) - TimedAnimation.__init__(self, fig, interval=50, blit=True) + animation.TimedAnimation.__init__(self, fig, interval=50, blit=True) def _draw_frame(self, framedata): i = framedata This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 8660 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8660&view=rev Author: ryanmay Date: 2010年08月26日 03:23:25 +0000 (2010年8月26日) Log Message: ----------- Add previous animation examples ported to new framework, as well as a few new ones. Added Paths: ----------- trunk/matplotlib/examples/animation/ trunk/matplotlib/examples/animation/animate_decay.py trunk/matplotlib/examples/animation/dynamic_image.py trunk/matplotlib/examples/animation/dynamic_image2.py trunk/matplotlib/examples/animation/histogram.py trunk/matplotlib/examples/animation/random_data.py trunk/matplotlib/examples/animation/simple_3danim.py trunk/matplotlib/examples/animation/simple_anim.py trunk/matplotlib/examples/animation/strip_chart_demo.py trunk/matplotlib/examples/animation/subplots.py Added: trunk/matplotlib/examples/animation/animate_decay.py =================================================================== --- trunk/matplotlib/examples/animation/animate_decay.py (rev 0) +++ trunk/matplotlib/examples/animation/animate_decay.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,36 @@ +import numpy as np +import matplotlib.pyplot as plt +from animation import FuncAnimation + +def data_gen(): + t = data_gen.t + cnt = 0 + while cnt < 1000: + cnt+=1 + t += 0.05 + yield t, np.sin(2*np.pi*t) * np.exp(-t/10.) +data_gen.t = 0 + +fig = plt.figure() +ax = fig.add_subplot(111) +line, = ax.plot([], [], lw=2) +ax.set_ylim(-1.1, 1.1) +ax.set_xlim(0, 5) +ax.grid() +xdata, ydata = [], [] +def run(data): + # update the data + t,y = data + xdata.append(t) + ydata.append(y) + xmin, xmax = ax.get_xlim() + + if t >= xmax: + ax.set_xlim(xmin, 2*xmax) + ax.figure.canvas.draw() + line.set_data(xdata, ydata) + + return line, + +ani = FuncAnimation(fig, run, data_gen, blit=True, interval=10, repeat=False) +plt.show() Added: trunk/matplotlib/examples/animation/dynamic_image.py =================================================================== --- trunk/matplotlib/examples/animation/dynamic_image.py (rev 0) +++ trunk/matplotlib/examples/animation/dynamic_image.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,27 @@ +#!/usr/bin/env python +""" +An animated image +""" +import numpy as np +import matplotlib.pyplot as plt +from animation import FuncAnimation + +fig = plt.figure() + +def f(x, y): + return np.sin(x) + np.cos(y) + +x = np.linspace(0, 2 * np.pi, 120) +y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) + +im = plt.imshow(f(x, y), cmap=plt.get_cmap('jet')) + +def updatefig(*args): + global x,y + x += np.pi / 15. + y += np.pi / 20. + im.set_array(f(x,y)) + return im, + +ani = FuncAnimation(fig, updatefig, interval=50, blit=True) +plt.show() Added: trunk/matplotlib/examples/animation/dynamic_image2.py =================================================================== --- trunk/matplotlib/examples/animation/dynamic_image2.py (rev 0) +++ trunk/matplotlib/examples/animation/dynamic_image2.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,24 @@ +#!/usr/bin/env python +""" +An animated image +""" +import numpy as np +import matplotlib.pyplot as plt +from animation import ArtistAnimation + +fig = plt.figure() + +def f(x, y): + return np.sin(x) + np.cos(y) + +x = np.linspace(0, 2 * np.pi, 120) +y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) + +ims = [] +for i in range(60): + x += np.pi / 15. + y += np.pi / 20. + ims.append([plt.imshow(f(x, y), cmap=plt.get_cmap('jet'))]) + +ani = ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) +plt.show() Added: trunk/matplotlib/examples/animation/histogram.py =================================================================== --- trunk/matplotlib/examples/animation/histogram.py (rev 0) +++ trunk/matplotlib/examples/animation/histogram.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,62 @@ +""" +This example shows how to use a path patch to draw a bunch of +rectangles for an animated histogram +""" +import numpy as np + +import matplotlib.pyplot as plt +import matplotlib.patches as patches +import matplotlib.path as path +from animation import FuncAnimation + +fig = plt.figure() +ax = fig.add_subplot(111) + +# histogram our data with numpy +data = np.random.randn(1000) +n, bins = np.histogram(data, 100) + +# get the corners of the rectangles for the histogram +left = np.array(bins[:-1]) +right = np.array(bins[1:]) +bottom = np.zeros(len(left)) +top = bottom + n +nrects = len(left) + +# here comes the tricky part -- we have to set up the vertex and path +# codes arrays using moveto, lineto and closepoly + +# for each rect: 1 for the MOVETO, 3 for the LINETO, 1 for the +# CLOSEPOLY; the vert for the closepoly is ignored but we still need +# it to keep the codes aligned with the vertices +nverts = nrects*(1+3+1) +verts = np.zeros((nverts, 2)) +codes = np.ones(nverts, int) * path.Path.LINETO +codes[0::5] = path.Path.MOVETO +codes[4::5] = path.Path.CLOSEPOLY +verts[0::5,0] = left +verts[0::5,1] = bottom +verts[1::5,0] = left +verts[1::5,1] = top +verts[2::5,0] = right +verts[2::5,1] = top +verts[3::5,0] = right +verts[3::5,1] = bottom + +barpath = path.Path(verts, codes) +patch = patches.PathPatch(barpath, facecolor='green', edgecolor='yellow', alpha=0.5) +ax.add_patch(patch) + +ax.set_xlim(left[0], right[-1]) +ax.set_ylim(bottom.min(), top.max()) + +def animate(i): + # simulate new data coming in + data = np.random.randn(1000) + n, bins = np.histogram(data, 100) + top = bottom + n + verts[1::5,1] = top + verts[2::5,1] = top + +ani = FuncAnimation(fig, animate, 100, repeat=False) +plt.show() Added: trunk/matplotlib/examples/animation/random_data.py =================================================================== --- trunk/matplotlib/examples/animation/random_data.py (rev 0) +++ trunk/matplotlib/examples/animation/random_data.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,18 @@ +import numpy as np +import matplotlib.pyplot as plt +from animation import FuncAnimation + +fig = plt.figure() +ax = fig.add_subplot(111) +line, = ax.plot(np.random.rand(10)) +ax.set_ylim(0, 1) + +def update(data): + line.set_ydata(data) + return line, + +def data_gen(): + while True: yield np.random.rand(10) + +ani = FuncAnimation(fig, update, data_gen, interval=100) +plt.show() Added: trunk/matplotlib/examples/animation/simple_3danim.py =================================================================== --- trunk/matplotlib/examples/animation/simple_3danim.py (rev 0) +++ trunk/matplotlib/examples/animation/simple_3danim.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,63 @@ +""" +A simple example of an animated plot... In 3D! +""" +import numpy as np +import matplotlib.pyplot as plt +import mpl_toolkits.mplot3d.axes3d as p3 + +from animation import FuncAnimation + +def Gen_RandLine(length, dims=2) : + """ + Create a line using a random walk algorithm + + length is the number of points for the line. + dims is the number of dimensions the line has. + """ + lineData = np.empty((dims, length)) + lineData[:, 0] = np.random.rand(1, dims) + for index in xrange(1, length) : + # scaling the random numbers by 0.1 so + # movement is small compared to position. + # subtraction by 0.5 is to change the range to [-0.5, 0.5] + # to allow a line to move backwards. + step = ((np.random.rand(1, dims) - 0.5) * 0.1) + lineData[:, index] = lineData[:, index-1] + step + + return lineData + +def update_lines(num, dataLines, lines) : + for line, data in zip(lines, dataLines) : + # NOTE: there is no .set_data() for 3 dim data... + line.set_data(data[0:2, :num]) + line.set_3d_properties(data[2,:num]) + return lines + +# Attaching 3D axis to the figure +fig = plt.figure() +ax = p3.Axes3D(fig) + +# Fifty lines of random 3-D lines +data = [Gen_RandLine(25, 3) for index in xrange(50)] + +# Creating fifty line objects. +# NOTE: Can't pass empty arrays into 3d version of plot() +lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1])[0] for dat in data] + +# Setting the axes properties +ax.set_xlim3d([0.0, 1.0]) +ax.set_xlabel('X') + +ax.set_ylim3d([0.0, 1.0]) +ax.set_ylabel('Y') + +ax.set_zlim3d([0.0, 1.0]) +ax.set_zlabel('Z') + +ax.set_title('3D Test') + +# Creating the Animation object +line_ani = FuncAnimation(fig, update_lines, 25, fargs=(data, lines), + interval=50, blit=False) + +plt.show() Added: trunk/matplotlib/examples/animation/simple_anim.py =================================================================== --- trunk/matplotlib/examples/animation/simple_anim.py (rev 0) +++ trunk/matplotlib/examples/animation/simple_anim.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,25 @@ +""" +A simple example of an animated plot +""" +import numpy as np +import matplotlib.pyplot as plt +from animation import FuncAnimation + +fig = plt.figure() +ax = fig.add_subplot(111) + +x = np.arange(0, 2*np.pi, 0.01) # x-array +line, = ax.plot(x, np.sin(x)) + +def animate(i): + line.set_ydata(np.sin(x+i/10.0)) # update the data + return line, + +#Init only required for blitting to give a clean slate. +def init(): + line.set_ydata(np.ma.array(x, mask=True)) + return line, + +ani = FuncAnimation(fig, animate, np.arange(1, 200), init_func=init, + interval=25, blit=True) +plt.show() Added: trunk/matplotlib/examples/animation/strip_chart_demo.py =================================================================== --- trunk/matplotlib/examples/animation/strip_chart_demo.py (rev 0) +++ trunk/matplotlib/examples/animation/strip_chart_demo.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,49 @@ +""" +Emulate an oscilloscope. Requires the animation API introduced in +matplotlib 1.0 SVN. +""" +import matplotlib +import numpy as np +from matplotlib.lines import Line2D +import matplotlib.pyplot as plt +from animation import FuncAnimation + +class Scope: + def __init__(self, ax, maxt=10, dt=0.01): + self.ax = ax + self.dt = dt + self.maxt = maxt + self.tdata = [0] + self.ydata = [0] + self.line = Line2D(self.tdata, self.ydata) + self.ax.add_line(self.line) + self.ax.set_ylim(-.1, 1.1) + self.ax.set_xlim(0, self.maxt) + + def update(self, y): + lastt = self.tdata[-1] + if lastt > self.tdata[0] + self.maxt: # reset the arrays + self.tdata = [self.tdata[-1]] + self.ydata = [self.ydata[-1]] + self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt) + + t = self.tdata[-1] + self.dt + self.tdata.append(t) + self.ydata.append(y) + self.line.set_data(self.tdata, self.ydata) + return self.line, + +def emitter(p=0.01): + 'return a random value with probability p, else 0' + while True: + v = np.random.rand(1) + if v > p: + yield 0. + else: + yield np.random.rand(1) + +fig = plt.figure() +ax = fig.add_subplot(111) +scope = Scope(ax) +ani = FuncAnimation(fig, scope.update, emitter, interval=10, blit=True) +plt.show() Added: trunk/matplotlib/examples/animation/subplots.py =================================================================== --- trunk/matplotlib/examples/animation/subplots.py (rev 0) +++ trunk/matplotlib/examples/animation/subplots.py 2010年08月26日 03:23:25 UTC (rev 8660) @@ -0,0 +1,93 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.lines import Line2D +from animation import TimedAnimation + +# This example uses subclassing, but there is no reason that the proper function +# couldn't be set up and then use FuncAnimation. The code is long, but not +# really complex. The length is due solely to the fact that there are a total +# of 9 lines that need to be changed for the animation as well as 3 subplots +# that need initial set up. +class SubplotAnimation(TimedAnimation): + def __init__(self): + fig = plt.figure() + ax1 = fig.add_subplot(1, 2, 1) + ax2 = fig.add_subplot(2, 2, 2) + ax3 = fig.add_subplot(2, 2, 4) + + self.t = np.linspace(0, 80, 400) + self.x = np.cos(2 * np.pi * self.t / 10.) + self.y = np.sin(2 * np.pi * self.t / 10.) + self.z = 10 * self.t + + ax1.set_xlabel('x') + ax1.set_ylabel('y') + self.line1 = Line2D([], [], color='black') + self.line1a = Line2D([], [], color='red', linewidth=2) + self.line1e = Line2D([], [], color='red', marker='o', markeredgecolor='r') + ax1.add_line(self.line1) + ax1.add_line(self.line1a) + ax1.add_line(self.line1e) + ax1.set_xlim(-1, 1) + ax1.set_ylim(-2, 2) + ax1.set_aspect('equal', 'datalim') + + ax2.set_xlabel('y') + ax2.set_ylabel('z') + self.line2 = Line2D([], [], color='black') + self.line2a = Line2D([], [], color='red', linewidth=2) + self.line2e = Line2D([], [], color='red', marker='o', markeredgecolor='r') + ax2.add_line(self.line2) + ax2.add_line(self.line2a) + ax2.add_line(self.line2e) + ax2.set_xlim(-1, 1) + ax2.set_ylim(0, 800) + + ax3.set_xlabel('x') + ax3.set_ylabel('z') + self.line3 = Line2D([], [], color='black') + self.line3a = Line2D([], [], color='red', linewidth=2) + self.line3e = Line2D([], [], color='red', marker='o', markeredgecolor='r') + ax3.add_line(self.line3) + ax3.add_line(self.line3a) + ax3.add_line(self.line3e) + ax3.set_xlim(-1, 1) + ax3.set_ylim(0, 800) + + TimedAnimation.__init__(self, fig, interval=50, blit=True) + + def _draw_frame(self, framedata): + i = framedata + head = i - 1 + head_len = 10 + head_slice = (self.t > self.t[i] - 1.0) & (self.t < self.t[i]) + + self.line1.set_data(self.x[:i], self.y[:i]) + self.line1a.set_data(self.x[head_slice], self.y[head_slice]) + self.line1e.set_data(self.x[head], self.y[head]) + + self.line2.set_data(self.y[:i], self.z[:i]) + self.line2a.set_data(self.y[head_slice], self.z[head_slice]) + self.line2e.set_data(self.y[head], self.z[head]) + + self.line3.set_data(self.x[:i], self.z[:i]) + self.line3a.set_data(self.x[head_slice], self.z[head_slice]) + self.line3e.set_data(self.x[head], self.z[head]) + + self._drawn_artists = [self.line1, self.line1a, self.line1e, + self.line2, self.line2a, self.line2e, + self.line3, self.line3a, self.line3e] + + def new_frame_seq(self): + return iter(range(self.t.size)) + + def _init_draw(self): + lines = [self.line1, self.line1a, self.line1e, + self.line2, self.line2a, self.line2e, + self.line3, self.line3a, self.line3e] + for l in lines: + l.set_data([], []) + +ani = SubplotAnimation() +#ani.save('test_sub.mp4') +plt.show() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 8659 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8659&view=rev Author: ryanmay Date: 2010年08月26日 03:19:14 +0000 (2010年8月26日) Log Message: ----------- Move previous animation examples to make room for new ones. Added Paths: ----------- trunk/matplotlib/examples/old_animation/ Removed Paths: ------------- trunk/matplotlib/examples/animation/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 8658 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8658&view=rev Author: ryanmay Date: 2010年08月26日 03:11:42 +0000 (2010年8月26日) Log Message: ----------- Add new animation framework. Modified Paths: -------------- trunk/matplotlib/CHANGELOG Added Paths: ----------- trunk/matplotlib/lib/matplotlib/animation.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010年08月25日 22:13:56 UTC (rev 8657) +++ trunk/matplotlib/CHANGELOG 2010年08月26日 03:11:42 UTC (rev 8658) @@ -1,3 +1,5 @@ +2010年08月25日 Add new framework for doing animations with examples.- RM + 2010年08月21日 Remove unused and inappropriate methods from Tick classes: set_view_interval, get_minpos, and get_data_interval are properly found in the Axis class and don't need to be Added: trunk/matplotlib/lib/matplotlib/animation.py =================================================================== --- trunk/matplotlib/lib/matplotlib/animation.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/animation.py 2010年08月26日 03:11:42 UTC (rev 8658) @@ -0,0 +1,451 @@ +# TODO: +# * Loop Delay is broken on GTKAgg. This is because source_remove() is not +# working as we want. PyGTK bug? +# * Documentation -- this will need a new section of the User's Guide. +# Both for Animations and just timers. +# - Also need to update http://www.scipy.org/Cookbook/Matplotlib/Animations +# * Blit +# * Currently broken with Qt4 for widgets that don't start on screen +# * Still a few edge cases that aren't working correctly +# * Can this integrate better with existing matplotlib animation artist flag? +# * Example +# * Frameless animation - pure procedural with no loop +# * Need example that uses something like inotify or subprocess +# * Complex syncing examples +# * Movies +# * Library to make movies? +# * RC parameter for config? +# * Need to consider event sources to allow clicking through multiple figures +from datetime import datetime + +def traceme(func): + def wrapper(*args): + print '%s -- Calling: %s %s' % (datetime.now(), func.__name__, str(args)) + ret = func(*args) + print 'Returned: %s' % func.__name__ + return ret + return wrapper + +from matplotlib.cbook import iterable + +class Animation(object): + ''' + This class wraps the creation of an animation using matplotlib. It is + only a base class which should be subclassed to provide needed behavior. + + *fig* is the figure object that is used to get draw, resize, and any + other needed events. + + *event_source* is a class that can run a callback when desired events + are generated, as well as be stopped and started. Examples include timers + (see :class:`TimedAnimation`) and file system notifications. + + *blit* is a boolean that controls whether blitting is used to optimize + drawing. + ''' + def __init__(self, fig, event_source=None, blit=False): + self._fig = fig + self._blit = blit + + # These are the basics of the animation. The frame sequence represents + # information for each frame of the animation and depends on how the + # drawing is handled by the subclasses. The event source fires events + # that cause the frame sequence to be iterated. + self.frame_seq = self.new_frame_seq() + self.event_source = event_source + + # Clear the initial frame + self._init_draw() + + # Instead of starting the event source now, we connect to the figure's + # draw_event, so that we only start once the figure has been drawn. + self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start) + + # Connect to the figure's close_event so that we don't continue to + # fire events and try to draw to a deleted figure. + self._close_id = self._fig.canvas.mpl_connect('close_event', self._stop) + if blit: + self._setup_blit() + + def _start(self, *args): + ''' + Starts interactive animation. Adds the draw frame command to the GUI + handler, calls show to start the event loop. + ''' + # On start, we add our callback for stepping the animation and + # actually start the event_source. We also disconnect _start + # from the draw_events + self.event_source.add_callback(self._step) + self.event_source.start() + self._fig.canvas.mpl_disconnect(self._first_draw_id) + + def _stop(self, *args): + # On stop we disconnect all of our events. + if self._blit: + self._fig.canvas.mpl_disconnect(self._resize_id) + self._fig.canvas.mpl_disconnect(self._close_id) + self.event_source.remove_callback(self._step) + self.event_source = None + + def save(self, filename, fps=5, codec='mpeg4', clear_temp=True, + frame_prefix='_tmp'): + ''' + Saves a movie file by drawing every frame. + + *fps* is the frames per second in the movie + + *codec* is the codec to be used,if it is supported by the output method. + + *clear_temp* specifies whether the temporary image files should be + deleted. + + *frame_prefix* gives the prefix that should be used for individual + image files. This prefix will have a frame number (i.e. 0001) appended + when saving individual frames. + ''' + fnames = [] + # Create a new sequence of frames for saved data. This is different + # from new_frame_seq() to give the ability to save 'live' generated + # frame information to be saved later. + for idx,data in enumerate(self.new_saved_frame_seq()): + self._draw_next_frame(data, blit=False) + fname = '%s%04d.png' % (frame_prefix, idx) + fnames.append(fname) + self._fig.savefig(fname) + + self._make_movie(filename, fps, codec, frame_prefix) + + #Delete temporary files + if clear_temp: + import os + for fname in fnames: + os.remove(fname) + + def ffmpeg_cmd(self, fname, fps, codec, frame_prefix): + # Returns the command line parameters for subprocess to use + # ffmpeg to create a movie + return ['ffmpeg', '-y', '-r', str(fps), '-b', '1800k', '-i', + '%s%%04d.png' % frame_prefix, fname] + + def mencoder_cmd(self, fname, fps, codec, frame_prefix): + # Returns the command line parameters for subprocess to use + # mencoder to create a movie + return ['mencoder', 'mf://%s*.png' % frame_prefix, '-mf', + 'type=png:fps=%d' % fps, '-ovc', 'lavc', '-lavcopts', + 'vcodec=%s' % codec, '-oac', 'copy', '-o', fname] + + def _make_movie(self, fname, fps, codec, frame_prefix, cmd_gen=None): + # Uses subprocess to call the program for assembling frames into a + # movie file. *cmd_gen* is a callable that generates the sequence + # of command line arguments from a few configuration options. + from subprocess import Popen, PIPE + if cmd_gen is None: + cmd_gen = self.ffmpeg_cmd + proc = Popen(cmd_gen(fname, fps, codec, frame_prefix), shell=False, + stdout=PIPE, stderr=PIPE) + proc.wait() + + def _step(self, *args): + ''' + Handler for getting events. By default, gets the next frame in the + sequence and hands the data off to be drawn. + ''' + # Returns True to indicate that the event source should continue to + # call _step, until the frame sequence reaches the end of iteration, + # at which point False will be returned. + try: + framedata = self.frame_seq.next() + self._draw_next_frame(framedata, self._blit) + return True + except StopIteration: + return False + + def new_frame_seq(self): + 'Creates a new sequence of frame information.' + # Default implementation is just an iterator over self._framedata + return iter(self._framedata) + + def new_saved_frame_seq(self): + 'Creates a new sequence of saved/cached frame information.' + # Default is the same as the regular frame sequence + return self.new_frame_seq() + + def _draw_next_frame(self, framedata, blit): + # Breaks down the drawing of the next frame into steps of pre- and + # post- draw, as well as the drawing of the frame itself. + self._pre_draw(framedata, blit) + self._draw_frame(framedata) + self._post_draw(framedata, blit) + + def _init_draw(self): + # Initial draw to clear the frame. Also used by the blitting code + # when a clean base is required. + pass + + def _pre_draw(self, framedata, blit): + # Perform any cleaning or whatnot before the drawing of the frame. + # This default implementation allows blit to clear the frame. + if blit: + self._blit_clear(self._drawn_artists, self._blit_cache) + + def _draw_frame(self, framedata): + # Performs actual drawing of the frame. + raise NotImplementedError('Needs to be implemented by subclasses to' + ' actually make an animation.') + + def _post_draw(self, framedata, blit): + # After the frame is rendered, this handles the actual flushing of + # the draw, which can be a direct draw_idle() or make use of the + # blitting. + if blit and self._drawn_artists: + self._blit_draw(self._drawn_artists, self._blit_cache) + else: + self._fig.canvas.draw_idle() + + # The rest of the code in this class is to facilitate easy blitting + def _blit_draw(self, artists, bg_cache): + # Handles blitted drawing, which renders only the artists given instead + # of the entire figure. + updated_ax = [] + for a in artists: + # If we haven't cached the background for this axes object, do + # so now. This might not always be reliable, but it's an attempt + # to automate the process. + if a.axes not in bg_cache: + bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox) + a.axes.draw_artist(a) + updated_ax.append(a.axes) + + # After rendering all the needed artists, blit each axes individually. + for ax in set(updated_ax): + ax.figure.canvas.blit(ax.bbox) + + def _blit_clear(self, artists, bg_cache): + # Get a list of the axes that need clearing from the artists that + # have been drawn. Grab the appropriate saved background from the + # cache and restore. + axes = set(a.axes for a in artists) + for a in axes: + a.figure.canvas.restore_region(bg_cache[a]) + + def _setup_blit(self): + # Setting up the blit requires: a cache of the background for the + # axes + self._blit_cache = dict() + self._drawn_artists = [] + self._resize_id = self._fig.canvas.mpl_connect('resize_event', + self._handle_resize) + self._post_draw(None, self._blit) + + def _handle_resize(self, *args): + # On resize, we need to disable the resize event handling so we don't + # get too many events. Also stop the animation events, so that + # we're paused. Reset the cache and re-init. Set up an event handler + # to catch once the draw has actually taken place. + self._fig.canvas.mpl_disconnect(self._resize_id) + self.event_source.stop() + self._blit_cache.clear() + self._init_draw() + self._resize_id = self._fig.canvas.mpl_connect('draw_event', self._end_redraw) + + def _end_redraw(self, evt): + # Now that the redraw has happened, do the post draw flushing and + # blit handling. Then re-enable all of the original events. + self._post_draw(None, self._blit) + self.event_source.start() + self._fig.canvas.mpl_disconnect(self._resize_id) + self._resize_id = self._fig.canvas.mpl_connect('resize_event', + self._handle_resize) + + +class TimedAnimation(Animation): + ''' + :class:`Animation` subclass that supports time-based animation, drawing + a new frame every *interval* milliseconds. + + *repeat* controls whether the animation should repeat when the sequence + of frames is completed. + + *repeat_delay* optionally adds a delay in milliseconds before repeating + the animation. + ''' + def __init__(self, fig, interval=200, repeat_delay=None, repeat=True, + event_source=None, *args, **kwargs): + # Store the timing information + self._interval = interval + self._repeat_delay = repeat_delay + self.repeat = repeat + + # If we're not given an event source, create a new timer. This permits + # sharing timers between animation objects for syncing animations. + if event_source is None: + event_source = fig.canvas.new_timer() + event_source.interval = self._interval + + Animation.__init__(self, fig, event_source=event_source, *args, **kwargs) + + def _step(self, *args): + ''' + Handler for getting events. + ''' + # Extends the _step() method for the Animation class. If + # Animation._step signals that it reached the end and we want to repeat, + # we refresh the frame sequence and return True. If _repeat_delay is + # set, change the event_source's interval to our loop delay and set the + # callback to one which will then set the interval back. + still_going = Animation._step(self, *args) + if not still_going and self.repeat: + if self._repeat_delay: + self.event_source.remove_callback(self._step) + self.event_source.add_callback(self._loop_delay) + self.event_source.interval = self._repeat_delay + self.frame_seq = self.new_frame_seq() + return True + else: + return still_going + + def _stop(self, *args): + # If we stop in the middle of a loop delay (which is relatively likely + # given the potential pause here, remove the loop_delay callback as + # well. + self.event_source.remove_callback(self._loop_delay) + Animation._stop(self) + + def _loop_delay(self, *args): + # Reset the interval and change callbacks after the delay. + self.event_source.remove_callback(self._loop_delay) + self.event_source.interval = self._interval + self.event_source.add_callback(self._step) + + +class ArtistAnimation(TimedAnimation): + ''' + Before calling this function, all plotting should have taken place + and the relevant artists saved. + + frame_info is a list, with each list entry a collection of artists that + represent what needs to be enabled on each frame. These will be disabled + for other frames. + ''' + def __init__(self, fig, artists, *args, **kwargs): + # Internal list of artists drawn in the most recent frame. + self._drawn_artists = [] + + # Use the list of artists as the framedata, which will be iterated + # over by the machinery. + self._framedata = artists + TimedAnimation.__init__(self, fig, *args, **kwargs) + + def _init_draw(self): + # Make all the artists involved in *any* frame invisible + axes = [] + for f in self.new_frame_seq(): + for artist in f: + artist.set_visible(False) + # Assemble a list of unique axes that need flushing + if artist.axes not in axes: + axes.append(artist.axes) + + # Flush the needed axes + for ax in axes: + ax.figure.canvas.draw() + + def _pre_draw(self, framedata, blit): + ''' + Clears artists from the last frame. + ''' + if blit: + # Let blit handle clearing + self._blit_clear(self._drawn_artists, self._blit_cache) + else: + # Otherwise, make all the artists from the previous frame invisible + for artist in self._drawn_artists: + artist.set_visible(False) + + def _draw_frame(self, artists): + # Save the artists that were passed in as framedata for the other + # steps (esp. blitting) to use. + self._drawn_artists = artists + + # Make all the artists from the current frame visible + for artist in artists: + artist.set_visible(True) + +class FuncAnimation(TimedAnimation): + ''' + Makes an animation by repeatedly calling a function *func*, passing in + (optional) arguments in *fargs*. + + *frames* can be a generator, an iterable, or a number of frames. + + *init_func* is a function used to draw a clear frame. If not given, the + results of drawing from the first item in the frames sequence will be + used. + ''' + def __init__(self, fig, func, frames=None ,init_func=None, fargs=None, + save_count=None, **kwargs): + if fargs: + self._args = fargs + else: + self._args = () + self._func = func + + # Amount of framedata to keep around for saving movies. This is only + # used if we don't know how many frames there will be: in the case + # of no generator or in the case of a callable. + self.save_count = save_count + + # Set up a function that creates a new iterable when needed. If nothing + # is passed in for frames, just use itertools.count, which will just + # keep counting from 0. A callable passed in for frames is assumed to + # be a generator. An iterable will be used as is, and anything else + # will be treated as a number of frames. + if frames is None: + import itertools + self._iter_gen = itertools.count + elif callable(frames): + self._iter_gen = frames + elif iterable(frames): + self._iter_gen = lambda: iter(frames) + self.save_count = len(frames) + else: + self._iter_gen = lambda: iter(range(frames)) + self.save_count = frames + + # If we're passed in and using the default, set it to 100. + if self.save_count is None: + self.save_count = 100 + + self._init_func = init_func + self._save_seq = [] + + TimedAnimation.__init__(self, fig, **kwargs) + + def new_frame_seq(self): + # Use the generating function to generate a new frame sequence + return self._iter_gen() + + def new_saved_frame_seq(self): + # Generate an iterator for the sequence of saved data. + return iter(self._save_seq) + + def _init_draw(self): + # Initialize the drawing either using the given init_func or by + # calling the draw function with the first item of the frame sequence. + # For blitting, the init_func should return a sequence of modified + # artists. + if self._init_func is None: + self._draw_frame(self.new_frame_seq().next()) + else: + self._drawn_artists = self._init_func() + + def _draw_frame(self, framedata): + # Save the data for potential saving of movies. + self._save_seq.append(framedata) + + # Make sure to respect save_count (keep only the last save_count around) + self._save_seq = self._save_seq[-self.save_count:] + + # Call the func with framedata and args. If blitting is desired, + # func needs to return a sequence of any artists that were modified. + self._drawn_artists = self._func(framedata, *self._args) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.