Skip to content

Commit df533d4

Browse files
committed
Merge pull request #290 from WeatherGod/cliplimbs
The SuperCuts patch! Clipping done right.
2 parents 16dae04 + 9651af4 commit df533d4

File tree

1 file changed

+61
-73
lines changed

1 file changed

+61
-73
lines changed

lib/mpl_toolkits/basemap/__init__.py

Lines changed: 61 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,7 @@ def drawmapboundary(self,color='k',linewidth=1.0,fill_color=None,\
16681668
limb.set_zorder(0)
16691669
limb.set_edgecolor(color)
16701670
limb.set_linewidth(linewidth)
1671-
limb.set_clip_on(False)
1671+
limb.set_clip_on(True)
16721672
if zorder is not None:
16731673
limb.set_zorder(zorder)
16741674
elif self.projection in _pseudocyl: # elliptical region.
@@ -1702,7 +1702,7 @@ def drawmapboundary(self,color='k',linewidth=1.0,fill_color=None,\
17021702
else:
17031703
limb.set_facecolor(fill_color)
17041704
limb.set_zorder(0)
1705-
limb.set_clip_on(False)
1705+
limb.set_clip_on(True)
17061706
if zorder is not None:
17071707
limb.set_zorder(zorder)
17081708
elif self.round:
@@ -1716,7 +1716,7 @@ def drawmapboundary(self,color='k',linewidth=1.0,fill_color=None,\
17161716
else:
17171717
limb.set_facecolor(fill_color)
17181718
limb.set_zorder(0)
1719-
limb.set_clip_on(False)
1719+
limb.set_clip_on(True)
17201720
if zorder is not None:
17211721
limb.set_zorder(zorder)
17221722
else: # all other projections are rectangular.
@@ -1834,16 +1834,17 @@ def fillcontinents(self,color='0.8',lake_color=None,ax=None,zorder=None,alpha=No
18341834
npoly = npoly + 1
18351835
# set axes limits to fit map region.
18361836
self.set_axes_limits(ax=ax)
1837-
# clip continent polygons for round polar plots.
1838-
if self.round: polys,c = self._clipcircle(ax,polys)
1837+
# clip continent polygons to map limbs
1838+
polys,c = self._cliplimb(ax,polys)
18391839
return polys
18401840

1841-
def _clipcircle(self,ax,coll):
1842-
c = Circle((0.5*(self.xmax+self.xmin),0.5*(self.ymax+self.ymin)),
1843-
radius=0.5*(self.xmax-self.xmin),fc='none')
1841+
def _cliplimb(self,ax,coll):
1842+
if not self._mapboundarydrawn:
1843+
return coll, None
1844+
c = self._mapboundarydrawn
18441845
if c not in ax.patches:
18451846
p = ax.add_patch(c)
1846-
p.set_clip_on(False)
1847+
#p.set_clip_on(False)
18471848
try:
18481849
coll.set_clip_path(c)
18491850
except:
@@ -1883,11 +1884,11 @@ def drawcoastlines(self,linewidth=1.,linestyle='solid',color='k',antialiased=1,a
18831884
coastlines.set_label('_nolabel_')
18841885
if zorder is not None:
18851886
coastlines.set_zorder(zorder)
1886-
# clip coastlines for round polar plots.
1887-
if self.round: coastlines,c = self._clipcircle(ax,coastlines)
18881887
ax.add_collection(coastlines)
18891888
# set axes limits to fit map region.
18901889
self.set_axes_limits(ax=ax)
1890+
# clip to map limbs
1891+
coastlines,c = self._cliplimb(ax,coastlines)
18911892
return coastlines
18921893

18931894
def drawcountries(self,linewidth=0.5,linestyle='solid',color='k',antialiased=1,ax=None,zorder=None):
@@ -1928,10 +1929,10 @@ def drawcountries(self,linewidth=0.5,linestyle='solid',color='k',antialiased=1,a
19281929
if zorder is not None:
19291930
countries.set_zorder(zorder)
19301931
ax.add_collection(countries)
1931-
# clip countries for round polar plots.
1932-
if self.round: countries,c = self._clipcircle(ax,countries)
19331932
# set axes limits to fit map region.
19341933
self.set_axes_limits(ax=ax)
1934+
# clip countries to map limbs
1935+
countries,c = self._cliplimb(ax,countries)
19351936
return countries
19361937

19371938
def drawstates(self,linewidth=0.5,linestyle='solid',color='k',antialiased=1,ax=None,zorder=None):
@@ -1972,10 +1973,10 @@ def drawstates(self,linewidth=0.5,linestyle='solid',color='k',antialiased=1,ax=N
19721973
if zorder is not None:
19731974
states.set_zorder(zorder)
19741975
ax.add_collection(states)
1975-
# clip states for round polar plots.
1976-
if self.round: states,c = self._clipcircle(ax,states)
19771976
# set axes limits to fit map region.
19781977
self.set_axes_limits(ax=ax)
1978+
# clip states to map limbs
1979+
states,c = self._cliplimb(ax,states)
19791980
return states
19801981

19811982
def drawcounties(self,linewidth=0.1,linestyle='solid',color='k',antialiased=1,
@@ -2058,10 +2059,10 @@ def drawrivers(self,linewidth=0.5,linestyle='solid',color='k',antialiased=1,ax=N
20582059
if zorder is not None:
20592060
rivers.set_zorder(zorder)
20602061
ax.add_collection(rivers)
2061-
# clip rivers for round polar plots.
2062-
if self.round: rivers,c = self._clipcircle(ax,rivers)
20632062
# set axes limits to fit map region.
20642063
self.set_axes_limits(ax=ax)
2064+
# clip rivers to map limbs
2065+
rivers,c = self._cliplimb(ax,rivers)
20652066
return rivers
20662067

20672068
def is_land(self,xpt,ypt):
@@ -2229,10 +2230,10 @@ def readshapefile(self,shapefile,name,drawbounds=True,zorder=None,
22292230
if zorder is not None:
22302231
lines.set_zorder(zorder)
22312232
ax.add_collection(lines)
2232-
# clip boundaries for round polar plots.
2233-
if self.round: lines,c = self._clipcircle(ax,lines)
22342233
# set axes limits to fit map region.
22352234
self.set_axes_limits(ax=ax)
2235+
# clip boundaries to map limbs
2236+
lines,c = self._cliplimb(ax,lines)
22362237
info = info + (lines,)
22372238
self.__dict__[name]=coords
22382239
self.__dict__[name+'_info']=attributes
@@ -2512,16 +2513,8 @@ def drawparallels(self,circles,color='k',textcolor='k',linewidth=1.,zorder=None,
25122513
# override __delitem__ in dict to call remove() on values.
25132514
pardict = _dict(linecolls)
25142515
# clip parallels for round polar plots (and delete labels).
2515-
if self.round:
2516-
c = Circle((0.5*(self.xmax+self.xmin),0.5*(self.ymax+self.ymin)),
2517-
radius=0.5*(self.xmax-self.xmin),fc='none')
2518-
if c not in ax.patches:
2519-
p = ax.add_patch(c)
2520-
p.set_clip_on(False)
2521-
for par in pardict:
2522-
lines,labs = pardict[par]
2523-
for l in lines:
2524-
l.set_clip_path(c)
2516+
for lines, _ in pardict.values():
2517+
self._cliplimb(ax, lines)
25252518
return pardict
25262519

25272520
def drawmeridians(self,meridians,color='k',textcolor='k',linewidth=1., zorder=None,\
@@ -2766,20 +2759,11 @@ def addlon(meridians,madd):
27662759
meridict = _dict(linecolls)
27672760
# for round polar plots, clip meridian lines and label them.
27682761
if self.round:
2769-
c = Circle((0.5*(self.xmax+self.xmin),0.5*(self.ymax+self.ymin)),
2770-
radius=0.5*(self.xmax-self.xmin),fc='none')
2771-
if c not in ax.patches:
2772-
p = ax.add_patch(c)
2773-
p.set_clip_on(False)
27742762
# label desired?
27752763
label = False
27762764
for lab in labels:
27772765
if lab: label = True
27782766
for merid in meridict:
2779-
lines,labs = meridict[merid]
2780-
# clip lines.
2781-
for l in lines:
2782-
l.set_clip_path(c)
27832767
if not label: continue
27842768
# label
27852769
lonlab = _setlonlab(fmt,merid,labelstyle)
@@ -2840,6 +2824,8 @@ def addlon(meridians,madd):
28402824
if labels[3] and not labels[2] and y <= 0.5*(self.ymin+self.ymax)+yoffset: continue
28412825
t=ax.text(x,y,lonlab,horizontalalignment=horizalign,verticalalignment=vertalign,**text_kwargs)
28422826
meridict[merid][1].append(t)
2827+
for lines, _ in meridict.values():
2828+
self._cliplimb(ax, lines)
28432829
return meridict
28442830

28452831
def tissot(self,lon_0,lat_0,radius_deg,npts,ax=None,**kwargs):
@@ -2877,10 +2863,10 @@ def tissot(self,lon_0,lat_0,radius_deg,npts,ax=None,**kwargs):
28772863
seg.append((x,y))
28782864
poly = Polygon(seg,**kwargs)
28792865
ax.add_patch(poly)
2880-
# clip polygons for round polar plots.
2881-
if self.round: poly,c = self._clipcircle(ax,poly)
28822866
# set axes limits to fit map region.
28832867
self.set_axes_limits(ax=ax)
2868+
# clip polygons to map limbs
2869+
poly,c = self._cliplimb(ax,poly)
28842870
return poly
28852871

28862872
def gcpoints(self,lon1,lat1,lon2,lat2,npoints):
@@ -3291,10 +3277,10 @@ def scatter(self, *args, **kwargs):
32913277
# reset current active image (only if pyplot is imported).
32923278
if plt:
32933279
plt.sci(ret)
3294-
# clip for round polar plots.
3295-
if self.round: ret,c = self._clipcircle(ax,ret)
32963280
# set axes limits to fit map region.
32973281
self.set_axes_limits(ax=ax)
3282+
# clip to map limbs
3283+
ret,c = self._cliplimb(ax,ret)
32983284
return ret
32993285

33003286
@_transform1d
@@ -3326,10 +3312,10 @@ def plot(self, *args, **kwargs):
33263312
ax.hold(b)
33273313
raise
33283314
ax.hold(b)
3329-
# clip for round polar plots.
3330-
if self.round: ret,c = self._clipcircle(ax,ret)
33313315
# set axes limits to fit map region.
33323316
self.set_axes_limits(ax=ax)
3317+
# clip to map limbs
3318+
ret,c = self._cliplimb(ax,ret)
33333319
return ret
33343320

33353321
def imshow(self, *args, **kwargs):
@@ -3365,10 +3351,10 @@ def imshow(self, *args, **kwargs):
33653351
# reset current active image (only if pyplot is imported).
33663352
if plt:
33673353
plt.sci(ret)
3368-
# clip image for round polar plots.
3369-
if self.round: ret,c = self._clipcircle(ax,ret)
33703354
# set axes limits to fit map region.
33713355
self.set_axes_limits(ax=ax)
3356+
# clip image to map limbs
3357+
ret,c = self._cliplimb(ax,ret)
33723358
return ret
33733359

33743360
@_transform
@@ -3445,10 +3431,10 @@ def pcolor(self,x,y,data,**kwargs):
34453431
# reset current active image (only if pyplot is imported).
34463432
if plt:
34473433
plt.sci(ret)
3448-
# clip for round polar plots.
3449-
if self.round: ret,c = self._clipcircle(ax,ret)
34503434
# set axes limits to fit map region.
34513435
self.set_axes_limits(ax=ax)
3436+
# clip to map limbs
3437+
ret,c = self._cliplimb(ax,ret)
34523438
if self.round:
34533439
# for some reason, frame gets turned on.
34543440
ax.set_frame_on(False)
@@ -3490,10 +3476,10 @@ def pcolormesh(self,x,y,data,**kwargs):
34903476
# reset current active image (only if pyplot is imported).
34913477
if plt:
34923478
plt.sci(ret)
3493-
# clip for round polar plots.
3494-
if self.round: ret,c = self._clipcircle(ax,ret)
34953479
# set axes limits to fit map region.
34963480
self.set_axes_limits(ax=ax)
3481+
# clip to map limbs
3482+
ret,c = self._cliplimb(ax,ret)
34973483
if self.round:
34983484
# for some reason, frame gets turned on.
34993485
ax.set_frame_on(False)
@@ -3540,10 +3526,10 @@ def hexbin(self,x,y,**kwargs):
35403526
# reset current active image (only if pyplot is imported).
35413527
if plt:
35423528
plt.sci(ret)
3543-
# clip for round polar plots.
3544-
if self.round: ret,c = self._clipcircle(ax,ret)
35453529
# set axes limits to fit map region.
35463530
self.set_axes_limits(ax=ax)
3531+
# clip to map limbs
3532+
ret,c = self._cliplimb(ax,ret)
35473533
return ret
35483534

35493535
@_transform
@@ -3640,10 +3626,10 @@ def contour(self,x,y,data,*args,**kwargs):
36403626
# reset current active image (only if pyplot is imported).
36413627
if plt and CS.get_array() is not None:
36423628
plt.sci(CS)
3643-
# clip for round polar plots.
3644-
if self.round: CS.collections,c = self._clipcircle(ax,CS.collections)
36453629
# set axes limits to fit map region.
36463630
self.set_axes_limits(ax=ax)
3631+
# clip to map limbs
3632+
CS.collections,c = self._cliplimb(ax,CS.collections)
36473633
return CS
36483634

36493635
@_transform
@@ -3747,8 +3733,8 @@ def contourf(self,x,y,data,*args,**kwargs):
37473733
plt.sci(CS)
37483734
# set axes limits to fit map region.
37493735
self.set_axes_limits(ax=ax)
3750-
# clip for round polar plots.
3751-
if self.round: CS.collections,c = self._clipcircle(ax,CS.collections)
3736+
# clip to map limbs
3737+
CS.collections,c = self._cliplimb(ax,CS.collections)
37523738
return CS
37533739

37543740
@_transformuv
@@ -3783,10 +3769,10 @@ def quiver(self, x, y, u, v, *args, **kwargs):
37833769
ax.hold(b)
37843770
if plt is not None and ret.get_array() is not None:
37853771
plt.sci(ret)
3786-
# clip for round polar plots.
3787-
if self.round: ret,c = self._clipcircle(ax,ret)
37883772
# set axes limits to fit map region.
37893773
self.set_axes_limits(ax=ax)
3774+
# clip to map limbs
3775+
ret,c = self._cliplimb(ax,ret)
37903776
return ret
37913777

37923778
@_transformuv
@@ -3825,15 +3811,15 @@ def streamplot(self, x, y, u, v, *args, **kwargs):
38253811
ax.hold(b)
38263812
if plt is not None and ret.lines.get_array() is not None:
38273813
plt.sci(ret.lines)
3828-
# clip for round polar plots.
3814+
# set axes limits to fit map region.
3815+
self.set_axes_limits(ax=ax)
3816+
# clip to map limbs
3817+
ret,c = self._cliplimb(ax,ret)
38293818
# streamplot arrows not returned in matplotlib 1.1.1, so clip all
38303819
# FancyArrow patches attached to axes instance.
3831-
if self. round:
3832-
ret,c = self._clipcircle(ax,ret)
3820+
if c is not None:
38333821
for p in ax.patches:
38343822
if isinstance(p,FancyArrowPatch): p.set_clip_path(c)
3835-
# set axes limits to fit map region.
3836-
self.set_axes_limits(ax=ax)
38373823
return ret
38383824

38393825
@_transformuv
@@ -3884,12 +3870,12 @@ def barbs(self, x, y, u, v, *args, **kwargs):
38843870
# we can't set the current image...
38853871
#if plt is not None and ret.get_array() is not None:
38863872
# plt.sci(retnh)
3887-
# clip for round polar plots.
3888-
if self.round:
3889-
retnh,c = self._clipcircle(ax,retnh)
3890-
retsh,c = self._clipcircle(ax,retsh)
38913873
# set axes limits to fit map region.
38923874
self.set_axes_limits(ax=ax)
3875+
# clip to map limbs
3876+
retnh,c = self._cliplimb(ax,retnh)
3877+
retsh,c = self._cliplimb(ax,retsh)
3878+
38933879
return retnh,retsh
38943880

38953881
def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None,
@@ -4031,8 +4017,8 @@ def drawlsmask(self,land_color="0.8",ocean_color="w",lsmask=None,
40314017
rgba[:,:,3] = np.where(self.lsmask==255,0,rgba[:,:,3])
40324018
# plot mask as rgba image.
40334019
im = self.imshow(rgba,interpolation='nearest',ax=ax,**kwargs)
4034-
# clip for round polar plots.
4035-
if self.round: im,c = self._clipcircle(ax,im)
4020+
# clip to map limbs.
4021+
im,c = self._cliplimb(ax,im)
40364022
return im
40374023

40384024
def bluemarble(self,ax=None,scale=None,**kwargs):
@@ -4253,20 +4239,22 @@ def warpimage(self,image="bluemarble",scale=None,**kwargs):
42534239
self._bm_rgba_warped = \
42544240
ma.masked_array(self._bm_rgba_warped,mask=mask)
42554241
# make points outside projection limb transparent.
4242+
# FIXME: Probably not needed anymore
42564243
self._bm_rgba_warped = self._bm_rgba_warped.filled(0.)
42574244
# plot warped rgba image.
42584245
im = self.imshow(self._bm_rgba_warped,ax=ax,**kwargs)
42594246
# for hammer projection, use clip path defined by
42604247
# projection limb (patch created in drawmapboundary).
4248+
# FIXME: Is this now redundant?
42614249
if self.projection == 'hammer':
42624250
if not self._mapboundarydrawn:
42634251
self.drawmapboundary(color='none',linewidth=None)
42644252
im.set_clip_path(self._mapboundarydrawn)
42654253
else:
42664254
# bmproj True, no interpolation necessary.
42674255
im = self.imshow(self._bm_rgba,ax=ax,**kwargs)
4268-
# clip for round polar plots.
4269-
if self.round: im,c = self._clipcircle(ax,im)
4256+
# clip to map limbs
4257+
im,c = self._cliplimb(ax,im)
42704258
return im
42714259

42724260
def arcgisimage(self,server='http://server.arcgisonline.com/ArcGIS',\
@@ -4715,8 +4703,8 @@ def nightshade(self,date,color="k",delta=0.25,alpha=0.5,ax=None,zorder=2):
47154703
# is on top.
47164704
for c in CS.collections:
47174705
c.set_zorder(zorder)
4718-
# clip for round polar plots.
4719-
if self.round: CS.collections,c = self._clipcircle(ax,CS.collections)
4706+
# clip to map limbs
4707+
CS.collections,c = self._cliplimb(ax,CS.collections)
47204708
return CS
47214709

47224710
def _check_ax(self):

0 commit comments

Comments
 (0)