.. _sphx_glr_gallery_misc_demo_agg_filter.py: =============== Demo Agg Filter =============== .. image:: /gallery/misc/images/sphx_glr_demo_agg_filter_001.png :align: center .. code-block:: python import matplotlib.pyplot as plt import numpy as np import matplotlib.cm as cm import matplotlib.mlab as mlab import matplotlib.transforms as mtransforms from matplotlib.colors import LightSource from matplotlib.artist import Artist def smooth1d(x, window_len): # copied from http://www.scipy.org/Cookbook/SignalSmooth 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 # tgt_image = np.zeros([pad*2+ny, pad*2+nx, depth], dtype="d") 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): # offsetx, offsety = int(self.offsets[0]), int(self.offsets[1]) 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 class LightFilter(BaseFilter): "simple gauss filter" def __init__(self, sigma, fraction=0.5): self.gauss_filter = GaussianFilter(sigma, alpha=1) self.light_source = LightSource() self.fraction = fraction def get_pad(self, dpi): return self.gauss_filter.get_pad(dpi) def process_image(self, padded_src, dpi): t1 = self.gauss_filter.process_image(padded_src, dpi) elevation = t1[:, :, 3] rgb = padded_src[:, :, :3] rgb2 = self.light_source.shade_rgb(rgb, elevation, fraction=self.fraction) tgt = np.empty_like(padded_src) tgt[:, :, :3] = rgb2 tgt[:, :, 3] = padded_src[:, :, 3] return tgt class GrowFilter(BaseFilter): "enlarge the area" def __init__(self, pixels, color=None): self.pixels = pixels if color is None: self.color = (1, 1, 1) else: self.color = color def __call__(self, im, dpi): pad = self.pixels ny, nx, depth = im.shape new_im = np.empty([pad*2 + ny, pad*2 + nx, depth], dtype="d") alpha = new_im[:, :, 3] alpha.fill(0) alpha[pad:-pad, pad:-pad] = im[:, :, -1] alpha2 = np.clip(smooth2d(alpha, self.pixels/72.*dpi) * 5, 0, 1) new_im[:, :, -1] = alpha2 new_im[:, :, :-1] = self.color offsetx, offsety = -pad, -pad return new_im, offsetx, offsety class FilteredArtistList(Artist): """ A simple container to draw filtered artist. """ def __init__(self, artist_list, filter): self._artist_list = artist_list self._filter = filter Artist.__init__(self) def draw(self, renderer): renderer.start_rasterizing() renderer.start_filter() for a in self._artist_list: a.draw(renderer) renderer.stop_filter(self._filter) renderer.stop_rasterizing() def filtered_text(ax): # mostly copied from contour_demo.py # prepare image delta = 0.025 x = np.arange(-3.0, 3.0, delta) y = np.arange(-2.0, 2.0, delta) X, Y = np.meshgrid(x, y) Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) # difference of Gaussians Z = 10.0 * (Z2 - Z1) # draw im = ax.imshow(Z, interpolation='bilinear', origin='lower', cmap=cm.gray, extent=(-3, 3, -2, 2)) levels = np.arange(-1.2, 1.6, 0.2) CS = ax.contour(Z, levels, origin='lower', linewidths=2, extent=(-3, 3, -2, 2)) ax.set_aspect("auto") # contour label cl = ax.clabel(CS, levels[1::2], # label every second level inline=1, fmt='%1.1f', fontsize=11) # change clable color to black from matplotlib.patheffects import Normal for t in cl: t.set_color("k") # to force TextPath (i.e., same font in all backends) t.set_path_effects([Normal()]) # Add white glows to improve visibility of labels. white_glows = FilteredArtistList(cl, GrowFilter(3)) ax.add_artist(white_glows) white_glows.set_zorder(cl[0].get_zorder() - 0.1) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) def drop_shadow_line(ax): # copied from examples/misc/svg_filter_line.py # 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 drop_shadow_patches(ax): # Copied from barchart_demo.py N = 5 menMeans = (20, 35, 30, 35, 27) ind = np.arange(N) # the x locations for the groups width = 0.35 # the width of the bars rects1 = ax.bar(ind, menMeans, width, color='r', ec="w", lw=2) womenMeans = (25, 32, 34, 20, 25) rects2 = ax.bar(ind + width + 0.1, womenMeans, width, color='y', ec="w", lw=2) # gauss = GaussianFilter(1.5, offsets=(1,1), ) gauss = DropShadowFilter(5, offsets=(1, 1), ) shadow = FilteredArtistList(rects1 + rects2, gauss) ax.add_artist(shadow) shadow.set_zorder(rects1[0].get_zorder() - 0.1) ax.set_ylim(0, 40) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) def light_filter_pie(ax): fracs = [15, 30, 45, 10] explode = (0, 0.05, 0, 0) pies = ax.pie(fracs, explode=explode) ax.patch.set_visible(True) light_filter = LightFilter(9) for p in pies[0]: p.set_agg_filter(light_filter) p.set_rasterized(True) # to support mixed-mode renderers p.set(ec="none", lw=2) gauss = DropShadowFilter(9, offsets=(3, 4), alpha=0.7) shadow = FilteredArtistList(pies[0], gauss) ax.add_artist(shadow) shadow.set_zorder(pies[0][0].get_zorder() - 0.1) if 1: plt.figure(1, figsize=(6, 6)) plt.subplots_adjust(left=0.05, right=0.95) ax = plt.subplot(221) filtered_text(ax) ax = plt.subplot(222) drop_shadow_line(ax) ax = plt.subplot(223) drop_shadow_patches(ax) ax = plt.subplot(224) ax.set_aspect(1) light_filter_pie(ax) ax.set_frame_on(True) plt.show() **Total running time of the script:** ( 0 minutes 0.206 seconds) .. only :: html .. container:: sphx-glr-footer .. container:: sphx-glr-download :download:`Download Python source code: demo_agg_filter.py ` .. container:: sphx-glr-download :download:`Download Jupyter notebook: demo_agg_filter.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_