Skip to content

Commit c278ec8

Browse files
committed
Speed improvements -- determine path extents in C
svn path=/branches/transforms/; revision=4489
1 parent 8705b9e commit c278ec8

File tree

6 files changed

+407
-317
lines changed

6 files changed

+407
-317
lines changed

lib/matplotlib/axes.py

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,10 @@ class Axes(martist.Artist):
425425
426426
"""
427427
name = "rectilinear"
428-
428+
429429
_shared_x_axes = cbook.Grouper()
430430
_shared_y_axes = cbook.Grouper()
431-
431+
432432
def __str__(self):
433433
return "Axes(%g,%g;%gx%g)" % tuple(self._position.bounds)
434434
def __init__(self, fig, rect,
@@ -496,7 +496,7 @@ def __init__(self, fig, rect,
496496

497497
# this call may differ for non-sep axes, eg polar
498498
self._init_axis()
499-
499+
500500
if axisbg is None: axisbg = rcParams['axes.facecolor']
501501
self._axisbg = axisbg
502502
self._frameon = frameon
@@ -679,20 +679,20 @@ def get_yaxis_text2_transform(self, pad_pixels):
679679
return (self._yaxis_transform +
680680
mtransforms.Affine2D().translate(pad_pixels, 0),
681681
"center", "left")
682-
682+
683683
def _update_transScale(self):
684684
self.transScale.set(
685685
mtransforms.blended_transform_factory(
686686
self.xaxis.get_transform(), self.yaxis.get_transform()))
687-
687+
688688
def get_position(self, original=False):
689689
'Return the a copy of the axes rectangle as a Bbox'
690690
if original:
691691
return self._originalPosition.frozen()
692692
else:
693693
return self._position.frozen()
694694

695-
695+
696696
def set_position(self, pos, which='both'):
697697
"""
698698
Set the axes position with pos = [left, bottom, width, height]
@@ -734,7 +734,7 @@ def get_axes_patch(self):
734734
Intended to be overridden by new projection types.
735735
"""
736736
return mpatches.Rectangle((0.0, 0.0), 1.0, 1.0)
737-
737+
738738
def cla(self):
739739
'Clear the current axes'
740740

@@ -780,7 +780,7 @@ def cla(self):
780780
self.title.set_clip_box(None)
781781

782782
self._set_artist_props(self.title)
783-
783+
784784
self.axesPatch = self.get_axes_patch()
785785
self.axesPatch.set_figure(self.figure)
786786
self.axesPatch.set_facecolor(self._axisbg)
@@ -904,7 +904,7 @@ def get_data_ratio(self):
904904
ymin,ymax = self.get_ybound()
905905
ysize = max(math.fabs(ymax-ymin), 1e-30)
906906
return ysize/xsize
907-
907+
908908
def apply_aspect(self):
909909
'''
910910
Use self._aspect and self._adjustable to modify the
@@ -938,7 +938,7 @@ def apply_aspect(self):
938938
xsize = max(math.fabs(xmax-xmin), 1e-30)
939939
ymin,ymax = self.get_ybound()
940940
ysize = max(math.fabs(ymax-ymin), 1e-30)
941-
941+
942942
l,b,w,h = self.get_position(original=True).bounds
943943
box_aspect = fig_aspect * (h/w)
944944
data_ratio = box_aspect / A
@@ -1125,7 +1125,6 @@ def add_artist(self, a):
11251125
a.set_axes(self)
11261126
self.artists.append(a)
11271127
self._set_artist_props(a)
1128-
# MGDTODO: We may not want to do this -- the old trunk didn't
11291128
a.set_clip_path(self.axesPatch)
11301129
a._remove_method = lambda h: self.artists.remove(h)
11311130

@@ -1168,7 +1167,7 @@ def add_patch(self, p):
11681167
self._update_patch_limits(p)
11691168
self.patches.append(p)
11701169
p._remove_method = lambda h: self.patches.remove(h)
1171-
1170+
11721171
def _update_patch_limits(self, p):
11731172
'update the datalimits for patch p'
11741173
vertices = p.get_patch_transform().transform(p.get_path().vertices)
@@ -1181,7 +1180,6 @@ def add_table(self, tab):
11811180
'Add a table instance to the list of axes tables'
11821181
self._set_artist_props(tab)
11831182
self.tables.append(tab)
1184-
# MGDTODO: We may not want to do this (the old version in trunk didn't)
11851183
tab.set_clip_path(self.axesPatch)
11861184
tab._remove_method = lambda h: self.tables.remove(h)
11871185

@@ -1202,7 +1200,8 @@ def update_datalim(self, xys):
12021200
# and the data in xydata
12031201
if not ma.isMaskedArray(xys):
12041202
xys = npy.asarray(xys)
1205-
self.update_datalim_numerix(xys[:, 0], xys[:, 1])
1203+
self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits)
1204+
self.ignore_existing_data_limits = False
12061205

12071206
def update_datalim_numerix(self, x, y):
12081207
'Update the data lim bbox with seq of xy tups'
@@ -1216,7 +1215,7 @@ def update_datalim_numerix(self, x, y):
12161215
def update_datalim_bounds(self, bounds):
12171216
'Update the datalim to include the given Bbox'
12181217
self.dataLim.set(Bbox.union([self.dataLim, bounds]))
1219-
1218+
12201219
def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
12211220
'look for unit kwargs and update the axis instances as necessary'
12221221

@@ -1303,7 +1302,7 @@ def draw(self, renderer=None, inframe=False):
13031302

13041303
if self.axison and self._frameon:
13051304
self.axesPatch.draw(renderer)
1306-
1305+
13071306
artists = []
13081307

13091308
if len(self.images)<=1 or renderer.option_image_nocomposite():
@@ -1513,7 +1512,7 @@ def set_axis_bgcolor(self, color):
15131512
self.axesPatch.set_facecolor(color)
15141513

15151514
### data limits, ticks, tick labels, and formatting
1516-
1515+
15171516
def invert_xaxis(self):
15181517
"Invert the x-axis."
15191518
left, right = self.get_xlim()
@@ -1601,7 +1600,7 @@ def set_xlim(self, xmin=None, xmax=None, emit=True, **kwargs):
16011600
xmin, xmax = self.xaxis.limit_range_for_scale(xmin, xmax)
16021601

16031602
self.viewLim.intervalx = (xmin, xmax)
1604-
1603+
16051604
if emit:
16061605
self.callbacks.process('xlim_changed', self)
16071606
# Call all of the other x-axes that are shared with this one
@@ -1610,7 +1609,7 @@ def set_xlim(self, xmin=None, xmax=None, emit=True, **kwargs):
16101609
other.set_xlim(self.viewLim.intervalx, emit=False)
16111610
if other.figure != self.figure and other.figure.canvas is not None:
16121611
other.figure.canvas.draw_idle()
1613-
1612+
16141613
return xmin, xmax
16151614

16161615
def get_xscale(self):
@@ -1638,7 +1637,7 @@ def set_xscale(self, value, **kwargs):
16381637
""" % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
16391638
self.xaxis.set_scale(value, **kwargs)
16401639
self._update_transScale()
1641-
1640+
16421641
def get_xticks(self, minor=False):
16431642
'Return the x ticks as a list of locations'
16441643
return self.xaxis.get_ticklocs(minor=minor)
@@ -1777,7 +1776,7 @@ def get_yscale(self):
17771776
'return the xaxis scale string: %s' % (
17781777
", ".join(mscale.get_scale_names()))
17791778
return self.yaxis.get_scale()
1780-
1779+
17811780
def set_yscale(self, value, **kwargs):
17821781
"""
17831782
SET_YSCALE(value, basey=10, subsy=None)
@@ -1798,7 +1797,7 @@ def set_yscale(self, value, **kwargs):
17981797
""" % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
17991798
self.yaxis.set_scale(value, **kwargs)
18001799
self._update_transScale()
1801-
1800+
18021801
def get_yticks(self, minor=False):
18031802
'Return the y ticks as a list of locations'
18041803
return self.yaxis.get_ticklocs(minor=minor)
@@ -1903,15 +1902,15 @@ def format_coord(self, x, y):
19031902
xs = self.format_xdata(x)
19041903
ys = self.format_ydata(y)
19051904
return 'x=%s, y=%s'%(xs,ys)
1906-
1905+
19071906
#### Interactive manipulation
19081907

