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

Skip to content

Commit b6e9ae7

Browse files
committed
Significant speed improvement in text layout. Reverted to fix bug in
ticklabels. Lots of other minor things. svn path=/branches/transforms/; revision=3947
1 parent 08610fc commit b6e9ae7

7 files changed

Lines changed: 138 additions & 129 deletions

File tree

lib/matplotlib/axes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ def add_artist(self, a):
10371037
a.set_axes(self)
10381038
self.artists.append(a)
10391039
self._set_artist_props(a)
1040+
a.set_clip_path(self.axesPatch)
10401041
a._remove_method = lambda h: self.artists.remove(h)
10411042

10421043
def add_collection(self, collection, autolim=False):
@@ -1091,6 +1092,7 @@ def add_table(self, tab):
10911092
'Add a table instance to the list of axes tables'
10921093
self._set_artist_props(tab)
10931094
self.tables.append(tab)
1095+
tab.set_clip_path(self.axesPatch)
10941096
tab._remove_method = lambda h: self.tables.remove(h)
10951097

10961098
def relim(self):

lib/matplotlib/axis.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ def __init__(self, axes, loc, label,
9191
self._size = size
9292

9393
self._padPixels = self.figure.dpi * self._pad * (1/72.0)
94-
self._locTransform = Affine2D()
9594

9695
self.tick1line = self._get_tick1line()
9796
self.tick2line = self._get_tick2line()
@@ -286,7 +285,7 @@ def _get_tick2line(self):
286285
markersize=self._size,
287286
)
288287

289-
l.set_transform(self._locTransform + self.axes.get_xaxis_transform())
288+
l.set_transform(self.axes.get_xaxis_transform())
290289
self._set_artist_props(l)
291290
return l
292291

@@ -298,16 +297,20 @@ def _get_gridline(self):
298297
linestyle=rcParams['grid.linestyle'],
299298
linewidth=rcParams['grid.linewidth'],
300299
)
301-
l.set_transform(self._locTransform + self.axes.get_xaxis_transform())
300+
l.set_transform(self.axes.get_xaxis_transform())
302301
self._set_artist_props(l)
303302

304303
return l
305304

306305
def update_position(self, loc):
307306
'Set the location of tick in data coords with scalar loc'
308-
self._locTransform.clear().translate(loc, 0.0)
309-
self.label1.set_x(loc)
310-
self.label2.set_x(loc)
307+
x = loc
308+
309+
self.tick1line.set_xdata((x,))
310+
self.tick2line.set_xdata((x,))
311+
self.gridline.set_xdata((x, ))
312+
self.label1.set_x(x)
313+
self.label2.set_x(x)
311314
self._loc = loc
312315

313316
def get_view_interval(self):
@@ -385,7 +388,7 @@ def _get_tick1line(self):
385388
linestyle = 'None',
386389
markersize=self._size,
387390
)
388-
l.set_transform(self._locTransform + self.axes.get_yaxis_transform())
391+
l.set_transform(self.axes.get_yaxis_transform())
389392
self._set_artist_props(l)
390393
return l
391394

@@ -398,7 +401,7 @@ def _get_tick2line(self):
398401
markersize=self._size,
399402
)
400403

401-
l.set_transform(self._locTransform + self.axes.get_yaxis_transform())
404+
l.set_transform(self.axes.get_yaxis_transform())
402405
self._set_artist_props(l)
403406
return l
404407

@@ -411,19 +414,24 @@ def _get_gridline(self):
411414
linewidth=rcParams['grid.linewidth'],
412415
)
413416

414-
l.set_transform(self._locTransform + self.axes.get_yaxis_transform())
417+
l.set_transform(self.axes.get_yaxis_transform())
415418
self._set_artist_props(l)
416419
return l
417420

418421

419422
def update_position(self, loc):
420423
'Set the location of tick in data coords with scalar loc'
421-
self._locTransform.clear().translate(0.0, loc)
422-
self.label1.set_y(loc)
423-
self.label2.set_y(loc)
424-
self._loc = loc
424+
y = loc
425+
self.tick1line.set_ydata((y,))
426+
self.tick2line.set_ydata((y,))
427+
self.gridline.set_ydata((y, ))
425428

