def test_save_animation_smoketest(tmpdir, writer, extension): try: # for ImageMagick the rcparams must be patched to account for # 'convert' being a built in MS tool, not the imagemagick # tool. writer._init_from_registry() except AttributeError: pass if not animation.writers.is_available(writer): skip("writer '%s' not available on this system" % writer) fig, ax = plt.subplots() line, = ax.plot([], []) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) def init(): line.set_data([], []) return line, def animate(i): x = np.linspace(0, 10, 100) y = np.sin(x + i) line.set_data(x, y) return line, # Use temporary directory for the file-based writers, which produce a file # per frame with known names. with tmpdir.as_cwd(): anim = animation.FuncAnimation(fig, animate, init_func=init, frames=5) try: anim.save('movie.' + extension, fps=30, writer=writer, bitrate=500) except UnicodeDecodeError: xfail("There can be errors in the numpy import stack, " "see issues #1891 and #2679")
def test_save_animation_smoketest(writer, extension): try: # for ImageMagick the rcparams must be patched to account for # 'convert' being a built in MS tool, not the imagemagick # tool. writer._init_from_registry() except AttributeError: pass if not animation.writers.is_available(writer): skip("writer '%s' not available on this system" % writer) fig, ax = plt.subplots() line, = ax.plot([], []) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) def init(): line.set_data([], []) return line, def animate(i): x = np.linspace(0, 10, 100) y = np.sin(x + i) line.set_data(x, y) return line, # Use NamedTemporaryFile: will be automatically deleted F = tempfile.NamedTemporaryFile(suffix='.' + extension) F.close() anim = animation.FuncAnimation(fig, animate, init_func=init, frames=5) try: anim.save(F.name, fps=30, writer=writer, bitrate=500) except UnicodeDecodeError: xfail("There can be errors in the numpy import stack, " "see issues #1891 and #2679") finally: try: os.remove(F.name) except Exception: pass
def test_agg_filter(): def smooth1d(x, window_len): s = np.r_[2 * x[0] - x[window_len:1:-1], x, 2 * x[-1] - x[-1:-window_len:-1]] w = np.hanning(window_len) y = np.convolve(w / w.sum(), s, mode='same') return y[window_len - 1:-window_len + 1] def smooth2d(A, sigma=3): window_len = max(int(sigma), 3) * 2 + 1 A1 = np.array([smooth1d(x, window_len) for x in np.asarray(A)]) A2 = np.transpose(A1) A3 = np.array([smooth1d(x, window_len) for x in A2]) A4 = np.transpose(A3) return A4 class BaseFilter(object): def prepare_image(self, src_image, dpi, pad): ny, nx, depth = src_image.shape padded_src = np.zeros([pad * 2 + ny, pad * 2 + nx, depth], dtype="d") padded_src[pad:-pad, pad:-pad, :] = src_image[:, :, :] return padded_src # , tgt_image def get_pad(self, dpi): return 0 def __call__(self, im, dpi): pad = self.get_pad(dpi) padded_src = self.prepare_image(im, dpi, pad) tgt_image = self.process_image(padded_src, dpi) return tgt_image, -pad, -pad class OffsetFilter(BaseFilter): def __init__(self, offsets=None): if offsets is None: self.offsets = (0, 0) else: self.offsets = offsets def get_pad(self, dpi): return int(max(*self.offsets) / 72. * dpi) def process_image(self, padded_src, dpi): ox, oy = self.offsets a1 = np.roll(padded_src, int(ox / 72. * dpi), axis=1) a2 = np.roll(a1, -int(oy / 72. * dpi), axis=0) return a2 class GaussianFilter(BaseFilter): "simple gauss filter" def __init__(self, sigma, alpha=0.5, color=None): self.sigma = sigma self.alpha = alpha if color is None: self.color = (0, 0, 0) else: self.color = color def get_pad(self, dpi): return int(self.sigma * 3 / 72. * dpi) def process_image(self, padded_src, dpi): tgt_image = np.zeros_like(padded_src) aa = smooth2d(padded_src[:, :, -1] * self.alpha, self.sigma / 72. * dpi) tgt_image[:, :, -1] = aa tgt_image[:, :, :-1] = self.color return tgt_image class DropShadowFilter(BaseFilter): def __init__(self, sigma, alpha=0.3, color=None, offsets=None): self.gauss_filter = GaussianFilter(sigma, alpha, color) self.offset_filter = OffsetFilter(offsets) def get_pad(self, dpi): return max(self.gauss_filter.get_pad(dpi), self.offset_filter.get_pad(dpi)) def process_image(self, padded_src, dpi): t1 = self.gauss_filter.process_image(padded_src, dpi) t2 = self.offset_filter.process_image(t1, dpi) return t2 if V(np.__version__) < V('1.7.0'): skip('Disabled on Numpy < 1.7.0') fig = plt.figure() ax = fig.add_subplot(111) # draw lines l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-", mec="b", mfc="w", lw=5, mew=3, ms=10, label="Line 1") l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "ro-", mec="r", mfc="w", lw=5, mew=3, ms=10, label="Line 1") gauss = DropShadowFilter(4) for l in [l1, l2]: # draw shadows with same lines with slight offset. xx = l.get_xdata() yy = l.get_ydata() shadow, = ax.plot(xx, yy) shadow.update_from(l) # offset transform ot = mtransforms.offset_copy(l.get_transform(), ax.figure, x=4.0, y=-6.0, units='points') shadow.set_transform(ot) # adjust zorder of the shadow lines so that it is drawn below the # original lines shadow.set_zorder(l.get_zorder() - 0.5) shadow.set_agg_filter(gauss) shadow.set_rasterized(True) # to support mixed-mode renderers ax.set_xlim(0., 1.) ax.set_ylim(0., 1.) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False)
def test_agg_filter(): def smooth1d(x, window_len): s = np.r_[2*x[0] - x[window_len:1:-1], x, 2*x[-1] - x[-1:-window_len:-1]] w = np.hanning(window_len) y = np.convolve(w/w.sum(), s, mode='same') return y[window_len-1:-window_len+1] def smooth2d(A, sigma=3): window_len = max(int(sigma), 3)*2 + 1 A1 = np.array([smooth1d(x, window_len) for x in np.asarray(A)]) A2 = np.transpose(A1) A3 = np.array([smooth1d(x, window_len) for x in A2]) A4 = np.transpose(A3) return A4 class BaseFilter(object): def prepare_image(self, src_image, dpi, pad): ny, nx, depth = src_image.shape padded_src = np.zeros([pad*2 + ny, pad*2 + nx, depth], dtype="d") padded_src[pad:-pad, pad:-pad, :] = src_image[:, :, :] return padded_src # , tgt_image def get_pad(self, dpi): return 0 def __call__(self, im, dpi): pad = self.get_pad(dpi) padded_src = self.prepare_image(im, dpi, pad) tgt_image = self.process_image(padded_src, dpi) return tgt_image, -pad, -pad class OffsetFilter(BaseFilter): def __init__(self, offsets=None): if offsets is None: self.offsets = (0, 0) else: self.offsets = offsets def get_pad(self, dpi): return int(max(*self.offsets)/72.*dpi) def process_image(self, padded_src, dpi): ox, oy = self.offsets a1 = np.roll(padded_src, int(ox/72.*dpi), axis=1) a2 = np.roll(a1, -int(oy/72.*dpi), axis=0) return a2 class GaussianFilter(BaseFilter): "simple gauss filter" def __init__(self, sigma, alpha=0.5, color=None): self.sigma = sigma self.alpha = alpha if color is None: self.color = (0, 0, 0) else: self.color = color def get_pad(self, dpi): return int(self.sigma*3/72.*dpi) def process_image(self, padded_src, dpi): tgt_image = np.zeros_like(padded_src) aa = smooth2d(padded_src[:, :, -1]*self.alpha, self.sigma/72.*dpi) tgt_image[:, :, -1] = aa tgt_image[:, :, :-1] = self.color return tgt_image class DropShadowFilter(BaseFilter): def __init__(self, sigma, alpha=0.3, color=None, offsets=None): self.gauss_filter = GaussianFilter(sigma, alpha, color) self.offset_filter = OffsetFilter(offsets) def get_pad(self, dpi): return max(self.gauss_filter.get_pad(dpi), self.offset_filter.get_pad(dpi)) def process_image(self, padded_src, dpi): t1 = self.gauss_filter.process_image(padded_src, dpi) t2 = self.offset_filter.process_image(t1, dpi) return t2 if V(np.__version__) < V('1.7.0'): skip('Disabled on Numpy < 1.7.0') fig = plt.figure() ax = fig.add_subplot(111) # draw lines l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-", mec="b", mfc="w", lw=5, mew=3, ms=10, label="Line 1") l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "ro-", mec="r", mfc="w", lw=5, mew=3, ms=10, label="Line 1") gauss = DropShadowFilter(4) for l in [l1, l2]: # draw shadows with same lines with slight offset. xx = l.get_xdata() yy = l.get_ydata() shadow, = ax.plot(xx, yy) shadow.update_from(l) # offset transform ot = mtransforms.offset_copy(l.get_transform(), ax.figure, x=4.0, y=-6.0, units='points') shadow.set_transform(ot) # adjust zorder of the shadow lines so that it is drawn below the # original lines shadow.set_zorder(l.get_zorder() - 0.5) shadow.set_agg_filter(gauss) shadow.set_rasterized(True) # to support mixed-mode renderers ax.set_xlim(0., 1.) ax.set_ylim(0., 1.) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False)