Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2113578

Browse files
committed
Cleanup demo_agg_filter.
1 parent 2cc5d8d commit 2113578

File tree

2 files changed

+75
-129
lines changed

2 files changed

+75
-129
lines changed

examples/misc/demo_agg_filter.py

Lines changed: 46 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -4,97 +4,82 @@
44
===============
55
66
"""
7-
import matplotlib.pyplot as plt
87

9-
import numpy as np
108
import matplotlib.cm as cm
9+
import matplotlib.pyplot as plt
1110
import matplotlib.transforms as mtransforms
1211
from matplotlib.colors import LightSource
1312
from matplotlib.artist import Artist
13+
import numpy as np
1414

1515

1616
def smooth1d(x, window_len):
1717
# copied from http://www.scipy.org/Cookbook/SignalSmooth
18-
1918
s = np.r_[2*x[0] - x[window_len:1:-1], x, 2*x[-1] - x[-1:-window_len:-1]]
2019
w = np.hanning(window_len)
2120
y = np.convolve(w/w.sum(), s, mode='same')
2221
return y[window_len-1:-window_len+1]
2322

2423

2524
def smooth2d(A, sigma=3):
26-
27-
window_len = max(int(sigma), 3)*2 + 1
28-
A1 = np.array([smooth1d(x, window_len) for x in np.asarray(A)])
29-
A2 = np.transpose(A1)
30-
A3 = np.array([smooth1d(x, window_len) for x in A2])
31-
A4 = np.transpose(A3)
32-
33-
return A4
25+
window_len = max(int(sigma), 3) * 2 + 1
26+
A = np.apply_along_axis(smooth1d, 0, A, window_len)
27+
A = np.apply_along_axis(smooth1d, 1, A, window_len)
28+
return A
3429

3530

3631
class BaseFilter:
37-
def prepare_image(self, src_image, dpi, pad):
38-
ny, nx, depth = src_image.shape
39-
# tgt_image = np.zeros([pad*2+ny, pad*2+nx, depth], dtype="d")
40-
padded_src = np.zeros([pad*2 + ny, pad*2 + nx, depth], dtype="d")
41-
padded_src[pad:-pad, pad:-pad, :] = src_image[:, :, :]
42-
43-
return padded_src # , tgt_image
4432

4533
def get_pad(self, dpi):
4634
return 0
4735

36+
def process_image(padded_src, dpi):
37+
raise NotImplementedError("Should be overridden by subclasses")
38+
4839
def __call__(self, im, dpi):
4940
pad = self.get_pad(dpi)
50-
padded_src = self.prepare_image(im, dpi, pad)
41+
padded_src = np.pad(im, [(pad, pad), (pad, pad), (0, 0)], "constant")
5142
tgt_image = self.process_image(padded_src, dpi)
5243
return tgt_image, -pad, -pad
5344

5445

5546
class OffsetFilter(BaseFilter):
56-
def __init__(self, offsets=None):
57-
if offsets is None:
58-
self.offsets = (0, 0)
59-
else:
60-
self.offsets = offsets
47+
48+
def __init__(self, offsets=(0, 0)):
49+
self.offsets = offsets
6150

6251
def get_pad(self, dpi):
63-
return int(max(*self.offsets)/72.*dpi)
52+
return int(max(self.offsets) / 72 * dpi)
6453

6554
def process_image(self, padded_src, dpi):
6655
ox, oy = self.offsets
67-
a1 = np.roll(padded_src, int(ox/72.*dpi), axis=1)
68-
a2 = np.roll(a1, -int(oy/72.*dpi), axis=0)
56+
a1 = np.roll(padded_src, int(ox / 72 * dpi), axis=1)
57+
a2 = np.roll(a1, -int(oy / 72 * dpi), axis=0)
6958
return a2
7059

7160

7261
class GaussianFilter(BaseFilter):
73-
"simple gauss filter"
62+
"""Simple Gaussian filter."""
7463

75-
def __init__(self, sigma, alpha=0.5, color=None):
64+
def __init__(self, sigma, alpha=0.5, color=(0, 0, 0)):
7665
self.sigma = sigma
7766
self.alpha = alpha
78-
if color is None:
79-
self.color = (0, 0, 0)
80-
else:
81-
self.color = color
67+
self.color = color
8268

8369
def get_pad(self, dpi):
84-
return int(self.sigma*3/72.*dpi)
70+
return int(self.sigma*3 / 72 * dpi)
8571

8672
def process_image(self, padded_src, dpi):
87-
# offsetx, offsety = int(self.offsets[0]), int(self.offsets[1])
88-
tgt_image = np.zeros_like(padded_src)
89-
aa = smooth2d(padded_src[:, :, -1]*self.alpha,
90-
self.sigma/72.*dpi)
91-
tgt_image[:, :, -1] = aa
92-
tgt_image[:, :, :-1] = self.color
73+
tgt_image = np.empty_like(padded_src)
74+
tgt_image[:, :, :3] = self.color
75+
tgt_image[:, :, 3] = smooth2d(padded_src[:, :, 3] * self.alpha,
76+
self.sigma / 72 * dpi)
9377
return tgt_image
9478

9579

9680
class DropShadowFilter(BaseFilter):
97-
def __init__(self, sigma, alpha=0.3, color=None, offsets=None):
81+
82+
def __init__(self, sigma, alpha=0.3, color=(0, 0, 0), offsets=(0, 0)):
9883
self.gauss_filter = GaussianFilter(sigma, alpha, color)
9984
self.offset_filter = OffsetFilter(offsets)
10085

@@ -109,7 +94,6 @@ def process_image(self, padded_src, dpi):
10994

11095

11196
class LightFilter(BaseFilter):
112-
"simple gauss filter"
11397

11498
def __init__(self, sigma, fraction=0.5):
11599
self.gauss_filter = GaussianFilter(sigma, alpha=1)
@@ -123,47 +107,36 @@ def process_image(self, padded_src, dpi):
123107
t1 = self.gauss_filter.process_image(padded_src, dpi)
124108
elevation = t1[:, :, 3]
125109
rgb = padded_src[:, :, :3]
126-
110+
alpha = padded_src[:, :, 3:]
127111
rgb2 = self.light_source.shade_rgb(rgb, elevation,
128112
fraction=self.fraction)
129-
130-
tgt = np.empty_like(padded_src)
131-
tgt[:, :, :3] = rgb2
132-
tgt[:, :, 3] = padded_src[:, :, 3]
133-
134-
return tgt
113+
return np.concatenate([rgb2, alpha], -1)
135114

136115

137116
class GrowFilter(BaseFilter):
138-
"enlarge the area"
117+
"""Enlarge the area."""
139118

140-
def __init__(self, pixels, color=None):
119+
def __init__(self, pixels, color=(1, 1, 1)):
141120
self.pixels = pixels
142-
if color is None:
143-
self.color = (1, 1, 1)
144-
else:
145-
self.color = color
121+
self.color = color
146122

147123
def __call__(self, im, dpi):
148-
ny, nx, depth = im.shape
149-
alpha = np.pad(im[..., -1], self.pixels, "constant")
150-
alpha2 = np.clip(smooth2d(alpha, self.pixels/72.*dpi) * 5, 0, 1)
124+
alpha = np.pad(im[..., 3], self.pixels, "constant")
125+
alpha2 = np.clip(smooth2d(alpha, self.pixels / 72 * dpi) * 5, 0, 1)
151126
new_im = np.empty((*alpha2.shape, 4))
152-
new_im[:, :, -1] = alpha2
153-
new_im[:, :, :-1] = self.color
127+
new_im[:, :, :3] = self.color
128+
new_im[:, :, 3] = alpha2
154129
offsetx, offsety = -self.pixels, -self.pixels
155130
return new_im, offsetx, offsety
156131

157132

158133
class FilteredArtistList(Artist):
159-
"""
160-
A simple container to draw filtered artist.
161-
"""
134+
"""A simple container to filter multiple artists at once."""
162135

163136
def __init__(self, artist_list, filter):
137+
super().__init__()
164138
self._artist_list = artist_list
165139
self._filter = filter
166-
Artist.__init__(self)
167140

168141
def draw(self, renderer):
169142
renderer.start_rasterizing()
@@ -188,15 +161,13 @@ def filtered_text(ax):
188161

189162
# draw
190163
ax.imshow(Z, interpolation='bilinear', origin='lower',
191-
cmap=cm.gray, extent=(-3, 3, -2, 2))
164+
cmap=cm.gray, extent=(-3, 3, -2, 2), aspect='auto')
192165
levels = np.arange(-1.2, 1.6, 0.2)
193166
CS = ax.contour(Z, levels,
194167
origin='lower',
195168
linewidths=2,
196169
extent=(-3, 3, -2, 2))
197170

198-
ax.set_aspect("auto")
199-
200171
# contour label
201172
cl = ax.clabel(CS, levels[1::2], # label every second level
202173
inline=1,
@@ -223,17 +194,14 @@ def drop_shadow_line(ax):
223194
# copied from examples/misc/svg_filter_line.py
224195

225196
# draw lines
226-
l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-",
227-
mec="b", mfc="w", lw=5, mew=3, ms=10, label="Line 1")
228-
l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "ro-",
229-
mec="r", mfc="w", lw=5, mew=3, ms=10, label="Line 1")
197+
l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-")
198+
l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "ro-")
230199

231200
gauss = DropShadowFilter(4)
232201

233202
for l in [l1, l2]:
234203

235204
# draw shadows with same lines with slight offset.
236-
237205
xx = l.get_xdata()
238206
yy = l.get_ydata()
239207
shadow, = ax.plot(xx, yy)
@@ -288,7 +256,6 @@ def light_filter_pie(ax):
288256
fracs = [15, 30, 45, 10]
289257
explode = (0, 0.05, 0, 0)
290258
pies = ax.pie(fracs, explode=explode)
291-
ax.patch.set_visible(True)
292259

293260
light_filter = LightFilter(9)
294261
for p in pies[0]:
@@ -305,21 +272,12 @@ def light_filter_pie(ax):
305272

306273
if __name__ == "__main__":
307274

308-
plt.figure(figsize=(6, 6))
309-
plt.subplots_adjust(left=0.05, right=0.95)
310-
311-
ax = plt.subplot(221)
312-
filtered_text(ax)
313-
314-
ax = plt.subplot(222)
315-
drop_shadow_line(ax)
316-
317-
ax = plt.subplot(223)
318-
drop_shadow_patches(ax)
275+
fix, axs = plt.subplots(2, 2)
319276

320-
ax = plt.subplot(224)
321-
ax.set_aspect(1)
322-
light_filter_pie(ax)
323-
ax.set_frame_on(True)
277+
filtered_text(axs[0, 0])
278+
drop_shadow_line(axs[0, 1])
279+
drop_shadow_patches(axs[1, 0])
280+
light_filter_pie(axs[1, 1])
281+
axs[1, 1].set_frame_on(True)
324282

325283
plt.show()

lib/matplotlib/tests/test_agg.py

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -81,79 +81,69 @@ def test_long_path():
8181
@image_comparison(['agg_filter.png'], remove_text=True)
8282
def test_agg_filter():
8383
def smooth1d(x, window_len):
84-
s = np.r_[2*x[0] - x[window_len:1:-1],
85-
x,
86-
2*x[-1] - x[-1:-window_len:-1]]
84+
# copied from http://www.scipy.org/Cookbook/SignalSmooth
85+
s = np.r_[
86+
2*x[0] - x[window_len:1:-1], x, 2*x[-1] - x[-1:-window_len:-1]]
8787
w = np.hanning(window_len)
8888
y = np.convolve(w/w.sum(), s, mode='same')
8989
return y[window_len-1:-window_len+1]
9090

9191
def smooth2d(A, sigma=3):
92-
window_len = max(int(sigma), 3)*2 + 1
93-
A1 = np.array([smooth1d(x, window_len) for x in np.asarray(A)])
94-
A2 = np.transpose(A1)
95-
A3 = np.array([smooth1d(x, window_len) for x in A2])
96-
A4 = np.transpose(A3)
97-
98-
return A4
92+
window_len = max(int(sigma), 3) * 2 + 1
93+
A = np.apply_along_axis(smooth1d, 0, A, window_len)
94+
A = np.apply_along_axis(smooth1d, 1, A, window_len)
95+
return A
9996

10097
class BaseFilter:
101-
def prepare_image(self, src_image, dpi, pad):
102-
ny, nx, depth = src_image.shape
103-
padded_src = np.zeros([pad*2 + ny, pad*2 + nx, depth], dtype="d")
104-
padded_src[pad:-pad, pad:-pad, :] = src_image[:, :, :]
105-
106-
return padded_src # , tgt_image
10798

10899
def get_pad(self, dpi):
109100
return 0
110101

102+
def process_image(padded_src, dpi):
103+
raise NotImplementedError("Should be overridden by subclasses")
104+
111105
def __call__(self, im, dpi):
112106
pad = self.get_pad(dpi)
113-
padded_src = self.prepare_image(im, dpi, pad)
107+
padded_src = np.pad(im, [(pad, pad), (pad, pad), (0, 0)],
108+
"constant")
114109
tgt_image = self.process_image(padded_src, dpi)
115110
return tgt_image, -pad, -pad
116111

117112
class OffsetFilter(BaseFilter):
118-
def __init__(self, offsets=None):
119-
if offsets is None:
120-
self.offsets = (0, 0)
121-
else:
122-
self.offsets = offsets
113+
114+
def __init__(self, offsets=(0, 0)):
115+
self.offsets = offsets
123116

124117
def get_pad(self, dpi):
125-
return int(max(*self.offsets)/72.*dpi)
118+
return int(max(self.offsets) / 72 * dpi)
126119

127120
def process_image(self, padded_src, dpi):
128121
ox, oy = self.offsets
129-
a1 = np.roll(padded_src, int(ox/72.*dpi), axis=1)
130-
a2 = np.roll(a1, -int(oy/72.*dpi), axis=0)
122+
a1 = np.roll(padded_src, int(ox / 72 * dpi), axis=1)
123+
a2 = np.roll(a1, -int(oy / 72 * dpi), axis=0)
131124
return a2
132125

133126
class GaussianFilter(BaseFilter):
134-
"simple gauss filter"
127+
"""Simple Gaussian filter."""
135128

136-
def __init__(self, sigma, alpha=0.5, color=None):
129+
def __init__(self, sigma, alpha=0.5, color=(0, 0, 0)):
137130
self.sigma = sigma
138131
self.alpha = alpha
139-
if color is None:
140-
self.color = (0, 0, 0)
141-
else:
142-
self.color = color
132+
self.color = color
143133

144134
def get_pad(self, dpi):
145-
return int(self.sigma*3/72.*dpi)
135+
return int(self.sigma*3 / 72 * dpi)
146136

147137
def process_image(self, padded_src, dpi):
148-
tgt_image = np.zeros_like(padded_src)
149-
aa = smooth2d(padded_src[:, :, -1]*self.alpha,
150-
self.sigma/72.*dpi)
151-
tgt_image[:, :, -1] = aa
152-
tgt_image[:, :, :-1] = self.color
138+
tgt_image = np.empty_like(padded_src)
139+
tgt_image[:, :, :3] = self.color
140+
tgt_image[:, :, 3] = smooth2d(padded_src[:, :, 3] * self.alpha,
141+
self.sigma / 72 * dpi)
153142
return tgt_image
154143

155144
class DropShadowFilter(BaseFilter):
156-
def __init__(self, sigma, alpha=0.3, color=None, offsets=None):
145+
146+
def __init__(self, sigma, alpha=0.3, color=(0, 0, 0), offsets=(0, 0)):
157147
self.gauss_filter = GaussianFilter(sigma, alpha, color)
158148
self.offset_filter = OffsetFilter(offsets)
159149

@@ -166,8 +156,7 @@ def process_image(self, padded_src, dpi):
166156
t2 = self.offset_filter.process_image(t1, dpi)
167157
return t2
168158

169-
fig = plt.figure()
170-
ax = fig.add_subplot(111)
159+
fig, ax = plt.subplots()
171160

172161
# draw lines
173162
l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-",
@@ -180,7 +169,6 @@ def process_image(self, padded_src, dpi):
180169
for l in [l1, l2]:
181170

182171
# draw shadows with same lines with slight offset.
183-
184172
xx = l.get_xdata()
185173
yy = l.get_ydata()
186174
shadow, = ax.plot(xx, yy)

0 commit comments

Comments
 (0)