429+
self.label1.set_y( y )
430+
self.label2.set_y( y )
426431

432+
self._loc = loc
433+
434+
427435
def get_view_interval(self):
428436
'return the Interval instance for this axis view limits'
429437
return self.axes.viewLim.intervaly
@@ -751,7 +759,7 @@ def get_minor_ticks(self, numticks=None):
751759
if len(self.minorTicks) < numticks:
752760
# update the new tick label properties from the old
753761
for i in range(numticks - len(self.minorTicks)):
754-
tick = self._get_tick(minor=True)
762+
tick = self._get_tick(major=False)
755763
self.minorTicks.append(tick)
756764

757765
if self._lastNumMinorTicks < numticks:

lib/matplotlib/collections.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Collection(artist.Artist, cm.ScalarMappable):
4343
linewidths=None,
4444
antialiaseds = None,
4545
offsets = None,
46-
transOffset = transforms.identity_transform(),
46+
transOffset = transforms.IdentityTransform(),
4747
norm = None, # optional for cm.ScalarMappable
4848
cmap = None, # ditto
4949
@@ -376,7 +376,7 @@ def update_scalarmappable(self):
376376
linewidths=None,
377377
antialiaseds = None,
378378
offsets = None,
379-
transOffset = transforms.identity_transform(),
379+
transOffset = transforms.IdentityTransform(),
380380
norm = None, # optional for cm.ScalarMappable
381381
cmap = None, # ditto
382382

lib/matplotlib/lines.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,10 @@ def draw(self, renderer):
455455
gc.set_capstyle(cap)
456456

457457
funcname = self._lineStyles.get(self._linestyle, '_draw_nothing')
458-
lineFunc = getattr(self, funcname)
459-
lineFunc(renderer, gc, *self._transformed_path.get_transformed_path_and_affine())
458+
if funcname != '_draw_nothing':
459+
tpath, affine = self._transformed_path.get_transformed_path_and_affine()
460+
lineFunc = getattr(self, funcname)
461+
lineFunc(renderer, gc, tpath, affine)
460462

461463
if self._marker is not None:
462464
gc = renderer.new_gc()
@@ -465,8 +467,10 @@ def draw(self, renderer):
465467
gc.set_linewidth(self._markeredgewidth)
466468
gc.set_alpha(self._alpha)
467469
funcname = self._markers.get(self._marker, '_draw_nothing')
468-
markerFunc = getattr(self, funcname)
469-
markerFunc(renderer, gc, *self._transformed_path.get_transformed_path_and_affine())
470+
if funcname != '_draw_nothing':
471+
tpath, affine = self._transformed_path.get_transformed_path_and_affine()
472+
markerFunc = getattr(self, funcname)
473+
markerFunc(renderer, gc, tpath, affine)
470474

471475
renderer.close_group('line2d')
472476

@@ -621,10 +625,8 @@ def set_xdata(self, x):
621625
622626
ACCEPTS: npy.array
623627
"""
624-
try: del self._xsorted
625-
except AttributeError: pass
626-
627-
self.set_data(x, self.get_ydata())
628+
self._xorig = x
629+
self.recache()
628630

629631
def set_ydata(self, y):
630632
"""
@@ -633,8 +635,8 @@ def set_ydata(self, y):
633635
ACCEPTS: npy.array
634636
"""
635637

636-
self.set_data(self.get_xdata(), y)
637-
638+
self._yorig = y
639+
self.recache()
638640

639641
def set_dashes(self, seq):
640642
"""

