diff --git a/Changelog b/Changelog index 60af496b5..b39c2e672 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,7 @@ -version 1.0.5 (not yet released) --------------------------------- +version 1.0.5 (git tag v1.0.5rel) +--------------------------------- +* fix error in contour method that caused a bogus mask to be applied + to the data (issue 58). * fix further corner cases with splitting of parallels that cross the dateline (issue 40). * add latlon keyword to plotting methods. If latlon=True, x and y diff --git a/KNOWN_BUGS b/KNOWN_BUGS index 4694a25bf..3a27bc31c 100644 --- a/KNOWN_BUGS +++ b/KNOWN_BUGS @@ -2,5 +2,6 @@ always tries to fill the inside of a polygon. Under certain situations, what is the inside of a coastline polygon can be ambiguous, and the outside may be filled instead of the inside. -Workaround - mask the land areas with the drawlsmask method instead of +Workarounds - change the map projection region slightly or +mask the land areas with the drawlsmask method instead of filling the coastline polygons (this is illustrated in the ortho_demo.py example). diff --git a/MANIFEST.in b/MANIFEST.in index b07af5142..cf32148f4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,6 +11,7 @@ include Changelog include setup.py include nad2bin.c include src/* +include examples/shiftdata.py include examples/allskymap.py include examples/allskymap_cr_example.py include examples/plothighsandlows.py diff --git a/examples/README b/examples/README index 3bcbd23f9..233e28a64 100644 --- a/examples/README +++ b/examples/README @@ -153,3 +153,6 @@ make_inset.py shows how to make an inset showing the location of the map project from a global perspective. utmtest.py shows how to plot a UTM zone. + +shiftdata.py shows how to use the 'latlon' keyword to automatically transform to map +projection coordinates and shift the data longitudinally to fit the map projection region. diff --git a/examples/ccsm_popgrid.py b/examples/ccsm_popgrid.py index e18ccb7e9..a4ae6bfa9 100644 --- a/examples/ccsm_popgrid.py +++ b/examples/ccsm_popgrid.py @@ -49,15 +49,15 @@ plt.figure(figsize=(6,8)) plt.subplot(2,1,1) # subplot 1 just shows POP grid cells. -map = Basemap(projection='merc', lat_ts=20, llcrnrlon=-180, \ +m = Basemap(projection='merc', lat_ts=20, llcrnrlon=-180, \ urcrnrlon=180, llcrnrlat=-84, urcrnrlat=84, resolution='c') -map.drawcoastlines() -map.fillcontinents(color='white') +m.drawcoastlines() +m.fillcontinents(color='white') -x, y = map(tlon,tlat) -im = map.pcolor(x,y,ma.masked_array(np.zeros(temp.shape,'f'), temp.mask), - shading='faceted', antialiased=True, cmap=plt.cm.cool, +x, y = m(tlon,tlat) +im = m.pcolor(x,y,ma.masked_array(np.zeros(temp.shape,'f'), temp.mask), + shading='faceted', antialiased=True, cmap=plt.cm.cool, vmin=0, vmax=0) # disclaimer: these are not really the grid cells because of the # way pcolor interprets the x and y args. @@ -66,11 +66,11 @@ # subplot 2 is a contour plot of surface temperature from the # CCSM ocean model. plt.subplot(2,1,2) -map.drawcoastlines() -map.fillcontinents(color='white') +m.drawcoastlines() +m.fillcontinents(color='white') -CS1 = map.contourf(x,y,temp,15) -CS2 = map.contour(x,y,temp,15,colors='black',linewidths=0.5) +CS1 = m.contourf(x,y,temp,15) +CS2 = m.contour(x,y,temp,15,colors='black',linewidths=0.5) plt.title('(B) Surface Temp contours on POP Grid') plt.show() diff --git a/examples/fcstmaps_axesgrid.py b/examples/fcstmaps_axesgrid.py index bea441b11..1cc031449 100644 --- a/examples/fcstmaps_axesgrid.py +++ b/examples/fcstmaps_axesgrid.py @@ -1,5 +1,5 @@ from __future__ import print_function -# this example reads today's numerical weather forecasts +# this example reads today's numerical weather forecasts # from the NOAA OpenDAP servers and makes a multi-panel plot. # This version demonstrates the use of the AxesGrid toolkit. import numpy as np @@ -100,7 +100,7 @@ ax.set_title('%d-h forecast valid '%fcsthr+verifdates[nt],fontsize=9) # figure title plt.figtext(0.5,0.95, - "2-m temp (\N{DEGREE SIGN}C) forecasts from %s"%verifdates[0], + u"2-m temp (\N{DEGREE SIGN}C) forecasts from %s"%verifdates[0], horizontalalignment='center',fontsize=14) # a single colorbar. cbar = fig.colorbar(cs, cax=grid.cbar_axes[0], orientation='horizontal') diff --git a/examples/geos_demo.py b/examples/geos_demo.py index 7a9717e64..049e42bf3 100644 --- a/examples/geos_demo.py +++ b/examples/geos_demo.py @@ -29,12 +29,11 @@ def get_input(prompt): fig = plt.figure() m = Basemap(projection='geos',lon_0=lon_0,rsphere=(6378137.00,6356752.3142),resolution='l') m.drawcoastlines() -m.drawmapboundary(fill_color='aqua') m.fillcontinents(color='coral',lake_color='aqua') +m.drawmapboundary(fill_color='aqua') m.drawcountries() # draw parallels and meridians. m.drawparallels(np.arange(-90.,120.,30.)) m.drawmeridians(np.arange(0.,420.,60.)) -m.drawmapboundary() plt.title('Geostationary Map Centered on Lon=%s' % (lon_0)) plt.show() diff --git a/lib/mpl_toolkits/basemap/__init__.py b/lib/mpl_toolkits/basemap/__init__.py index 0a7025ddd..62b881c53 100644 --- a/lib/mpl_toolkits/basemap/__init__.py +++ b/lib/mpl_toolkits/basemap/__init__.py @@ -505,6 +505,8 @@ def __init__(self, llcrnrlon=None, llcrnrlat=None, self.boundinglat = boundinglat # is a round pole-centered plot desired? self.round = round + # full disk projection? + self._fulldisk = False # default value # set up projection parameter dict. projparams = {} @@ -1378,6 +1380,13 @@ def _getmapboundary(self): n = n + 1 self.boundarylonmin = lons.min() self.boundarylonmax = lons.max() + # for circular full disk projections where boundary is + # a latitude circle, set boundarylonmax and boundarylonmin + # to cover entire world (so parallels will be drawn). + if self._fulldisk and \ + np.abs(self.boundarylonmax-self.boundarylonmin) < 1.: + self.boundarylonmin = -180. + self.boundarylonmax = 180. b = np.empty((len(lons),2),np.float64) b[:,0] = lons; b[:,1] = lats boundaryll = _geoslib.Polygon(b) @@ -3083,6 +3092,8 @@ def pcolor(self,x,y,data,**kwargs): x = np.compress(mask,x) y = np.compress(mask,y) data = np.compress(mask,data) + # delete this keyword so it's not pass on to pcolor. + del kwargs['tri'] if masked: triang = tri.Triangulation(x, y) z = data[triang.triangles] @@ -3091,8 +3102,6 @@ def pcolor(self,x,y,data,**kwargs): ret = ax.tripcolor(triang,data,**kwargs) else: ret = ax.tripcolor(x,y,data,**kwargs) - # delete this keyword so it's not pass on to pcolor. - del kwargs['tri'] else: # make x,y masked arrays # (masked where data is outside of projection limb) @@ -3249,6 +3258,8 @@ def contour(self,x,y,data,*args,**kwargs): x = np.compress(mask,x) y = np.compress(mask,y) data = np.compress(mask,data) + # delete this keyword so it's not pass on to pcolor. + del kwargs['tri'] if masked: triang = tri.Triangulation(x, y) z = data[triang.triangles] @@ -3457,6 +3468,11 @@ def streamplot(self, x, y, u, v, *args, **kwargs): Other \*args and \**kwargs passed on to matplotlib.pyplot.streamplot. """ + if _matplotlib_version < '1.2': + msg = dedent(""" + streamplot method requires matplotlib 1.2 or higher, + you have %s""" % _matplotlib_version) + raise NotImplementedError(msg) ax, plt = self._ax_plt_from_kw(kwargs) # allow callers to override the hold state by passing hold=True|False b = ax.ishold()