19091908
def can_zoom(self):
19101909
"""
19111910
Return True if this axes support the zoom box
19121911
"""
19131912
return True
1914-
1913+
19151914
def get_navigate(self):
19161915
"""
19171916
Get whether the axes responds to navigation commands
@@ -1949,7 +1948,7 @@ def start_pan(self, x, y, button):
19491948
1: LEFT
19501949
2: MIDDLE
19511950
3: RIGHT
1952-
1951+
19531952
Intended to be overridden by new projection types.
19541953
"""
19551954
self._pan_start = cbook.Bunch(
@@ -1968,7 +1967,7 @@ def end_pan(self):
19681967
Intended to be overridden by new projection types.
19691968
"""
19701969
del self._pan_start
1971-
1970+
19721971
def drag_pan(self, button, key, x, y):
19731972
"""
19741973
Called when the mouse moves during a pan operation.
@@ -2029,10 +2028,10 @@ def format_deltas(key, dx, dy):
20292028
except OverflowError:
20302029
warnings.warn('Overflow while panning')
20312030
return
2032-
2031+
20332032
self.set_xlim(*result.intervalx)
20342033
self.set_ylim(*result.intervaly)
2035-
2034+
20362035
def get_cursor_props(self):
20372036
"""return the cursor props as a linewidth, color tuple where
20382037
linewidth is a float and color is an RGBA tuple"""
@@ -3158,7 +3157,7 @@ def step(self, x, y, *args, **kwargs):
31583157
if where not in ('pre', 'post', 'mid'):
31593158
raise ValueError("'where' argument to step must be 'pre', 'post' or 'mid'")
31603159
kwargs['linestyle'] = 'steps-' + where
3161-
3160+
31623161
return self.plot(x, y, *args, **kwargs)
31633162

31643163

@@ -3828,7 +3827,7 @@ def xywhere(xs, ys, mask):
38283827
# using list comps rather than arrays to preserve units
38293828
lower = [thisy-thiserr for (thisy, thiserr) in cbook.safezip(y,yerr)]
38303829
upper = [thisy+thiserr for (thisy, thiserr) in cbook.safezip(y,yerr)]
3831-
3830+
38323831
barcols.append( self.vlines(x, lower, upper, **lines_kw) )
38333832
if capsize > 0:
38343833

@@ -4334,7 +4333,7 @@ def quiverkey(self, *args, **kw):
43344333

43354334
def quiver(self, *args, **kw):
43364335
"""
4337-
MGDTODO: Document me
4336+
TODO: Document me
43384337
"""
43394338
q = mquiver.Quiver(self, *args, **kw)
43404339
self.add_collection(q, False)
@@ -4516,7 +4515,7 @@ def imshow(self, X,
45164515

45174516
return im
45184517

4519-
4518+
45204519
def _pcolorargs(self, funcname, *args):
45214520
if len(args)==1:
45224521
C = args[0]
@@ -4790,7 +4789,7 @@ def pcolormesh(self, *args, **kwargs):
47904789
shading = kwargs.pop('shading', 'flat')
47914790
edgecolors = kwargs.pop('edgecolors', 'None')
47924791
antialiased = kwargs.pop('antialiased', False)
4793-
4792+
47944793
X, Y, C = self._pcolorargs('pcolormesh', *args)
47954794
Ny, Nx = X.shape
47964795

@@ -5519,7 +5518,7 @@ def __init__(self, fig, *args, **kwargs):
55195518

55205519
# _axes_class is set in the subplot_class_factory
55215520
self._axes_class.__init__(self, fig, self.figbox, **kwargs)
5522-
5521+
55235522
def get_geometry(self):
55245523
'get the subplot geometry, eg 2,2,3'
55255524
return self._rows, self._cols, self._num+1
@@ -5608,24 +5607,24 @@ def label_outer(self):
56085607
for label in self.get_yticklabels():
56095608
label.set_visible(firstcol)
56105609

5611-
_subplot_classes = {}
5610+
_subplot_classes = {}
56125611
def subplot_class_factory(axes_class=None):
56135612
# This makes a new class that inherits from SubclassBase and the
56145613
# given axes_class (which is assumed to be a subclass of Axes).
5615-
5614+
56165615
# This is perhaps a little bit roundabout to make a new class on
56175616
# the fly like this, but it means that a new Subplot class does
56185617
# not have to be created for every type of Axes.
56195618
if axes_class is None:
56205619
axes_class = Axes
5621-
5620+
56225621
new_class = _subplot_classes.get(axes_class)
56235622
if new_class is None:
56245623
new_class = new.classobj("%sSubplot" % (axes_class.__name__),
56255624
(SubplotBase, axes_class),
56265625
{'_axes_class': axes_class})
56275626
_subplot_classes[axes_class] = new_class
5628-
5627+
56295628
return new_class
56305629

56315630
# This is provided for backward compatibility

lib/matplotlib/colorbar.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,17 @@ def _config_axes(self, X, Y):
198198
ax = self.ax
199199
ax.set_frame_on(False)
200200
ax.set_navigate(False)
201-
x, y = self._outline(X, Y)
202-
ax.set_xlim(npy.amin(x), npy.amax(x))
203-
ax.set_ylim(npy.amin(y), npy.amax(y))
204-
ax.update_datalim_numerix(x, y)
205-
self.outline = lines.Line2D(x, y, color=mpl.rcParams['axes.edgecolor'],
201+
xy = self._outline(X, Y)
202+
ax.update_datalim(xy)
203+
ax.set_xlim(*ax.dataLim.intervalx)
204+
ax.set_ylim(*ax.dataLim.intervaly)
205+
self.outline = lines.Line2D(xy[:, 0], xy[:, 1], color=mpl.rcParams['axes.edgecolor'],
206206
linewidth=mpl.rcParams['axes.linewidth'])
207207
ax.add_artist(self.outline)
208208
self.outline.set_clip_box(None)
209209
self.outline.set_clip_path(None)
210210
c = mpl.rcParams['axes.facecolor']
211-
self.patch = patches.Polygon(zip(x,y), edgecolor=c,
211+
self.patch = patches.Polygon(xy, edgecolor=c,
212212
facecolor=c,
213213
linewidth=0.01,
214214
zorder=-1)
@@ -250,9 +250,11 @@ def _outline(self, X, Y):
250250
ii = [0, 1, N-2, N-1, 2*N-1, 2*N-2, N+1, N, 0]
251251
x = npy.take(npy.ravel(npy.transpose(X)), ii)
252252
y = npy.take(npy.ravel(npy.transpose(Y)), ii)
253+
x = x.reshape((len(x), 1))
254+
y = y.reshape((len(y), 1))
253255
if self.orientation == 'horizontal':
254-
return y,x
255-
return x,y
256+
return npy.hstack((y, x))
257+
return npy.hstack((x, y))
256258

257259
def _edges(self, X, Y):
258260
'''
@@ -510,7 +512,7 @@ def _locate(self, x):
510512
N = len(b)
511513
ii = npy.minimum(npy.searchsorted(b, xn), N-1)
512514
i0 = npy.maximum(ii - 1, 0)
513-
#db = b[ii] - b[i0]
515+
#db = b[ii] - b[i0]
514516
db = npy.take(b, ii) - npy.take(b, i0)
515517
db = npy.where(i0==ii, 1.0, db)
516518
#dy = y[ii] - y[i0]

0 commit comments

Comments
 (0)