lib/matplotlib/path.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ def __init__(self, vertices, codes=None, closed=True):
8484
resulting path will be compressed, with MOVETO codes inserted
8585
in the correct places to jump over the masked regions.
8686
"""
87-
vertices = ma.asarray(vertices, npy.float_)
87+
if not ma.isMaskedArray(vertices):
88+
vertices = ma.asarray(vertices, npy.float_)
8889

8990
if codes is None:
9091
if len(vertices) == 0:

lib/matplotlib/text.py

Lines changed: 44 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -172,68 +172,58 @@ def update_from(self, other):
172172
self._linespacing = other._linespacing
173173

174174
def _get_layout(self, renderer):
175-
# layout the xylocs in display coords as if angle = zero and
176-
# then rotate them around self._x, self._y
177-
#return _unit_box
178175
key = self.get_prop_tup()
179176
if self.cached.has_key(key): return self.cached[key]
180-
horizLayout = []
181-
transform = self.get_transform()
182-
x, y = self.get_position()
183-
thisx, thisy = transform.transform_point((x, y))
184-
tx, ty = thisx, thisy
185177

186-
width = 0
187-
height = 0
178+
horizLayout = []
188179

189-
xmin, ymin = thisx, thisy
180+
thisx, thisy = 0.0, 0.0
181+
xmin, ymin = 0.0, 0.0
182+
width, height = 0.0, 0.0
190183
lines = self._text.split('\n')
191184

192-
whs = []
185+
whs = npy.zeros((len(lines), 2))
186+
horizLayout = npy.zeros((len(lines), 4))
193187
# Find full vertical extent of font,
194188
# including ascenders and descenders:
195189
tmp, heightt, bl = renderer.get_text_width_height_descent(
196190
'lp', self._fontproperties, ismath=False)
197191
offsety = heightt * self._linespacing
198192

199193
baseline = None
200-
for line in lines:
194+
for i, line in enumerate(lines):
201195
w, h, d = renderer.get_text_width_height_descent(
202196
line, self._fontproperties, ismath=self.is_math_text(line))
203197
if baseline is None:
204198
baseline = h - d
205-
whs.append( (w,h) )
206-
horizLayout.append((line, thisx, thisy, w, h))
199+
whs[i] = w, h
200+
horizLayout[i] = thisx, thisy, w, h
207201
thisy -= offsety
208202
width = max(width, w)
209203

210-
ymin = horizLayout[-1][2]
211-
ymax = horizLayout[0][2] + horizLayout[0][-1]
204+
ymin = horizLayout[-1][1]
205+
ymax = horizLayout[0][1] + horizLayout[0][3]
212206
height = ymax-ymin
213-
214207
xmax = xmin + width
208+
215209
# get the rotation matrix
216-
M = self.get_rotation_matrix(xmin, ymin)
210+
M = Affine2D().rotate_deg(self.get_rotation())
217211

218-
# the corners of the unrotated bounding box
219-
cornersHoriz = npy.array(
220-
[(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)],
221-
npy.float_)
222212
offsetLayout = npy.zeros((len(lines), 2))
213+
offsetLayout[:] = horizLayout[:, 0:2]
223214
# now offset the individual text lines within the box
224215
if len(lines)>1: # do the multiline aligment
225216
malign = self._get_multialignment()
226-
for i, (line, thisx, thisy, w, h) in enumerate(horizLayout):
227-
if malign=='center': offsetx = width/2.0-w/2.0
228-
elif malign=='right': offsetx = width-w
229-
else: offsetx = 0
230-
thisx += offsetx
231-
offsetLayout[i] = (thisx, thisy)
232-
else: # no additional layout needed
233-
offsetLayout[0] = horizLayout[0][1:3]
217+
if malign == 'center':
218+
offsetLayout[:, 0] += width/2.0 - horizLayout[:, 2] / 2.0
219+
elif malign == 'right':
220+
offsetLayout[:, 0] += width - horizLayout[:, 2]
234221

222+
# the corners of the unrotated bounding box
223+
cornersHoriz = npy.array(
224+
[(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)],
225+
npy.float_)
235226
# now rotate the bbox
236-
237227
cornersRotated = M.transform(cornersHoriz)
238228

239229
txs = cornersRotated[:, 0]
@@ -251,37 +241,30 @@ def _get_layout(self, renderer):
251241

252242
# compute the text location in display coords and the offsets
253243
# necessary to align the bbox with that location
254-
tx, ty = self._get_xy_display()
255-
256-
if halign=='center': offsetx = tx - (xmin + width/2.0)
257-
elif halign=='right': offsetx = tx - (xmin + width)
258-
else: offsetx = tx - xmin
244+
if halign=='center': offsetx = (xmin + width/2.0)
245+
elif halign=='right': offsetx = (xmin + width)
246+
else: offsetx = xmin
259247

260-
if valign=='center': offsety = ty - (ymin + height/2.0)
261-
elif valign=='top': offsety = ty - (ymin + height)
262-
elif valign=='baseline': offsety = ty - (ymin + height) + baseline
263-
else: offsety = ty - ymin
248+
if valign=='center': offsety = (ymin + height/2.0)
249+
elif valign=='top': offsety = (ymin + height)
250+
elif valign=='baseline': offsety = (ymin + height) + baseline
251+
else: offsety = ymin
264252

265-
xmin += offsetx
266-
ymin += offsety
253+
xmin -= offsetx
254+
ymin -= offsety
267255

268256
bbox = Bbox.from_lbwh(xmin, ymin, width, height)
269257

270258
# now rotate the positions around the first x,y position
271259
xys = M.transform(offsetLayout)
272-
xys += (offsetx, offsety)
273-
274-
# now inverse transform back to data coords
275-
inverse_transform = transform.inverted()
276-
xys = inverse_transform.transform(xys)
260+
xys -= (offsetx, offsety)
277261

278262
xs, ys = xys[:, 0], xys[:, 1]
279263

280264
ret = bbox, zip(lines, whs, xs, ys)
281265
self.cached[key] = ret
282266
return ret
283267

284-
285268
def set_bbox(self, rectprops):
286269
"""
287270
Draw a bounding box around self. rect props are any settable
@@ -307,28 +290,30 @@ def draw(self, renderer):
307290
if self.get_clip_on():
308291
gc.set_clip_rectangle(self.clipbox)
309292

310-
311-
312293
if self._bbox:
313294
bbox_artist(self, renderer, self._bbox)
314295
angle = self.get_rotation()
315296

316297
bbox, info = self._get_layout(renderer)
317298
trans = self.get_transform()
299+
posx, posy = self.get_position()
300+
posx, posy = trans.transform_point((posx, posy))
301+
canvasw, canvash = renderer.get_canvas_width_height()
302+
318303
if rcParams['text.usetex']:
319-
canvasw, canvash = renderer.get_canvas_width_height()
320304
for line, wh, x, y in info:
321-
x, y = trans.transform_point((x, y))
305+
x = x + posx
306+
y = y + posy
322307
if renderer.flipy():
323308
y = canvash-y
324309

325310
renderer.draw_tex(gc, x, y, line,
326311
self._fontproperties, angle)
327312
return
328313

329-
canvasw, canvash = renderer.get_canvas_width_height()
330314
for line, wh, x, y in info:
331-
x, y = trans.transform_point((x, y))
315+
x = x + posx
316+
y = y + posy
332317
if renderer.flipy():
333318
y = canvash-y
334319

@@ -402,8 +387,7 @@ def get_prop_tup(self):
402387
x, y = self.get_position()
403388
return (x, y, self._text, self._color,
404389
self._verticalalignment, self._horizontalalignment,
405-
hash(self._fontproperties), self._rotation,
406-
self.get_transform().id
390+
hash(self._fontproperties), self._rotation
407391
)
408392

409393
def get_text(self):
@@ -432,11 +416,11 @@ def get_window_extent(self, renderer=None):
432416

433417
angle = self.get_rotation()
434418
bbox, info = self._get_layout(self._renderer)
419+
x, y = self.get_position()
420+
x, y = self.get_transform().transform_point((x, y))
421+
bbox = bbox.translated(x, y)
435422
return bbox
436423

437-
def get_rotation_matrix(self, x0, y0):
438-
return Affine2D().rotate_deg_around(x0, y0, self.get_rotation())
439-
440424
def set_backgroundcolor(self, color):
441425
"""
442426
Set the background color of the text by updating the bbox (see set_bbox for more info)

0 commit comments

Comments
 (0)