SourceForge logo
SourceForge logo
Menu

matplotlib-checkins — Commit notification. DO NOT POST to this list, just subscribe to it.

You can subscribe to this list here.

2007 Jan
Feb
Mar
Apr
May
Jun
Jul
(115)
Aug
(120)
Sep
(137)
Oct
(170)
Nov
(461)
Dec
(263)
2008 Jan
(120)
Feb
(74)
Mar
(35)
Apr
(74)
May
(245)
Jun
(356)
Jul
(240)
Aug
(115)
Sep
(78)
Oct
(225)
Nov
(98)
Dec
(271)
2009 Jan
(132)
Feb
(84)
Mar
(74)
Apr
(56)
May
(90)
Jun
(79)
Jul
(83)
Aug
(296)
Sep
(214)
Oct
(76)
Nov
(82)
Dec
(66)
2010 Jan
(46)
Feb
(58)
Mar
(51)
Apr
(77)
May
(58)
Jun
(126)
Jul
(128)
Aug
(64)
Sep
(50)
Oct
(44)
Nov
(48)
Dec
(54)
2011 Jan
(68)
Feb
(52)
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
(1)
2018 Jan
Feb
Mar
Apr
May
(1)
Jun
Jul
Aug
Sep
Oct
Nov
Dec
S M T W T F S


1
(3)
2
3
4
(1)
5
6
(1)
7
(2)
8
(22)
9
(8)
10
(24)
11
(3)
12
(4)
13
14
(3)
15
(3)
16
(1)
17
(2)
18
(6)
19
20
21
(3)
22
(2)
23
(8)
24
(1)
25
26
(6)
27
(1)
28
(3)
29
(4)
30
31
(9)


Showing results of 120

<< < 1 2 3 4 5 > >> (Page 3 of 5)
From: <md...@us...> - 2008年01月14日 13:15:21
Revision: 4867
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4867&view=rev
Author: mdboom
Date: 2008年01月14日 05:15:17 -0800 (2008年1月14日)
Log Message:
-----------
Merged revisions 4856-4866 via svnmerge from 
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_91_maint
........
 r4866 | mdboom | 2008年01月14日 08:11:16 -0500 (2008年1月14日) | 3 lines
 
 Fix SVG glyphs for use with Qt (which doesn't look forward for the
 glyph definitions).
........
Modified Paths:
--------------
 trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
Property Changed:
----------------
 trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Name: svnmerge-integrated
 - /branches/v0_91_maint:1-4855
 + /branches/v0_91_maint:1-4866
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py	2008年01月14日 13:11:16 UTC (rev 4866)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py	2008年01月14日 13:15:17 UTC (rev 4867)
@@ -294,8 +294,20 @@
 
 fontsize = prop.get_size_in_points()
 color = rgb2hex(gc.get_rgb()[:3])
+ write = self._svgwriter.write
 
 if rcParams['svg.embed_char_paths']:
+ new_chars = []
+ for c in s:
+ path = self._add_char_def(prop, c)
+ if path is not None:
+ new_chars.append(path)
+ if len(new_chars):
+ write('<defs>\n')
+ for path in new_chars:
+ write(path)
+ write('</defs>\n')
+
 svg = ['<g style="fill: %s; opacity: %s" transform="' % (color, gc.get_alpha())]
 if angle != 0:
 svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle))
@@ -307,7 +319,7 @@
 lastgind = None
 currx = 0
 for c in s:
- charid = self._add_char_def(prop, c)
+ charnum = self._get_char_def_id(prop, c)
 ccode = ord(c)
 gind = cmap.get(ccode)
 if gind is None:
@@ -322,7 +334,7 @@
 lastgind = gind
 currx += kern/64.0
 
- svg.append('<use xlink:href="#%s"' % charid)
+ svg.append('<use xlink:href="#%s"' % charnum)
 if currx != 0:
 svg.append(' x="%s"' %
 (currx * (self.FONT_SCALE / fontsize)))
@@ -346,7 +358,7 @@
 svg = """\
 <text style="%(style)s" x="%(x)s" y="%(y)s" %(transform)s>%(thetext)s</text>
 """ % locals()
- self._svgwriter.write (svg)
+ write(svg)
 
 def _add_char_def(self, prop, char):
 if isinstance(prop, FontProperties):
@@ -357,9 +369,9 @@
 font.set_size(self.FONT_SCALE, 72)
 ps_name = font.get_sfnt()[(1,0,0,6)]
 char_id = urllib.quote('%s-%d' % (ps_name, ord(char)))
- char_num, path = self._char_defs.get(char_id, (None, None))
+ char_num = self._char_defs.get(char_id, None)
 if char_num is not None:
- return char_num
+ return None
 
 path_data = []
 glyph = font.load_char(ord(char), flags=LOAD_NO_HINTING)
@@ -388,9 +400,20 @@
 currx, curry = step[-2], -step[-1]
 char_num = 'c%x' % len(self._char_defs)
 path_element = '<path id="%s" d="%s"/>\n' % (char_num, ''.join(path_data))
- self._char_defs[char_id] = (char_num, path_element)
- return char_num
+ self._char_defs[char_id] = char_num
+ return path_element
 
+ def _get_char_def_id(self, prop, char):
+ if isinstance(prop, FontProperties):
+ newprop = prop.copy()
+ font = self._get_font(newprop)
+ else:
+ font = prop
+ font.set_size(self.FONT_SCALE, 72)
+ ps_name = font.get_sfnt()[(1,0,0,6)]
+ char_id = urllib.quote('%s-%d' % (ps_name, ord(char)))
+ return self._char_defs[char_id]
+
 def _draw_mathtext(self, gc, x, y, s, prop, angle):
 """
 Draw math text using matplotlib.mathtext
@@ -400,12 +423,22 @@
 svg_glyphs = svg_elements.svg_glyphs
 svg_rects = svg_elements.svg_rects
 color = rgb2hex(gc.get_rgb()[:3])
+ write = self._svgwriter.write
 
- self.open_group("mathtext")
-
 style = "fill: %s" % color
 
 if rcParams['svg.embed_char_paths']:
+ new_chars = []
+ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
+ path = self._add_char_def(font, thetext)
+ if path is not None:
+ new_chars.append(path)
+ if len(new_chars):
+ write('<defs>\n')
+ for path in new_chars:
+ write(path)
+ write('</defs>\n')
+
 svg = ['<g style="%s" transform="' % style]
 if angle != 0:
 svg.append('translate(%s,%s)rotate(%1.1f)'
@@ -415,7 +448,7 @@
 svg.append('">\n')
 
 for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
- charid = self._add_char_def(font, thetext)
+ charid = self._get_char_def_id(font, thetext)
 
 svg.append('<use xlink:href="#%s" transform="translate(%s,%s)scale(%s)"/>\n' %
 (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE))
@@ -469,16 +502,12 @@
 svg.append('<rect x="%s" y="%s" width="%s" height="%s" fill="black" stroke="none" />' % (x, -y + height, width, height))
 svg.append("</g>")
 
- self._svgwriter.write (''.join(svg))
+ self.open_group("mathtext")
+ write (''.join(svg))
 self.close_group("mathtext")
 
 def finalize(self):
 write = self._svgwriter.write
- if len(self._char_defs):
- write('<defs id="fontpaths">\n')
- for char_num, path in self._char_defs.values():
- write(path)
- write('</defs>\n')
 write('</svg>\n')
 
 def flipy(self):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4866
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4866&view=rev
Author: mdboom
Date: 2008年01月14日 05:11:16 -0800 (2008年1月14日)
Log Message:
-----------
Fix SVG glyphs for use with Qt (which doesn't look forward for the
glyph definitions).
Modified Paths:
--------------
 branches/v0_91_maint/lib/matplotlib/backends/backend_svg.py
Modified: branches/v0_91_maint/lib/matplotlib/backends/backend_svg.py
===================================================================
--- branches/v0_91_maint/lib/matplotlib/backends/backend_svg.py	2008年01月12日 13:36:24 UTC (rev 4865)
+++ branches/v0_91_maint/lib/matplotlib/backends/backend_svg.py	2008年01月14日 13:11:16 UTC (rev 4866)
@@ -284,8 +284,20 @@
 
 fontsize = prop.get_size_in_points()
 color = rgb2hex(gc.get_rgb())
+ write = self._svgwriter.write
 
 if rcParams['svg.embed_char_paths']:
+ new_chars = []
+ for c in s:
+ path = self._add_char_def(prop, c)
+ if path is not None:
+ new_chars.append(path)
+ if len(new_chars):
+ write('<defs>\n')
+ for path in new_chars:
+ write(path)
+ write('</defs>\n')
+
 svg = ['<g style="fill: %s; opacity: %s" transform="' % (color, gc.get_alpha())]
 if angle != 0:
 svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle))
@@ -297,7 +309,7 @@
 lastgind = None
 currx = 0
 for c in s:
- charid = self._add_char_def(prop, c)
+ charnum = self._get_char_def_id(prop, c)
 ccode = ord(c)
 gind = cmap.get(ccode)
 if gind is None:
@@ -312,7 +324,7 @@
 lastgind = gind
 currx += kern/64.0
 
- svg.append('<use xlink:href="#%s"' % charid)
+ svg.append('<use xlink:href="#%s"' % charnum)
 if currx != 0:
 svg.append(' transform="translate(%s)"' %
 (currx * (self.FONT_SCALE / fontsize)))
@@ -336,7 +348,7 @@
 svg = """\
 <text style="%(style)s" x="%(x)s" y="%(y)s" %(transform)s>%(thetext)s</text>
 """ % locals()
- self._svgwriter.write (svg)
+ write(svg)
 
 def _add_char_def(self, prop, char):
 if isinstance(prop, FontProperties):
@@ -347,9 +359,9 @@
 font.set_size(self.FONT_SCALE, 72)
 ps_name = font.get_sfnt()[(1,0,0,6)]
 char_id = urllib.quote('%s-%d' % (ps_name, ord(char)))
- char_num, path = self._char_defs.get(char_id, (None, None))
+ char_num = self._char_defs.get(char_id, None)
 if char_num is not None:
- return char_num
+ return None
 
 path_data = []
 glyph = font.load_char(ord(char), flags=LOAD_NO_HINTING)
@@ -378,9 +390,20 @@
 currx, curry = step[-2], -step[-1]
 char_num = 'c_%x' % len(self._char_defs)
 path_element = '<path id="%s" d="%s"/>\n' % (char_num, ''.join(path_data))
- self._char_defs[char_id] = (char_num, path_element)
- return char_num
+ self._char_defs[char_id] = char_num
+ return path_element
 
+ def _get_char_def_id(self, prop, char):
+ if isinstance(prop, FontProperties):
+ newprop = prop.copy()
+ font = self._get_font(newprop)
+ else:
+ font = prop
+ font.set_size(self.FONT_SCALE, 72)
+ ps_name = font.get_sfnt()[(1,0,0,6)]
+ char_id = urllib.quote('%s-%d' % (ps_name, ord(char)))
+ return self._char_defs[char_id]
+
 def _draw_mathtext(self, gc, x, y, s, prop, angle):
 """
 Draw math text using matplotlib.mathtext
@@ -390,12 +413,22 @@
 svg_glyphs = svg_elements.svg_glyphs
 svg_rects = svg_elements.svg_rects
 color = rgb2hex(gc.get_rgb())
+ write = self._svgwriter.write
 
- self.open_group("mathtext")
-
 style = "fill: %s" % color
 
 if rcParams['svg.embed_char_paths']:
+ new_chars = []
+ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
+ path = self._add_char_def(font, thetext)
+ if path is not None:
+ new_chars.append(path)
+ if len(new_chars):
+ write('<defs>\n')
+ for path in new_chars:
+ write(path)
+ write('</defs>\n')
+
 svg = ['<g style="%s" transform="' % style]
 if angle != 0:
 svg.append('translate(%s,%s)rotate(%1.1f)'
@@ -405,7 +438,7 @@
 svg.append('">\n')
 
 for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
- charid = self._add_char_def(font, thetext)
+ charid = self._get_char_def_id(font, thetext)
 
 svg.append('<use xlink:href="#%s" transform="translate(%s,%s)scale(%s)"/>\n' %
 (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE))
@@ -459,16 +492,12 @@
 svg.append('<rect x="%s" y="%s" width="%s" height="%s" fill="black" stroke="none" />' % (x, -y + height, width, height))
 svg.append("</g>")
 
- self._svgwriter.write (''.join(svg))
+ self.open_group("mathtext")
+ write (''.join(svg))
 self.close_group("mathtext")
 
 def finish(self):
 write = self._svgwriter.write
- if len(self._char_defs):
- write('<defs id="fontpaths">\n')
- for char_num, path in self._char_defs.values():
- write(path)
- write('</defs>\n')
 write('</svg>\n')
 
 def flipy(self):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月12日 13:36:28
Revision: 4865
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4865&view=rev
Author: jswhit
Date: 2008年01月12日 05:36:24 -0800 (2008年1月12日)
Log Message:
-----------
update download instructions
Modified Paths:
--------------
 trunk/toolkits/basemap/README
Modified: trunk/toolkits/basemap/README
===================================================================
--- trunk/toolkits/basemap/README	2008年01月12日 13:32:31 UTC (rev 4864)
+++ trunk/toolkits/basemap/README	2008年01月12日 13:36:24 UTC (rev 4865)
@@ -68,8 +68,11 @@
 
 0) Install pre-requisite python modules numpy and matplotlib.
 
-1) Then download basemap-X.Y.Z.tar.gz from
+1) Then download basemap-X.Y.Z.tar.gz (approx 32 mb) from
 the sourceforge download site, unpack and cd to basemap-X.Y.Z.
+If you want the full-resolution coastline dataset (useful if you
+will be making maps of very small regions), get 
+basemap-fullresdata-X.Y.Z.tar.gz (approx. 100 mb).
 
 2) Install the GEOS library. If you already have it on your
 system, just set the environment variable GEOS_DIR to point to the location 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月12日 13:32:39
Revision: 4864
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4864&view=rev
Author: jswhit
Date: 2008年01月12日 05:32:31 -0800 (2008年1月12日)
Log Message:
-----------
obsolete
Removed Paths:
-------------
 trunk/toolkits/basemap/MANIFEST-data
Deleted: trunk/toolkits/basemap/MANIFEST-data
===================================================================
--- trunk/toolkits/basemap/MANIFEST-data	2008年01月12日 00:12:10 UTC (rev 4863)
+++ trunk/toolkits/basemap/MANIFEST-data	2008年01月12日 13:32:31 UTC (rev 4864)
@@ -1,13 +0,0 @@
-MANIFEST-data
-LICENSE_data
-README
-setup-data.py
-lib/matplotlib/toolkits/basemap/data/__init__.py
-lib/matplotlib/toolkits/basemap/data/countries_f.dat
-lib/matplotlib/toolkits/basemap/data/countriesmeta_f.dat
-lib/matplotlib/toolkits/basemap/data/gshhs_f.dat
-lib/matplotlib/toolkits/basemap/data/gshhsmeta_f.dat
-lib/matplotlib/toolkits/basemap/data/rivers_f.dat
-lib/matplotlib/toolkits/basemap/data/riversmeta_f.dat
-lib/matplotlib/toolkits/basemap/data/states_f.dat
-lib/matplotlib/toolkits/basemap/data/statesmeta_f.dat
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4863
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4863&view=rev
Author: jswhit
Date: 2008年01月11日 16:12:10 -0800 (2008年1月11日)
Log Message:
-----------
not needed
Removed Paths:
-------------
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/__init__.py
Deleted: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/__init__.py
===================================================================
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月12日 00:00:30
Revision: 4862
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4862&view=rev
Author: jswhit
Date: 2008年01月11日 16:00:22 -0800 (2008年1月11日)
Log Message:
-----------
update install instructions.
Modified Paths:
--------------
 trunk/toolkits/basemap/README
Modified: trunk/toolkits/basemap/README
===================================================================
--- trunk/toolkits/basemap/README	2008年01月11日 23:59:04 UTC (rev 4861)
+++ trunk/toolkits/basemap/README	2008年01月12日 00:00:22 UTC (rev 4862)
@@ -89,19 +89,9 @@
 run the usual 'python setup.py install'. 
 
 4) To test, cd to the examples directory and run 'python simpletest.py'.
-On linux, if you get an import error (with a message about not
-finding libgeos.so) you may need to set the LD_LIBRARY_PATH environment
-to include $GEOS_DIR/lib. To run all the examples (except those that
-have extra dependenices or require an internet connection), execute
-'python run_all.py'.
+To run all the examples (except those that have extra dependencies
+or require an internet connection), execute 'python run_all.py'.
 
-5) if you want the full-resolution coastlines, download 
-basemap-data-fullres-X.Y.Z.tar.gz (about 70 mb), untar
-it, cd into basemap-data-fullres-X.Y.Z and
-run 'python setup-data.py install'. The fullres dataset does not
-change with every basemap release, so you may need to look back
-a couple of releases on the download page to find it.
-
 **Contact**
 
 Jeff Whitaker <jef...@no...>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月11日 23:59:13
Revision: 4861
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4861&view=rev
Author: jswhit
Date: 2008年01月11日 15:59:04 -0800 (2008年1月11日)
Log Message:
-----------
remove separate data package (won't work unless nested namespace
packages are used anyway)
Modified Paths:
--------------
 trunk/toolkits/basemap/MANIFEST.in
Removed Paths:
-------------
 trunk/toolkits/basemap/setup-data.py
 trunk/toolkits/basemap/setupegg-data.py
Modified: trunk/toolkits/basemap/MANIFEST.in
===================================================================
--- trunk/toolkits/basemap/MANIFEST.in	2008年01月11日 23:32:10 UTC (rev 4860)
+++ trunk/toolkits/basemap/MANIFEST.in	2008年01月11日 23:59:04 UTC (rev 4861)
@@ -84,54 +84,4 @@
 recursive-include lib/httplib2 *
 recursive-include lib/dbflib *
 recursive-include lib/shapelib *
-include lib/mpl_toolkits/basemap/data/5minmask.bin
-include lib/mpl_toolkits/basemap/data/GL27
-include lib/mpl_toolkits/basemap/data/countries_c.dat
-include lib/mpl_toolkits/basemap/data/countries_h.dat
-include lib/mpl_toolkits/basemap/data/countries_i.dat
-include lib/mpl_toolkits/basemap/data/countries_l.dat
-include lib/mpl_toolkits/basemap/data/countriesmeta_c.dat
-include lib/mpl_toolkits/basemap/data/countriesmeta_h.dat
-include lib/mpl_toolkits/basemap/data/countriesmeta_i.dat
-include lib/mpl_toolkits/basemap/data/countriesmeta_l.dat
-include lib/mpl_toolkits/basemap/data/epsg
-include lib/mpl_toolkits/basemap/data/esri
-include lib/mpl_toolkits/basemap/data/esri.extra
-include lib/mpl_toolkits/basemap/data/gshhs_c.dat
-include lib/mpl_toolkits/basemap/data/gshhs_h.dat
-include lib/mpl_toolkits/basemap/data/gshhs_i.dat
-include lib/mpl_toolkits/basemap/data/gshhs_l.dat
-include lib/mpl_toolkits/basemap/data/gshhsmeta_c.dat
-include lib/mpl_toolkits/basemap/data/gshhsmeta_h.dat
-include lib/mpl_toolkits/basemap/data/gshhsmeta_i.dat
-include lib/mpl_toolkits/basemap/data/gshhsmeta_l.dat
-include lib/mpl_toolkits/basemap/data/nad.lst
-include lib/mpl_toolkits/basemap/data/nad27
-include lib/mpl_toolkits/basemap/data/nad83
-include lib/mpl_toolkits/basemap/data/ntv2_out.dist
-include lib/mpl_toolkits/basemap/data/other.extra
-include lib/mpl_toolkits/basemap/data/pj_out27.dist
-include lib/mpl_toolkits/basemap/data/pj_out83.dist
-include lib/mpl_toolkits/basemap/data/proj_def.dat
-include lib/mpl_toolkits/basemap/data/rivers_c.dat
-include lib/mpl_toolkits/basemap/data/rivers_h.dat
-include lib/mpl_toolkits/basemap/data/rivers_i.dat
-include lib/mpl_toolkits/basemap/data/rivers_l.dat
-include lib/mpl_toolkits/basemap/data/riversmeta_c.dat
-include lib/mpl_toolkits/basemap/data/riversmeta_h.dat
-include lib/mpl_toolkits/basemap/data/riversmeta_i.dat
-include lib/mpl_toolkits/basemap/data/riversmeta_l.dat
-include lib/mpl_toolkits/basemap/data/states_c.dat
-include lib/mpl_toolkits/basemap/data/states_h.dat
-include lib/mpl_toolkits/basemap/data/states_i.dat
-include lib/mpl_toolkits/basemap/data/states_l.dat
-include lib/mpl_toolkits/basemap/data/statesmeta_c.dat
-include lib/mpl_toolkits/basemap/data/statesmeta_h.dat
-include lib/mpl_toolkits/basemap/data/statesmeta_i.dat
-include lib/mpl_toolkits/basemap/data/statesmeta_l.dat
-include lib/mpl_toolkits/basemap/data/td_out.dist
-include lib/mpl_toolkits/basemap/data/test27
-include lib/mpl_toolkits/basemap/data/test83
-include lib/mpl_toolkits/basemap/data/testntv2
-include lib/mpl_toolkits/basemap/data/testvarious
-include lib/mpl_toolkits/basemap/data/world
+recursive-include lib/mpl_toolkits/basemap/data *
Deleted: trunk/toolkits/basemap/setup-data.py
===================================================================
--- trunk/toolkits/basemap/setup-data.py	2008年01月11日 23:32:10 UTC (rev 4860)
+++ trunk/toolkits/basemap/setup-data.py	2008年01月11日 23:59:04 UTC (rev 4861)
@@ -1,41 +0,0 @@
-import sys, glob, os
-major, minor1, minor2, s, tmp = sys.version_info
-if major==2 and minor1<=3:
- # setuptools monkeypatches distutils.core.Distribution to support
- # package_data
- try: import setuptools
- except ImportError:
- raise SystemExit("""
-matplotlib requires setuptools for installation. Please download
-http://peak.telecommunity.com/dist/ez_setup.py and run it (as su if
-you are doing a system wide install) to install the proper version of
-setuptools for your system""")
- raise SystemExit("""The basemap toolkit requires python 2.4.""")
-from distutils.core import setup
-
-packages = ['mpl_toolkits.basemap.data']
-package_dirs = {'':'lib'}
-boundaryfiles = glob.glob("lib/matplotlib/toolkits/basemap/data/*_f.dat")
-basemap_datafiles = [os.path.basename(bfile) for bfile in boundaryfiles]
-package_data = {'mpl_toolkits.basemap.data':basemap_datafiles}
-setup(
- name = "basemap-data-fullres",
- version = "0.9.7",
- description = "full-resolution boundary data for basemap",
- url = "http://matplotlib.sourceforge.net/toolkits.html",
- download_url = "http://sourceforge.net/projects/matplotlib",
- author = "Jeff Whitaker",
- author_email = "jef...@no...",
- platforms = ["any"],
- license = "OSI Approved",
- keywords = ["python","plotting","plots","graphs","charts","GIS","mapping","map projections","maps"],
- classifiers = ["Development Status :: 4 - Beta",
-			 "Intended Audience :: Science/Research", 
-			 "License :: OSI Approved", 
-			 "Topic :: Scientific/Engineering :: Visualization",
-			 "Topic :: Software Development :: Libraries :: Python Modules",
-			 "Operating System :: OS Independent"],
- packages = packages,
- package_dir = package_dirs,
- package_data = package_data
- )
Deleted: trunk/toolkits/basemap/setupegg-data.py
===================================================================
--- trunk/toolkits/basemap/setupegg-data.py	2008年01月11日 23:32:10 UTC (rev 4860)
+++ trunk/toolkits/basemap/setupegg-data.py	2008年01月11日 23:59:04 UTC (rev 4861)
@@ -1,8 +0,0 @@
-"""
-Poor man's setuptools script...
-"""
-
-from setuptools import setup
-execfile('setup-data.py',
- {'additional_params' :
- {'namespace_packages' : ['mpl_toolkits']}})
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月11日 23:32:20
Revision: 4860
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4860&view=rev
Author: jswhit
Date: 2008年01月11日 15:32:10 -0800 (2008年1月11日)
Log Message:
-----------
fixed installation of fullres data for new mpl_toolkits namespace
Modified Paths:
--------------
 trunk/toolkits/basemap/setup-data.py
 trunk/toolkits/basemap/setupegg-data.py
Modified: trunk/toolkits/basemap/setup-data.py
===================================================================
--- trunk/toolkits/basemap/setup-data.py	2008年01月11日 21:08:45 UTC (rev 4859)
+++ trunk/toolkits/basemap/setup-data.py	2008年01月11日 23:32:10 UTC (rev 4860)
@@ -3,21 +3,21 @@
 if major==2 and minor1<=3:
 # setuptools monkeypatches distutils.core.Distribution to support
 # package_data
- #try: import setuptools
- #except ImportError:
- # raise SystemExit("""
-#matplotlib requires setuptools for installation. Please download
-#http://peak.telecommunity.com/dist/ez_setup.py and run it (as su if
-#you are doing a system wide install) to install the proper version of
-#setuptools for your system""")
+ try: import setuptools
+ except ImportError:
+ raise SystemExit("""
+matplotlib requires setuptools for installation. Please download
+http://peak.telecommunity.com/dist/ez_setup.py and run it (as su if
+you are doing a system wide install) to install the proper version of
+setuptools for your system""")
 raise SystemExit("""The basemap toolkit requires python 2.4.""")
 from distutils.core import setup
 
-packages = ['matplotlib.toolkits.basemap.data']
+packages = ['mpl_toolkits.basemap.data']
 package_dirs = {'':'lib'}
 boundaryfiles = glob.glob("lib/matplotlib/toolkits/basemap/data/*_f.dat")
 basemap_datafiles = [os.path.basename(bfile) for bfile in boundaryfiles]
-package_data = {'matplotlib.toolkits.basemap.data':basemap_datafiles}
+package_data = {'mpl_toolkits.basemap.data':basemap_datafiles}
 setup(
 name = "basemap-data-fullres",
 version = "0.9.7",
Modified: trunk/toolkits/basemap/setupegg-data.py
===================================================================
--- trunk/toolkits/basemap/setupegg-data.py	2008年01月11日 21:08:45 UTC (rev 4859)
+++ trunk/toolkits/basemap/setupegg-data.py	2008年01月11日 23:32:10 UTC (rev 4860)
@@ -3,4 +3,6 @@
 """
 
 from setuptools import setup
-execfile('setup-data.py')
+execfile('setup-data.py',
+ {'additional_params' :
+ {'namespace_packages' : ['mpl_toolkits']}})
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <cm...@us...> - 2008年01月11日 21:08:55
Revision: 4859
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4859&view=rev
Author: cmoad
Date: 2008年01月11日 13:08:45 -0800 (2008年1月11日)
Log Message:
-----------
added explicit compiler flag to win32 build notes
Modified Paths:
--------------
 trunk/matplotlib/setupext.py
Modified: trunk/matplotlib/setupext.py
===================================================================
--- trunk/matplotlib/setupext.py	2008年01月10日 19:32:16 UTC (rev 4858)
+++ trunk/matplotlib/setupext.py	2008年01月11日 21:08:45 UTC (rev 4859)
@@ -37,7 +37,7 @@
 http://matplotlib.sourceforge.net/win32_static_vs.tar.gz and
 see the README in that dir
 
- > python setup.py build bdist_wininst
+ > python setup.py build --compiler=msvc bdist_wininst
 
 """
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 19:32:19
Revision: 4858
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4858&view=rev
Author: jswhit
Date: 2008年01月10日 11:32:16 -0800 (2008年1月10日)
Log Message:
-----------
remove duplicate data files, change import to mpl_toolkits.
Modified Paths:
--------------
 trunk/htdocs/screenshots/contour_shot.py
 trunk/htdocs/screenshots/plotmap.py
Removed Paths:
-------------
 trunk/htdocs/screenshots/etopo20data.gz
 trunk/htdocs/screenshots/etopo20lats.gz
 trunk/htdocs/screenshots/etopo20lons.gz
Modified: trunk/htdocs/screenshots/contour_shot.py
===================================================================
--- trunk/htdocs/screenshots/contour_shot.py	2008年01月10日 18:38:56 UTC (rev 4857)
+++ trunk/htdocs/screenshots/contour_shot.py	2008年01月10日 19:32:16 UTC (rev 4858)
@@ -1,17 +1,14 @@
-from matplotlib.toolkits.basemap import Basemap, interp
+from mpl_toolkits.basemap import Basemap, interp
 from pylab import *
-import cPickle
 
 # read in data on lat/lon grid.
-hgt = array(load('data/500hgtdata.gz'),'d')
-lons = array(load('data/500hgtlons.gz'),'d')
-lats = array(load('data/500hgtlats.gz'),'d')
+hgt = load('data/500hgtdata.gz')
+lons = load('data/500hgtlons.gz')
+lats = load('data/500hgtlats.gz')
 lons, lats = meshgrid(lons,lats)
 
 # set up map projection (lambert azimuthal equal area).
-m = Basemap(-135.,-20.,45.,-20.,
- resolution='c',area_thresh=10000.,projection='laea',
- lat_0=90.,lon_0=-90.)
+m = Basemap(projection='nplaea',lon_0=-90,boundinglat=15.,resolution='c')
 
 cmap = cm.jet
 fig = figure(figsize=(6,6))
@@ -19,8 +16,8 @@
 ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
 
 x,y = m(lons, lats)
-cs = contour(x,y,hgt,15,linewidths=0.5,colors='k')
-cs = contourf(x,y,hgt,15,cmap=cmap,colors=None)
+cs = m.contour(x,y,hgt,15,linewidths=0.5,colors='k')
+cs = m.contourf(x,y,hgt,15,cmap=cm.jet)
 
 # draw map.
 m.drawcoastlines()
Deleted: trunk/htdocs/screenshots/etopo20data.gz
===================================================================
(Binary files differ)
Deleted: trunk/htdocs/screenshots/etopo20lats.gz
===================================================================
(Binary files differ)
Deleted: trunk/htdocs/screenshots/etopo20lons.gz
===================================================================
(Binary files differ)
Modified: trunk/htdocs/screenshots/plotmap.py
===================================================================
--- trunk/htdocs/screenshots/plotmap.py	2008年01月10日 18:38:56 UTC (rev 4857)
+++ trunk/htdocs/screenshots/plotmap.py	2008年01月10日 19:32:16 UTC (rev 4858)
@@ -4,15 +4,15 @@
 
 # the data is interpolated to the native projection grid.
 
-from matplotlib.toolkits.basemap import Basemap, shiftgrid
+from mpl_toolkits.basemap import Basemap, shiftgrid
 from pylab import title, colorbar, show, axes, cm, load, arange, figure, \
 text
 
 # read in topo data (on a regular lat/lon grid)
 # longitudes go from 20 to 380.
-topoin = load('etopo20data.gz')
-lons = load('etopo20lons.gz')
-lats = load('etopo20lats.gz')
+topoin = load('data/etopo20data.gz')
+lons = load('data/etopo20lons.gz')
+lats = load('data/etopo20lats.gz')
 # shift data so lons go from -180 to 180 instead of 20 to 380.
 topoin,lons = shiftgrid(180.,topoin,lons,start=False)
 
@@ -32,7 +32,11 @@
 # plot image over map with imshow.
 im = m.imshow(topodat,cm.jet)
 # setup colorbar axes instance.
-l,b,w,h = ax.get_position()
+# for matplotlib 0.91 and earlier, could do l,b,w,h = ax.get_position()
+# for post 0.91, pos = ax.get_position(); l,b,w,h = pos.bounds
+# this works for both.
+pos = ax.get_position()
+l, b, w, h = getattr(pos, 'bounds', pos)
 cax = axes([l+w+0.075, b, 0.05, h])
 colorbar(cax=cax) # draw colorbar
 axes(ax) # make the original axes current again
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 18:38:58
Revision: 4857
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4857&view=rev
Author: jswhit
Date: 2008年01月10日 10:38:56 -0800 (2008年1月10日)
Log Message:
-----------
toolkits moved to mpl_toolkits
Modified Paths:
--------------
 trunk/htdocs/hthelpers.py
Modified: trunk/htdocs/hthelpers.py
===================================================================
--- trunk/htdocs/hthelpers.py	2008年01月10日 16:42:31 UTC (rev 4856)
+++ trunk/htdocs/hthelpers.py	2008年01月10日 18:38:56 UTC (rev 4857)
@@ -46,7 +46,7 @@
 'matplotlib.texmanager',
 'matplotlib.text',
 'matplotlib.ticker',
- 'matplotlib.toolkits.basemap.basemap',
+ 'mpl_toolkits.basemap.basemap',
 'matplotlib.transforms',
 'matplotlib.type1font',
 'matplotlib.units',
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2008年01月10日 16:42:34
Revision: 4856
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4856&view=rev
Author: mdboom
Date: 2008年01月10日 08:42:31 -0800 (2008年1月10日)
Log Message:
-----------
Merged revisions 4844-4855 via svnmerge from 
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_91_maint
........
 r4846 | mdboom | 2008年01月10日 08:38:37 -0500 (2008年1月10日) | 3 lines
 
 Merge Darren's win32 build changes to the maintenance branch (since
 they'll be handy there also).
........
 r4854 | mdboom | 2008年01月10日 11:37:18 -0500 (2008年1月10日) | 2 lines
 
 Fix display of '[' and ']' in mathtext.
........
 r4855 | mdboom | 2008年01月10日 11:40:54 -0500 (2008年1月10日) | 2 lines
 
 Update changelog.
........
Modified Paths:
--------------
 trunk/matplotlib/CHANGELOG
 trunk/matplotlib/lib/matplotlib/mathtext.py
Property Changed:
----------------
 trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Name: svnmerge-integrated
 - /branches/v0_91_maint:1-4843
 + /branches/v0_91_maint:1-4855
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG	2008年01月10日 16:40:54 UTC (rev 4855)
+++ trunk/matplotlib/CHANGELOG	2008年01月10日 16:42:31 UTC (rev 4856)
@@ -4,6 +4,15 @@
 2008年01月10日 Use setup.cfg to set the default parameters (tkagg,
 numpy) when building windows installers - DSD
 
+2008年01月10日 Fix bug displaying [ and ] in mathtext - MGD
+
+2008年01月10日 Fix bug when displaying a tick value offset with scientific
+ notation. (Manifests itself as a warning that the \times
+ symbol can not be found). - MGD
+
+2008年01月10日 Use setup.cfg to set the default parameters (tkagg,
+ numpy) when building windows installers - DSD
+
 ===============================================================
 2008年01月06日 Released 0.91.2 at revision 4802
 
Modified: trunk/matplotlib/lib/matplotlib/mathtext.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mathtext.py	2008年01月10日 16:40:54 UTC (rev 4855)
+++ trunk/matplotlib/lib/matplotlib/mathtext.py	2008年01月10日 16:42:31 UTC (rev 4856)
@@ -2057,7 +2057,7 @@
 ).setParseAction(self.customspace).setName('customspace')
 
 unicode_range = u"\U00000080-\U0001ffff"
- symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!'@()|%s])|(\\[%%${}\[\]_|])" % unicode_range)
+ symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!'@()\[\]|%s])|(\\[%%${}\[\]_|])" % unicode_range)
 | Combine(
 bslash
 + oneOf(tex2uni.keys())
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2008年01月10日 16:40:56
Revision: 4855
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4855&view=rev
Author: mdboom
Date: 2008年01月10日 08:40:54 -0800 (2008年1月10日)
Log Message:
-----------
Update changelog.
Modified Paths:
--------------
 branches/v0_91_maint/CHANGELOG
Modified: branches/v0_91_maint/CHANGELOG
===================================================================
--- branches/v0_91_maint/CHANGELOG	2008年01月10日 16:37:18 UTC (rev 4854)
+++ branches/v0_91_maint/CHANGELOG	2008年01月10日 16:40:54 UTC (rev 4855)
@@ -1,3 +1,5 @@
+2008年01月10日 Fix bug displaying [ and ] in mathtext - MGD
+
 2008年01月10日 Fix bug when displaying a tick value offset with scientific
 notation. (Manifests itself as a warning that the \times
 symbol can not be found). - MGD
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4854
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4854&view=rev
Author: mdboom
Date: 2008年01月10日 08:37:18 -0800 (2008年1月10日)
Log Message:
-----------
Fix display of '[' and ']' in mathtext.
Modified Paths:
--------------
 branches/v0_91_maint/lib/matplotlib/mathtext.py
Modified: branches/v0_91_maint/lib/matplotlib/mathtext.py
===================================================================
--- branches/v0_91_maint/lib/matplotlib/mathtext.py	2008年01月10日 16:01:02 UTC (rev 4853)
+++ branches/v0_91_maint/lib/matplotlib/mathtext.py	2008年01月10日 16:37:18 UTC (rev 4854)
@@ -2058,7 +2058,7 @@
 ).setParseAction(self.customspace).setName('customspace')
 
 unicode_range = u"\U00000080-\U0001ffff"
- symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!'@()|%s])|(\\[%%${}\[\]_|])" % unicode_range)
+ symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!'@()\[\]|%s])|(\\[%%${}\[\]_|])" % unicode_range)
 | Combine(
 bslash
 + oneOf(tex2uni.keys())
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 16:01:13
Revision: 4853
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4853&view=rev
Author: jswhit
Date: 2008年01月10日 08:01:02 -0800 (2008年1月10日)
Log Message:
-----------
include setupegg.py
Modified Paths:
--------------
 trunk/toolkits/basemap/MANIFEST.in
Modified: trunk/toolkits/basemap/MANIFEST.in
===================================================================
--- trunk/toolkits/basemap/MANIFEST.in	2008年01月10日 15:57:28 UTC (rev 4852)
+++ trunk/toolkits/basemap/MANIFEST.in	2008年01月10日 16:01:02 UTC (rev 4853)
@@ -8,6 +8,7 @@
 include KNOWN_BUGS
 include Changelog
 include setup.py
+include setupegg.py
 include src/*
 include examples/simpletest.py
 include examples/hires.py
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4852
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4852&view=rev
Author: jswhit
Date: 2008年01月10日 07:57:28 -0800 (2008年1月10日)
Log Message:
-----------
add missing files
Added Paths:
-----------
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/pupynere.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/pyproj.py
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/netcdftime.py	2008年01月10日 15:57:28 UTC (rev 4852)
@@ -0,0 +1,853 @@
+"""
+Performs conversions of netCDF time coordinate data to/from datetime objects.
+"""
+import math, numpy, re, time
+from datetime import datetime as real_datetime
+
+_units = ['days','hours','minutes','seconds','day','hour','minute','second']
+_calendars = ['standard','gregorian','proleptic_gregorian','noleap','julian','all_leap','365_day','366_day','360_day']
+
+__version__ = '0.6'
+
+class datetime:
+ """
+Phony datetime object which mimics the python datetime object,
+but allows for dates that don't exist in the proleptic gregorian calendar.
+Doesn't do timedelta operations, doesn't overload + and -.
+
+Has strftime, timetuple and __repr__ methods. The format
+of the string produced by __repr__ is controlled by self.format
+(default %Y-%m-%d %H:%M:%S).
+
+Instance variables are year,month,day,hour,minute,second,dayofwk,dayofyr
+and format.
+ """
+ def __init__(self,year,month,day,hour=0,minute=0,second=0,dayofwk=-1,dayofyr=1):
+ """dayofyr set to 1 by default - otherwise time.strftime will complain"""
+ self.year=year
+ self.month=month
+ self.day=day
+ self.hour=hour
+ self.minute=minute
+ self.dayofwk=dayofwk
+ self.dayofyr=dayofyr
+ self.second=second
+ self.format='%Y-%m-%d %H:%M:%S'
+ def strftime(self,format=None):
+ if format is None:
+ format = self.format
+ return _strftime(self,format)
+ def timetuple(self):
+ return (self.year,self.month,self.day,self.hour,self.minute,self.second,self.dayofwk,self.dayofyr,-1)
+ def __repr__(self):
+ return self.strftime(self.format)
+
+def JulianDayFromDate(date,calendar='standard'):
+
+ """
+
+creates a Julian Day from a 'datetime-like' object. Returns the fractional
+Julian Day (resolution 1 second).
+
+if calendar='standard' or 'gregorian' (default), Julian day follows Julian 
+Calendar on and before 1582年10月5日, Gregorian calendar after 1582年10月15日.
+
+if calendar='proleptic_gregorian', Julian Day follows gregorian calendar.
+
+if calendar='julian', Julian Day follows julian calendar.
+
+Algorithm:
+
+Meeus, Jean (1998) Astronomical Algorithms (2nd Edition). Willmann-Bell,
+Virginia. p. 63
+
+ """
+ 
+ # based on redate.py by David Finlayson.
+
+ year=date.year; month=date.month; day=date.day
+ hour=date.hour; minute=date.minute; second=date.second
+ # Convert time to fractions of a day
+ day = day + hour/24.0 + minute/1440.0 + second/86400.0
+
+ # Start Meeus algorithm (variables are in his notation)
+ if (month < 3):
+ month = month + 12
+ year = year - 1
+ 
+ A = int(year/100)
+
+ jd = int(365.25 * (year + 4716)) + int(30.6001 * (month + 1)) + \
+ day - 1524.5
+
+ # optionally adjust the jd for the switch from 
+ # the Julian to Gregorian Calendar
+ # here assumed to have occurred the day after 1582 October 4
+ if calendar in ['standard','gregorian']:
+ if jd >= 2299170.5:
+ # 1582 October 15 (Gregorian Calendar)
+ B = 2 - A + int(A/4)
+ elif jd < 2299160.5:
+ # 1582 October 5 (Julian Calendar)
+ B = 0
+ else:
+ raise ValueError, 'impossible date (falls in gap between end of Julian calendar and beginning of Gregorian calendar'
+ elif calendar == 'proleptic_gregorian':
+ B = 2 - A + int(A/4)
+ elif calendar == 'julian':
+ B = 0
+ else:
+ raise ValueError, 'unknown calendar, must be one of julian,standard,gregorian,proleptic_gregorian, got %s' % calendar
+ 
+ # adjust for Julian calendar if necessary
+ jd = jd + B
+ 
+ return jd 
+
+def _NoLeapDayFromDate(date):
+
+ """
+
+creates a Julian Day for a calendar with no leap years from a datetime 
+instance. Returns the fractional Julian Day (resolution 1 second).
+
+ """
+ 
+ year=date.year; month=date.month; day=date.day
+ hour=date.hour; minute=date.minute; second=date.second
+ # Convert time to fractions of a day
+ day = day + hour/24.0 + minute/1440.0 + second/86400.0
+
+ # Start Meeus algorithm (variables are in his notation)
+ if (month < 3):
+ month = month + 12
+ year = year - 1
+ 
+ jd = int(365. * (year + 4716)) + int(30.6001 * (month + 1)) + \
+ day - 1524.5
+ 
+ return jd 
+
+def _AllLeapFromDate(date):
+
+ """
+
+creates a Julian Day for a calendar where all years have 366 days from
+a 'datetime-like' object.
+Returns the fractional Julian Day (resolution 1 second).
+
+ """
+ 
+ year=date.year; month=date.month; day=date.day
+ hour=date.hour; minute=date.minute; second=date.second
+ # Convert time to fractions of a day
+ day = day + hour/24.0 + minute/1440.0 + second/86400.0
+
+ # Start Meeus algorithm (variables are in his notation)
+ if (month < 3):
+ month = month + 12
+ year = year - 1
+ 
+ jd = int(366. * (year + 4716)) + int(30.6001 * (month + 1)) + \
+ day - 1524.5
+ 
+ return jd 
+
+def _360DayFromDate(date):
+
+ """
+
+creates a Julian Day for a calendar where all months have 30 daysfrom
+a 'datetime-like' object.
+Returns the fractional Julian Day (resolution 1 second).
+
+ """
+ 
+ year=date.year; month=date.month; day=date.day
+ hour=date.hour; minute=date.minute; second=date.second
+ # Convert time to fractions of a day
+ day = day + hour/24.0 + minute/1440.0 + second/86400.0
+
+ jd = int(360. * (year + 4716)) + int(30. * (month - 1)) + day
+ 
+ return jd 
+
+def DateFromJulianDay(JD,calendar='standard'):
+ """
+
+returns a 'datetime-like' object given Julian Day. Julian Day is a 
+fractional day with a resolution of 1 second.
+
+if calendar='standard' or 'gregorian' (default), Julian day follows Julian 
+Calendar on and before 1582年10月5日, Gregorian calendar after 1582年10月15日.
+
+if calendar='proleptic_gregorian', Julian Day follows gregorian calendar.
+
+if calendar='julian', Julian Day follows julian calendar.
+
+The datetime object is a 'real' datetime object if the date falls in
+the Gregorian calendar (i.e. calendar='proleptic_gregorian', or
+calendar = 'standard'/'gregorian' and the date is after 1582年10月15日).
+Otherwise, it's a 'phony' datetime object which is actually an instance
+of netcdftime.datetime.
+
+
+Algorithm:
+
+Meeus, Jean (1998) Astronomical Algorithms (2nd Edition). Willmann-Bell,
+Virginia. p. 63
+
+ """
+
+ # based on redate.py by David Finlayson.
+ 
+ if JD < 0:
+ raise ValueError, 'Julian Day must be positive'
+
+ dayofwk = int(math.fmod(int(JD + 1.5),7))
+ (F, Z) = math.modf(JD + 0.5)
+ Z = int(Z)
+ if calendar in ['standard','gregorian']:
+ if JD < 2299160.5:
+ A = Z
+ else:
+ alpha = int((Z - 1867216.25)/36524.25)
+ A = Z + 1 + alpha - int(alpha/4)
+
+ elif calendar == 'proleptic_gregorian':
+ alpha = int((Z - 1867216.25)/36524.25)
+ A = Z + 1 + alpha - int(alpha/4)
+ elif calendar == 'julian':
+ A = Z
+ else:
+ raise ValueError, 'unknown calendar, must be one of julian,standard,gregorian,proleptic_gregorian, got %s' % calendar
+
+ B = A + 1524
+ C = int((B - 122.1)/365.25)
+ D = int(365.25 * C)
+ E = int((B - D)/30.6001)
+
+ # Convert to date
+ day = B - D - int(30.6001 * E) + F
+ nday = B-D-123
+ if nday <= 305:
+ dayofyr = nday+60
+ else:
+ dayofyr = nday-305
+ if E < 14:
+ month = E - 1
+ else:
+ month = E - 13
+
+ if month > 2:
+ year = C - 4716
+ else:
+ year = C - 4715
+
+ # a leap year?
+ leap = 0
+ if year % 4 == 0:
+ leap = 1
+ if calendar == 'proleptic_gregorian' or \
+ (calendar in ['standard','gregorian'] and JD >= 2299160.5):
+ if year % 100 == 0 and year % 400 != 0: 
+ print year % 100, year % 400
+ leap = 0
+ if leap and month > 2:
+ dayofyr = dayofyr + leap
+ 
+ # Convert fractions of a day to time 
+ (dfrac, days) = math.modf(day/1.0)
+ (hfrac, hours) = math.modf(dfrac * 24.0)
+ (mfrac, minutes) = math.modf(hfrac * 60.0)
+ seconds = round(mfrac * 60.0) # seconds are rounded
+ 
+ if seconds > 59:
+ seconds = 0
+ minutes = minutes + 1
+ if minutes > 59:
+ minutes = 0
+ hours = hours + 1
+ if hours > 23:
+ hours = 0
+ days = days + 1
+ 
+ # return a 'real' datetime instance if calendar is gregorian.
+ if calendar == 'proleptic_gregorian' or \
+ (calendar in ['standard','gregorian'] and JD >= 2299160.5):
+ return real_datetime(year,month,int(days),int(hours),int(minutes),int(seconds))
+ else:
+ # or else, return a 'datetime-like' instance.
+ return datetime(year,month,int(days),int(hours),int(minutes),int(seconds),dayofwk,dayofyr)
+
+def _DateFromNoLeapDay(JD):
+ """
+
+returns a 'datetime-like' object given Julian Day for a calendar with no leap 
+days. Julian Day is a fractional day with a resolution of 1 second.
+
+ """
+
+ # based on redate.py by David Finlayson.
+ 
+ if JD < 0:
+ raise ValueError, 'Julian Day must be positive'
+
+ dayofwk = int(math.fmod(int(JD + 1.5),7))
+ (F, Z) = math.modf(JD + 0.5)
+ Z = int(Z)
+ A = Z
+ B = A + 1524
+ C = int((B - 122.1)/365.)
+ D = int(365. * C)
+ E = int((B - D)/30.6001)
+
+ # Convert to date
+ day = B - D - int(30.6001 * E) + F
+ nday = B-D-123
+ if nday <= 305:
+ dayofyr = nday+60
+ else:
+ dayofyr = nday-305
+ if E < 14:
+ month = E - 1
+ else:
+ month = E - 13
+
+ if month > 2:
+ year = C - 4716
+ else:
+ year = C - 4715
+ 
+ # Convert fractions of a day to time 
+ (dfrac, days) = math.modf(day/1.0)
+ (hfrac, hours) = math.modf(dfrac * 24.0)
+ (mfrac, minutes) = math.modf(hfrac * 60.0)
+ seconds = round(mfrac * 60.0) # seconds are rounded
+ 
+ if seconds > 59:
+ seconds = 0
+ minutes = minutes + 1
+ if minutes > 59:
+ minutes = 0
+ hours = hours + 1
+ if hours > 23:
+ hours = 0
+ days = days + 1
+ 
+ return datetime(year,month,int(days),int(hours),int(minutes),int(seconds), dayofwk, dayofyr)
+
+def _DateFromAllLeap(JD):
+ """
+
+returns a 'datetime-like' object given Julian Day for a calendar where all
+years have 366 days.
+Julian Day is a fractional day with a resolution of 1 second.
+
+ """
+
+ # based on redate.py by David Finlayson.
+ 
+ if JD < 0:
+ raise ValueError, 'Julian Day must be positive'
+
+ dayofwk = int(math.fmod(int(JD + 1.5),7))
+ (F, Z) = math.modf(JD + 0.5)
+ Z = int(Z)
+ A = Z
+ B = A + 1524
+ C = int((B - 122.1)/366.)
+ D = int(366. * C)
+ E = int((B - D)/30.6001)
+
+ # Convert to date
+ day = B - D - int(30.6001 * E) + F
+ nday = B-D-123
+ if nday <= 305:
+ dayofyr = nday+60
+ else:
+ dayofyr = nday-305
+ if E < 14:
+ month = E - 1
+ else:
+ month = E - 13
+ if month > 2:
+ dayofyr = dayofyr+1
+
+ if month > 2:
+ year = C - 4716
+ else:
+ year = C - 4715
+ 
+ # Convert fractions of a day to time 
+ (dfrac, days) = math.modf(day/1.0)
+ (hfrac, hours) = math.modf(dfrac * 24.0)
+ (mfrac, minutes) = math.modf(hfrac * 60.0)
+ seconds = round(mfrac * 60.0) # seconds are rounded
+ 
+ if seconds > 59:
+ seconds = 0
+ minutes = minutes + 1
+ if minutes > 59:
+ minutes = 0
+ hours = hours + 1
+ if hours > 23:
+ hours = 0
+ days = days + 1
+ 
+ return datetime(year,month,int(days),int(hours),int(minutes),int(seconds), dayofwk, dayofyr)
+
+def _DateFrom360Day(JD):
+ """
+
+returns a 'datetime-like' object given Julian Day for a calendar where all
+months have 30 days.
+Julian Day is a fractional day with a resolution of 1 second.
+
+ """
+
+ if JD < 0:
+ raise ValueError, 'Julian Day must be positive'
+
+ #jd = int(360. * (year + 4716)) + int(30. * (month - 1)) + day
+ (F, Z) = math.modf(JD)
+ year = int((Z-0.5)/360.) - 4716
+ dayofyr = JD - (year+4716)*360 
+ month = int((dayofyr-0.5)/30)+1
+ day = dayofyr - (month-1)*30 + F 
+ 
+ # Convert fractions of a day to time 
+ (dfrac, days) = math.modf(day/1.0)
+ (hfrac, hours) = math.modf(dfrac * 24.0)
+ (mfrac, minutes) = math.modf(hfrac * 60.0)
+ seconds = round(mfrac * 60.0) # seconds are rounded
+ 
+ if seconds > 59:
+ seconds = 0
+ minutes = minutes + 1
+ if minutes > 59:
+ minutes = 0
+ hours = hours + 1
+ if hours > 23:
+ hours = 0
+ days = days + 1
+ 
+ return datetime(year,month,int(days),int(hours),int(minutes),int(seconds),-1, int(dayofyr))
+
+def _dateparse(timestr):
+ """parse a string of the form time-units since yyyy-mm-dd hh:mm:ss
+ return a tuple (units, datetimeinstance)"""
+ timestr_split = timestr.split()
+ units = timestr_split[0].lower()
+ if units not in _units:
+ raise ValueError,"units must be one of 'seconds', 'minutes', 'hours' or 'days' (or singular version of these), got '%s'" % units
+ if timestr_split[1].lower() != 'since':
+ raise ValueError,"no 'since' in unit_string"
+ # parse the date string.
+ n = timestr.find('since')+6
+ year,month,day,hour,minute,second,utc_offset = _parse_date(timestr[n:])
+ return units, utc_offset, datetime(year, month, day, hour, minute, second)
+
+class utime:
+ """
+Performs conversions of netCDF time coordinate
+data to/from datetime objects.
+
+To initialize: C{t = utime(unit_string,calendar='standard')}
+
+where 
+
+B{C{unit_string}} is a string of the form
+C{'time-units since <time-origin>'} defining the time units.
+
+Valid time-units are days, hours, minutes and seconds (the singular forms 
+are also accepted). An example unit_string would be C{'hours 
+since 0001年01月01日 00:00:00'}.
+
+The B{C{calendar}} keyword describes the calendar used in the time calculations. 
+All the values currently defined in the U{CF metadata convention 
+<http://www.cgd.ucar.edu/cms/eaton/cf-metadata/CF-1.0.html#time>} are 
+accepted. The default is C{'standard'}, which corresponds to the mixed 
+Gregorian/Julian calendar used by the C{udunits library}. Valid calendars 
+are:
+
+C{'gregorian'} or C{'standard'} (default):
+
+Mixed Gregorian/Julian calendar as defined by udunits.
+
+C{'proleptic_gregorian'}:
+
+A Gregorian calendar extended to dates before 1582年10月15日. That is, a year 
+is a leap year if either (i) it is divisible by 4 but not by 100 or (ii) 
+it is divisible by 400.
+
+C{'noleap'} or C{'365_day'}:
+
+Gregorian calendar without leap years, i.e., all years are 365 days long. 
+all_leap or 366_day Gregorian calendar with every year being a leap year, 
+i.e., all years are 366 days long.
+
+C{'360_day'}:
+
+All years are 360 days divided into 30 day months. 
+
+C{'julian'}:
+
+Proleptic Julian calendar, extended to dates after 1582年10月5日. A year is a 
+leap year if it is divisible by 4.
+
+The C{L{num2date}} and C{L{date2num}} class methods can used to convert datetime 
+instances to/from the specified time units using the specified calendar.
+
+The datetime instances returned by C{num2date} are 'real' python datetime 
+objects if the date falls in the Gregorian calendar (i.e. 
+C{calendar='proleptic_gregorian', 'standard'} or C{'gregorian'} and 
+the date is after 1582年10月15日). Otherwise, they are 'phony' datetime 
+objects which are actually instances of C{L{netcdftime.datetime}}. This is 
+because the python datetime module cannot handle the weird dates in some 
+calendars (such as C{'360_day'} and C{'all_leap'}) which don't exist in any real 
+world calendar.
+
+
+Example usage:
+
+>>> from netcdftime import utime
+>>> from datetime import datetime
+>>> cdftime = utime('hours since 0001年01月01日 00:00:00')
+>>> date = datetime.now()
+>>> print date
+2006年03月17日 16:04:02.561678
+>>>
+>>> t = cdftime.date2num(date)
+>>> print t
+17577328.0672
+>>>
+>>> date = cdftime.num2date(t)
+>>> print date
+2006年03月17日 16:04:02
+>>>
+
+The resolution of the transformation operation is 1 second.
+ 
+Warning: Dates between 1582年10月5日 and 1582年10月15日 do not exist in the 
+C{'standard'} or C{'gregorian'} calendars. An exception will be raised if you pass 
+a 'datetime-like' object in that range to the C{L{date2num}} class method.
+
+Words of Wisdom from the British MetOffice concerning reference dates 
+U{http://www.metoffice.com/research/hadleycentre/models/GDT/ch26.html}:
+
+"udunits implements the mixed Gregorian/Julian calendar system, as 
+followed in England, in which dates prior to 1582年10月15日 are assumed to use 
+the Julian calendar. Other software cannot be relied upon to handle the 
+change of calendar in the same way, so for robustness it is recommended 
+that the reference date be later than 1582. If earlier dates must be used, 
+it should be noted that udunits treats 0 AD as identical to 1 AD."
+
+@ivar origin: datetime instance defining the origin of the netCDF time variable.
+@ivar calendar: the calendar used (as specified by the C{calendar} keyword).
+@ivar unit_string: a string defining the the netCDF time variable.
+@ivar units: the units part of C{unit_string} (i.e. 'days', 'hours', 'seconds').
+ """
+ def __init__(self,unit_string,calendar='standard'):
+ """
+@param unit_string: a string of the form
+C{'time-units since <time-origin>'} defining the time units.
+
+Valid time-units are days, hours, minutes and seconds (the singular forms 
+are also accepted). An example unit_string would be C{'hours 
+since 0001年01月01日 00:00:00'}.
+
+@keyword calendar: describes the calendar used in the time calculations. 
+All the values currently defined in the U{CF metadata convention 
+<http://www.cgd.ucar.edu/cms/eaton/cf-metadata/CF-1.0.html#time>} are 
+accepted. The default is C{'standard'}, which corresponds to the mixed 
+Gregorian/Julian calendar used by the C{udunits library}. Valid calendars 
+are:
+ - C{'gregorian'} or C{'standard'} (default):
+ Mixed Gregorian/Julian calendar as defined by udunits.
+ - C{'proleptic_gregorian'}:
+ A Gregorian calendar extended to dates before 1582年10月15日. That is, a year 
+ is a leap year if either (i) it is divisible by 4 but not by 100 or (ii) 
+ it is divisible by 400.
+ - C{'noleap'} or C{'365_day'}:
+ Gregorian calendar without leap years, i.e., all years are 365 days long. 
+ - C{'all_leap'} or C{'366_day'}: 
+ Gregorian calendar with every year being a leap year, i.e.,
+ all years are 366 days long.
+ -C{'360_day'}:
+ All years are 360 days divided into 30 day months. 
+ -C{'julian'}:
+ Proleptic Julian calendar, extended to dates after 1582年10月5日. A year is a 
+ leap year if it is divisible by 4.
+
+@returns: A class instance which may be used for converting times from netCDF
+units to datetime objects.
+ """
+ if calendar in _calendars:
+ self.calendar = calendar
+ else:
+ raise ValueError, "calendar must be one of %s, got '%s'" % (str(_calendars),calendar)
+ units, tzoffset, self.origin = _dateparse(unit_string)
+ self.tzoffset = tzoffset # time zone offset in minutes
+ self.units = units
+ self.unit_string = unit_string
+ if self.calendar in ['noleap','365_day'] and self.origin.month == 2 and self.origin.day == 29:
+ raise ValueError, 'cannot specify a leap day as the reference time with the noleap calendar'
+ if self.calendar == '360_day' and self.origin.day > 30:
+ raise ValueError, 'there are only 30 days in every month with the 360_day calendar'
+ if self.calendar in ['noleap','365_day']:
+ self._jd0 = _NoLeapDayFromDate(self.origin)
+ elif self.calendar in ['all_leap','366_day']:
+ self._jd0 = _AllLeapFromDate(self.origin)
+ elif self.calendar == '360_day':
+ self._jd0 = _360DayFromDate(self.origin)
+ else:
+ self._jd0 = JulianDayFromDate(self.origin,calendar=self.calendar)
+
+ def date2num(self,date):
+ """
+Returns C{time_value} in units described by L{unit_string}, using
+the specified L{calendar}, given a 'datetime-like' object.
+
+The datetime object must represent UTC with no time-zone offset.
+If there is a time-zone offset implied by L{unit_string}, it will
+be applied to the returned numeric values.
+
+Resolution is 1 second.
+
+If C{calendar = 'standard'} or C{'gregorian'} (indicating
+that the mixed Julian/Gregorian calendar is to be used), an
+exception will be raised if the 'datetime-like' object describes
+a date between 1582年10月5日 and 1582年10月15日.
+
+Works for scalars, sequences and numpy arrays.
+Returns a scalar if input is a scalar, else returns a numpy array.
+ """
+ isscalar = False
+ try:
+ date[0]
+ except:
+ isscalar = True
+ if not isscalar:
+ date = numpy.array(date)
+ shape = date.shape
+ if self.calendar in ['julian','standard','gregorian','proleptic_gregorian']:
+ if isscalar:
+ jdelta = JulianDayFromDate(date,self.calendar)-self._jd0
+ else:
+ jdelta = [JulianDayFromDate(d,self.calendar)-self._jd0 for d in date.flat]
+ elif self.calendar in ['noleap','365_day']:
+ if date.month == 2 and date.day == 29:
+ raise ValueError, 'there is no leap day in the noleap calendar'
+ if isscalar:
+ jdelta = _NoLeapDayFromDate(date) - self._jd0
+ else:
+ jdelta = [_NoLeapDayFromDate(d)-self._jd0 for d in date.flat]
+ elif self.calendar in ['all_leap','366_day']:
+ if isscalar:
+ jdelta = _AllLeapFromDate(date) - self._jd0
+ else:
+ jdelta = [_AllLeapFromDate(d)-self._jd0 for d in date.flat]
+ elif self.calendar == '360_day':
+ if self.calendar == '360_day' and date.day > 30:
+ raise ValueError, 'there are only 30 days in every month with the 360_day calendar'
+ if isscalar:
+ jdelta = _360DayFromDate(date) - self._jd0
+ else:
+ jdelta = [_360DayFromDate(d)-self._jd0 for d in date.flat]
+ if not isscalar:
+ jdelta = numpy.array(jdelta)
+ # convert to desired units, add time zone offset.
+ if self.units in ['second','seconds']:
+ jdelta = jdelta*86400. + self.tzoffset*60.
+ elif self.units in ['minute','minutes']:
+ jdelta = jdelta*1440. + self.tzoffset
+ elif self.units in ['hour','hours']:
+ jdelta = jdelta*24. + self.tzoffset/60.
+ elif self.units in ['day','days']:
+ jdelta = jdelta + self.tzoffset/1440.
+ if isscalar:
+ return jdelta
+ else:
+ return numpy.reshape(jdelta,shape)
+
+ def num2date(self,time_value):
+ """
+Return a 'datetime-like' object given a C{time_value} in units
+described by L{unit_string}, using L{calendar}.
+
+dates are in UTC with no offset, even if L{unit_string} contains
+a time zone offset from UTC.
+
+Resolution is 1 second.
+
+Works for scalars, sequences and numpy arrays.
+Returns a scalar if input is a scalar, else returns a numpy array.
+
+The datetime instances returned by C{num2date} are 'real' python datetime 
+objects if the date falls in the Gregorian calendar (i.e. 
+C{calendar='proleptic_gregorian'}, or C{calendar = 'standard'/'gregorian'} and 
+the date is after 1582年10月15日). Otherwise, they are 'phony' datetime 
+objects which are actually instances of netcdftime.datetime. This is 
+because the python datetime module cannot handle the weird dates in some 
+calendars (such as C{'360_day'} and C{'all_leap'}) which 
+do not exist in any real world calendar.
+ """
+ isscalar = False
+ try:
+ time_value[0]
+ except:
+ isscalar = True
+ if not isscalar:
+ time_value = numpy.array(time_value)
+ shape = time_value.shape
+ # convert to desired units, remove time zone offset.
+ if self.units in ['second','seconds']:
+ jdelta = time_value/86400. - self.tzoffset/1440.
+ elif self.units in ['minute','minutes']:
+ jdelta = time_value/1440. - self.tzoffset/1440.
+ elif self.units in ['hour','hours']:
+ jdelta = time_value/24. - self.tzoffset/1440.
+ elif self.units in ['day','days']:
+ jdelta = time_value - self.tzoffset/1440.
+ jd = self._jd0 + jdelta
+ if self.calendar in ['julian','standard','gregorian','proleptic_gregorian']:
+ if not isscalar:
+ date = [DateFromJulianDay(j,self.calendar) for j in jd.flat]
+ else:
+ date = DateFromJulianDay(jd,self.calendar)
+ elif self.calendar in ['noleap','365_day']:
+ if not isscalar:
+ date = [_DateFromNoLeapDay(j) for j in jd.flat]
+ else:
+ date = _DateFromNoLeapDay(jd)
+ elif self.calendar in ['all_leap','366_day']:
+ if not isscalar:
+ date = [_DateFromAllLeap(j) for j in jd.flat]
+ else:
+ date = _DateFromAllLeap(jd)
+ elif self.calendar == '360_day':
+ if not isscalar:
+ date = [_DateFrom360Day(j) for j in jd.flat]
+ else:
+ date = _DateFrom360Day(jd)
+ if isscalar:
+ return date
+ else:
+ return numpy.reshape(numpy.array(date),shape)
+
+def _parse_date(origin):
+ """Parses a date string and returns a tuple
+ (year,month,day,hour,minute,second,utc_offset).
+ utc_offset is in minutes.
+
+ This function parses the 'origin' part of the time unit. It should be
+ something like::
+
+ 2004年11月03日 14:42:27.0 +2:00
+
+ Lots of things are optional; just the date is mandatory.
+
+ by Roberto De Almeida
+
+ excerpted from coards.py - http://cheeseshop.python.org/pypi/coards/
+ """
+ # yyyy-mm-dd [hh:mm:ss[.s][ [+-]hh[:][mm]]]
+ p = re.compile( r'''(?P<year>\d{1,4}) # yyyy
+ - #
+ (?P<month>\d{1,2}) # mm or m
+ - #
+ (?P<day>\d{1,2}) # dd or d
+ #
+ (?: # [optional time and timezone]
+ \s #
+ (?P<hour>\d{1,2}) # hh or h
+ : #
+ (?P<min>\d{1,2}) # mm or m
+ (?:
+ \:
+ (?P<sec>\d{1,2}) # ss or s (optional)
+ )?
+ #
+ (?: # [optional decisecond]
+ \. # .
+ (?P<dsec>\d) # s
+ )? #
+ (?: # [optional timezone]
+ \s #
+ (?P<ho>[+-]? # [+ or -]
+ \d{1,2}) # hh or h
+ :? # [:]
+ (?P<mo>\d{2})? # [mm]
+ )? #
+ )? #
+ $ # EOL
+ ''', re.VERBOSE)
+
+ m = p.match(origin.strip())
+ if m:
+ c = m.groupdict(0)
+ # UTC offset.
+ offset = int(c['ho'])*60 + int(c['mo'])
+ return int(c['year']),int(c['month']),int(c['day']),int(c['hour']),int(c['min']),int(c['sec']),offset
+ 
+ raise Exception('Invalid date origin: %s' % origin)
+
+# remove the unsupposed "%s" command. But don't
+# do it if there's an even number of %s before the s
+# because those are all escaped. Can't simply
+# remove the s because the result of
+# %sY
+# should be %Y if %s isn't supported, not the
+# 4 digit year.
+_illegal_s = re.compile(r"((^|[^%])(%%)*%s)")
+
+def _findall(text, substr):
+ # Also finds overlaps
+ sites = []
+ i = 0
+ while 1:
+ j = text.find(substr, i)
+ if j == -1:
+ break
+ sites.append(j)
+ i=j+1
+ return sites
+
+# Every 28 years the calendar repeats, except through century leap
+# years where it's 6 years. But only if you're using the Gregorian
+# calendar. ;)
+
+def _strftime(dt, fmt):
+ if _illegal_s.search(fmt):
+ raise TypeError("This strftime implementation does not handle %s")
+ # don't use strftime method at all.
+ #if dt.year > 1900:
+ # return dt.strftime(fmt)
+
+ year = dt.year
+ # For every non-leap year century, advance by
+ # 6 years to get into the 28-year repeat cycle
+ delta = 2000 - year
+ off = 6*(delta // 100 + delta // 400)
+ year = year + off
+
+ # Move to around the year 2000
+ year = year + ((2000 - year)//28)*28
+ timetuple = dt.timetuple()
+ s1 = time.strftime(fmt, (year,) + timetuple[1:])
+ sites1 = _findall(s1, str(year))
+ 
+ s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
+ sites2 = _findall(s2, str(year+28))
+
+ sites = []
+ for site in sites1:
+ if site in sites2:
+ sites.append(site)
+ 
+ s = s1
+ syear = "%4d" % (dt.year,)
+ for site in sites:
+ s = s[:site] + syear + s[site+4:]
+ return s
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py	2008年01月10日 15:57:28 UTC (rev 4852)
@@ -0,0 +1,343 @@
+import numpy as npy
+import pyproj
+import math
+
+__version__ = '1.2.2'
+_dg2rad = math.radians(1.)
+_rad2dg = math.degrees(1.)
+
+_upper_right_out_of_bounds = (
+ 'the upper right corner of the plot is not in the map projection region')
+
+_lower_left_out_of_bounds = (
+ 'the lower left corner of the plot is not in the map projection region')
+
+
+class Proj(object):
+ """
+ peforms cartographic transformations (converts from longitude,latitude
+ to native map projection x,y coordinates and vice versa) using proj
+ (http://proj.maptools.org/)
+ Uses a pyrex generated C-interface to libproj.
+
+ __init__ method sets up projection information.
+ __call__ method compute transformations.
+ See docstrings for __init__ and __call__ for details.
+
+ Contact: Jeff Whitaker <jef...@no...>
+ """
+
+ def __init__(self,projparams,llcrnrlon,llcrnrlat,
+ urcrnrlon,urcrnrlat,urcrnrislatlon=True):
+ """
+ initialize a Proj class instance.
+
+ Input 'projparams' is a dictionary containing proj map
+ projection control parameter key/value pairs.
+ See the proj documentation (http://www.remotesensing.org/proj/)
+ for details.
+
+ llcrnrlon,llcrnrlat are lon and lat (in degrees) of lower
+ left hand corner of projection region.
+
+ urcrnrlon,urcrnrlat are lon and lat (in degrees) of upper
+ right hand corner of projection region if urcrnrislatlon=True
+ (default). Otherwise, urcrnrlon,urcrnrlat are x,y in projection
+ coordinates (units meters), assuming the lower left corner is x=0,y=0.
+ """
+ self.projparams = projparams
+ self.projection = projparams['proj']
+ # rmajor is the semi-major axis.
+ # rminor is the semi-minor axis.
+ # esq is eccentricity squared.
+ try:
+ self.rmajor = projparams['a']
+ self.rminor = projparams['b']
+ except:
+ try:
+ self.rmajor = projparams['R']
+ except:
+ self.rmajor = projparams['bR_a']
+ self.rminor = self.rmajor
+ if self.rmajor == self.rminor:
+ self.ellipsoid = False
+ else:
+ self.ellipsoid = True
+ self.flattening = (self.rmajor-self.rminor)/self.rmajor
+ self.esq = (self.rmajor**2 - self.rminor**2)/self.rmajor**2
+ self.llcrnrlon = llcrnrlon
+ self.llcrnrlat = llcrnrlat
+ if self.projection not in ['cyl','ortho','geos','moll','robin','sinu']:
+ self._proj4 = pyproj.Proj(projparams)
+ llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
+ elif self.projection == 'cyl':
+ llcrnrx = llcrnrlon
+ llcrnry = llcrnrlat
+ elif self.projection == 'ortho':
+ if (llcrnrlon == -180 and llcrnrlat == -90 and
+ urcrnrlon == 180 and urcrnrlat == 90):
+ self._fulldisk = True
+ self._proj4 = pyproj.Proj(projparams)
+ llcrnrx = -self.rmajor
+ llcrnry = -self.rmajor
+ urcrnrx = -llcrnrx
+ urcrnry = -llcrnry
+ else:
+ self._fulldisk = False
+ self._proj4 = pyproj.Proj(projparams)
+ llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
+ if llcrnrx > 1.e20 or llcrnry > 1.e20:
+ raise ValueError(_lower_left_out_of_bounds)
+ elif self.projection == 'geos':
+ self._proj4 = pyproj.Proj(projparams)
+ # find major and minor axes of ellipse defining map proj region.
+ delta = 0.01
+ lats = npy.arange(0,90,delta)
+ lon_0 = projparams['lon_0']
+ lons = lon_0*npy.ones(len(lats),'d')
+ x, y = self._proj4(lons, lats)
+ yi = (y > 1.e20).tolist()
+ ny = yi.index(1)-1
+ height = y[ny]
+ lons = npy.arange(lon_0,lon_0+90,delta)
+ lats = npy.zeros(len(lons),'d')
+ x, y = self(lons, lats)
+ xi = (x > 1.e20).tolist()
+ nx = xi.index(1)-1
+ width = x[nx]
+ self._height = height
+ self._width = width
+ if (llcrnrlon == -180 and llcrnrlat == -90 and
+ urcrnrlon == 180 and urcrnrlat == 90):
+ self._fulldisk = True
+ llcrnrx = -width
+ llcrnry = -height
+ urcrnrx = -llcrnrx
+ urcrnry = -llcrnry
+ else:
+ self._fulldisk = False
+ llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
+ if llcrnrx > 1.e20 or llcrnry > 1.e20:
+ raise ValueError(_lower_left_out_of_bounds)
+ elif self.projection in ['moll','robin','sinu']:
+ self._proj4 = pyproj.Proj(projparams)
+ xtmp,urcrnry = self(projparams['lon_0'],90.)
+ urcrnrx,xtmp = self(projparams['lon_0']+180.,0)
+ llcrnrx = -urcrnrx
+ llcrnry = -urcrnry
+ # compute x_0, y_0 so ll corner of domain is x=0,y=0.
+ # note that for 'cyl' x,y == lon,lat
+ self.projparams['x_0']=-llcrnrx
+ self.projparams['y_0']=-llcrnry
+ # reset with x_0, y_0.
+ if self.projection != 'cyl':
+ self._proj4 = pyproj.Proj(projparams)
+ llcrnry = 0.
+ llcrnrx = 0.
+ else:
+ llcrnrx = llcrnrlon
+ llcrnry = llcrnrlat
+ if urcrnrislatlon:
+ self.urcrnrlon = urcrnrlon
+ self.urcrnrlat = urcrnrlat
+ if self.projection not in ['ortho','geos','moll','robin','sinu']:
+ urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
+ elif self.projection == 'ortho':
+ if self._fulldisk:
+ urcrnrx = 2.*self.rmajor
+ urcrnry = 2.*self.rmajor
+ else:
+ urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
+ if urcrnrx > 1.e20 or urcrnry > 1.e20:
+ raise ValueError(_upper_right_out_of_bounds)
+ elif self.projection == 'geos':
+ if self._fulldisk:
+ urcrnrx = 2.*self._width
+ urcrnry = 2.*self._height
+ else:
+ urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
+ if urcrnrx > 1.e20 or urcrnry > 1.e20:
+ raise ValueError(_upper_right_out_of_bounds)
+ elif self.projection in ['moll','robin','sinu']:
+ xtmp,urcrnry = self(projparams['lon_0'],90.)
+ urcrnrx,xtmp = self(projparams['lon_0']+180.,0)
+ else:
+ urcrnrx = urcrnrlon
+ urcrnry = urcrnrlat
+ urcrnrlon, urcrnrlat = self(urcrnrx, urcrnry, inverse=True)
+ self.urcrnrlon = urcrnrlon
+ self.urcrnrlat = urcrnrlat
+ # corners of domain.
+ self.llcrnrx = llcrnrx
+ self.llcrnry = llcrnry
+ self.urcrnrx = urcrnrx
+ self.urcrnry = urcrnry
+ if urcrnrx > llcrnrx:
+ self.xmin = llcrnrx
+ self.xmax = urcrnrx
+ else:
+ self.xmax = llcrnrx
+ self.xmin = urcrnrx
+ if urcrnry > llcrnry:
+ self.ymin = llcrnry
+ self.ymax = urcrnry
+ else:
+ self.ymax = llcrnry
+ self.ymin = urcrnry
+
+ def __call__(self, *args, **kw):
+ # x,y,inverse=False):
+ """
+ Calling a Proj class instance with the arguments lon, lat will
+ convert lon/lat (in degrees) to x/y native map projection
+ coordinates (in meters). If optional keyword 'inverse' is
+ True (default is False), the inverse transformation from x/y
+ to lon/lat is performed.
+
+ For cylindrical equidistant projection ('cyl'), this
+ does nothing (i.e. x,y == lon,lat).
+
+ lon,lat can be either scalar floats or N arrays.
+ """
+ if len(args) == 1:
+ xy = args[0]
+ onearray = True
+ else:
+ x,y = args
+ onearray = False
+ if self.projection == 'cyl': # for cyl x,y == lon,lat
+ if onearray:
+ return xy
+ else:
+ return x,y
+ inverse = kw.get('inverse', False)
+ if onearray:
+ outxy = self._proj4(xy, inverse=inverse)
+ else:
+ outx,outy = self._proj4(x, y, inverse=inverse)
+ if inverse:
+ if self.projection in ['merc','mill']:
+ if self.projection == 'merc':
+ coslat = math.cos(math.radians(self.projparams['lat_ts']))
+ sinlat = math.sin(math.radians(self.projparams['lat_ts']))
+ else:
+ coslat = 1.
+ sinlat = 0.
+ # radius of curvature of the ellipse perpendicular to
+ # the plane of the meridian.
+ rcurv = self.rmajor*coslat/math.sqrt(1.-self.esq*sinlat**2)
+ if onearray:
+ outxy[:,0] = _rad2dg*(xy[:,0]/rcurv) + self.llcrnrlon
+ else:
+ try: # x a scalar or an array
+ outx = _rad2dg*(x/rcurv) + self.llcrnrlon
+ except: # x a sequence
+ outx = [_rad2dg*(xi/rcurv) + self.llcrnrlon for xi in x]
+ else:
+ if self.projection in ['merc','mill']:
+ if self.projection == 'merc':
+ coslat = math.cos(math.radians(self.projparams['lat_ts']))
+ sinlat = math.sin(math.radians(self.projparams['lat_ts']))
+ else:
+ coslat = 1.
+ sinlat = 0.
+ # radius of curvature of the ellipse perpendicular to
+ # the plane of the meridian.
+ rcurv = self.rmajor*coslat/math.sqrt(1.-self.esq*sinlat**2)
+ if onearray:
+ outxy[:,0] = rcurv*_dg2rad*(xy[:,0]-self.llcrnrlon)
+ else:
+ try: # x is a scalar or an array
+ outx = rcurv*_dg2rad*(x-self.llcrnrlon)
+ except: # x is a sequence.
+ outx = [rcurv*_dg2rad*(xi-self.llcrnrlon) for xi in x]
+ if onearray:
+ return outxy
+ else:
+ return outx, outy
+
+ def makegrid(self,nx,ny,returnxy=False):
+ """
+ return arrays of shape (ny,nx) containing lon,lat coordinates of
+ an equally spaced native projection grid.
+ if returnxy=True, the x,y values of the grid are returned also.
+ """
+ dx = (self.urcrnrx-self.llcrnrx)/(nx-1)
+ dy = (self.urcrnry-self.llcrnry)/(ny-1)
+ x = self.llcrnrx+dx*npy.indices((ny,nx),npy.float32)[1,:,:]
+ y = self.llcrnry+dy*npy.indices((ny,nx),npy.float32)[0,:,:]
+ lons, lats = self(x, y, inverse=True)
+ if returnxy:
+ return lons, lats, x, y
+ else:
+ return lons, lats
+
+ def makegrid3d(self,nx,ny,returnxy=False):
+ """
+ return array of shape (ny,nx, 2) containing lon,lat coordinates of
+ an equally spaced native projection grid.
+ if returnxy=True, the x,y values of the grid are returned also.
+ """
+ dx = (self.urcrnrx-self.llcrnrx)/(nx-1)
+ dy = (self.urcrnry-self.llcrnry)/(ny-1)
+ xy = npy.empty((ny,nx,2), npy.float64)
+ xy[...,0] = self.llcrnrx+dx*npy.indices((ny,nx),npy.float32)[1,:,:]
+ xy[...,1] = self.llcrnry+dy*npy.indices((ny,nx),npy.float32)[0,:,:]
+ lonlat = self(xy, inverse=True)
+ if returnxy:
+ return lonlat, xy
+ else:
+ return lonlat
+
+
+if __name__ == "__main__":
+
+ params = {}
+ params['proj'] = 'lcc'
+ params['R'] = 6371200
+ params['lat_1'] = 50
+ params['lat_2'] = 50
+ params['lon_0'] = -107
+ nx = 349; ny = 277; dx = 32463.41; dy = dx
+ awips221 = Proj(params,-145.5,1.0,(nx-1)*dx,(ny-1)*dy,urcrnrislatlon=False)
+ # AWIPS grid 221 parameters
+ # (from http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html)
+ llcornerx, llcornery = awips221(-145.5,1.)
+ # find 4 lon/lat corners of AWIPS grid 221.
+ llcornerx = 0.; llcornery = 0.
+ lrcornerx = dx*(nx-1); lrcornery = 0.
+ ulcornerx = 0.; ulcornery = dy*(ny-1)
+ urcornerx = dx*(nx-1); urcornery = dy*(ny-1)
+ llcornerlon, llcornerlat = awips221(llcornerx, llcornery, inverse=True)
+ lrcornerlon, lrcornerlat = awips221(lrcornerx, lrcornery, inverse=True)
+ urcornerlon, urcornerlat = awips221(urcornerx, urcornery, inverse=True)
+ ulcornerlon, ulcornerlat = awips221(ulcornerx, ulcornery, inverse=True)
+ print '4 corners of AWIPS grid 221:'
+ print llcornerlon, llcornerlat
+ print lrcornerlon, lrcornerlat
+ print urcornerlon, urcornerlat
+ print ulcornerlon, ulcornerlat
+ print 'from GRIB docs'
+ print '(see http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html)'
+ print ' -145.5 1.0'
+ print ' -68.318 0.897'
+ print ' -2.566 46.352'
+ print ' 148.639 46.635'
+ # compute lons and lats for the whole AWIPS grid 221 (377x249).
+ import time; t1 = time.clock()
+ lons, lats = awips221.makegrid(nx,ny)
+ t2 = time.clock()
+ print 'compute lats/lons for all points on AWIPS 221 grid (%sx%s)' %(nx,ny)
+ print 'max/min lons'
+ print min(npy.ravel(lons)),max(npy.ravel(lons))
+ print 'max/min lats'
+ print min(npy.ravel(lats)),max(npy.ravel(lats))
+ print 'took',t2-t1,'secs'
+ print 'Same thing but with a single 3-D array'
+ t1 = time.clock()
+ lonlat, xy = awips221.makegrid3d(nx,ny, returnxy=True)
+ t2 = time.clock()
+ print 'took',t2-t1,'secs'
+
+ assert (lons==lonlat[...,0]).all(), "The longitudes are different"
+ assert (lats==lonlat[...,1]).all(), "The latitudes are different"
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/pupynere.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/pupynere.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/pupynere.py	2008年01月10日 15:57:28 UTC (rev 4852)
@@ -0,0 +1,432 @@
+"""NetCDF reader.
+
+Pupynere implements a PUre PYthon NEtcdf REader.
+
+Copyright (c) 2003-2006 Roberto De Almeida <ro...@py...>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject
+to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+
+__author__ = "Roberto De Almeida <ro...@py...>"
+
+
+import struct
+import itertools
+import mmap
+
+from numpy import ndarray, empty, array, ma, squeeze, zeros 
+import numpy
+
+from dap.client import open as open_remote
+from dap.dtypes import ArrayType, GridType, typemap
+
+has_pynio = True
+try:
+ from PyNGL import nio
+except ImportError:
+ has_pynio = False
+
+ABSENT = '\x00' * 8
+ZERO = '\x00' * 4
+NC_BYTE = '\x00\x00\x00\x01' 
+NC_CHAR = '\x00\x00\x00\x02'
+NC_SHORT = '\x00\x00\x00\x03'
+NC_INT = '\x00\x00\x00\x04'
+NC_FLOAT = '\x00\x00\x00\x05'
+NC_DOUBLE = '\x00\x00\x00\x06'
+NC_DIMENSION = '\x00\x00\x00\n'
+NC_VARIABLE = '\x00\x00\x00\x0b'
+NC_ATTRIBUTE = '\x00\x00\x00\x0c'
+
+_typecodes = dict([[_v,_k] for _k,_v in typemap.items()])
+# default _FillValue for netcdf types (apply also to corresponding
+# DAP types).
+_default_fillvals = {'c':'0円',
+ 'S':"",
+ 'b':-127,
+ 'B':-127,
+ 'h':-32767,
+ 'H':65535,
+ 'i':-2147483647L,
+ 'L':4294967295L,
+ 'q':-2147483647L,
+ 'f':9.9692099683868690e+36,
+ 'd':9.9692099683868690e+36}
+
+def NetCDFFile(file, maskandscale=True):
+ """NetCDF File reader. API is the same as Scientific.IO.NetCDF.
+ If 'file' is a URL that starts with 'http', it is assumed
+ to be a remote OPenDAP dataset, and the python dap client is used
+ to retrieve the data. Only the OPenDAP Array and Grid data
+ types are recognized. If file does not start with 'http', it
+ is assumed to be a local file. If possible, the file will be read 
+ with a pure python NetCDF reader, otherwise PyNIO 
+ (http://www.pyngl.ucar.edu/Nio.shtml) will be used (if it is installed).
+ PyNIO supports NetCDF version 4, GRIB1, GRIB2, HDF4 and HDFEOS2 files.
+ Data read from OPenDAP and NetCDF version 3 datasets will 
+ automatically be converted to masked arrays if the variable has either
+ a 'missing_value' or '_FillValue' attribute, and some data points
+ are equal to the value specified by that attribute. In addition,
+ variables stored as integers that have the 'scale_factor' and
+ 'add_offset' attribute will automatically be rescaled to floats when
+ read. If PyNIO is used, neither of the automatic conversions will
+ be performed. To suppress these automatic conversions, set the
+ maskandscale keyword to False. 
+ """
+ if file.startswith('http'):
+ return _RemoteFile(file,maskandscale)
+ else:
+ # use pynio if it is installed and the file cannot
+ # be read with the pure python netCDF reader. This allows
+ # netCDF version 4, GRIB1, GRIB2, HDF4 and HDFEOS files
+ # to be read.
+ if has_pynio:
+ try:
+ f = _LocalFile(file,maskandscale)
+ except:
+ f = nio.open_file(file)
+ # otherwise, use the pupynere netCDF 3 pure python reader.
+ # (will fail if file is not a netCDF version 3 file).
+ else:
+ f = _LocalFile(file,maskandscale)
+ return f
+ 
+def _maskandscale(var,datout):
+ totalmask = zeros(datout.shape,numpy.bool)
+ fillval = None
+ if hasattr(var, 'missing_value') and (datout == var.missing_value).any():
+ fillval = var.missing_value
+ totalmask = totalmask + datout==fillval
+ if hasattr(var, '_FillValue') and (datout == var._FillValue).any():
+ if fillval is None:
+ fillval = var._FillValue
+ totalmask = totalmask + datout==var._FillValue
+ elif (datout == _default_fillvals[var.typecode()]).any():
+ if fillval is None:
+ fillval = _default_fillvals[var.typecode()]
+ totalmask = totalmask + datout==_default_fillvals[var.dtype]
+ if fillval is not None:
+ datout = ma.masked_array(datout,mask=totalmask,fill_value=fillval)
+ try:
+ datout = var.scale_factor*datout + var.add_offset
+ except:
+ pass
+ return datout
+
+class _RemoteFile(object):
+ """A NetCDF file reader. API is the same as Scientific.IO.NetCDF."""
+
+ def __init__(self, file, maskandscale):
+ self._buffer = open_remote(file)
+ self._maskandscale = maskandscale
+ self._parse()
+
+ def read(self, size=-1):
+ """Alias for reading the file buffer."""
+ return self._buffer.read(size)
+
+ def _parse(self):
+ """Initial parsing of the header."""
+ # Read header info.
+ self._dim_array()
+ self._gatt_array()
+ self._var_array()
+
+ def _dim_array(self):
+ """Read a dict with dimensions names and sizes."""
+ self.dimensions = {}
+ self._dims = []
+ for k,d in self._buffer.iteritems():
+ if (isinstance(d, ArrayType) or isinstance(d, GridType)) and len(d.shape) == 1 and k == d.dimensions[0]:
+ name = k
+ length = len(d)
+ self.dimensions[name] = length
+ self._dims.append(name) # preserve dim order
+
+ def _gatt_array(self):
+ """Read global attributes."""
+ self.__dict__.update(self._buffer.attributes)
+
+ def _var_array(self):
+ """Read all variables."""
+ # Read variables.
+ self.variables = {}
+ for k,d in self._buffer.iteritems():
+ if isinstance(d, GridType) or isinstance(d, ArrayType):
+ name = k
+ self.variables[name] = _RemoteVariable(d,self._maskandscale)
+
+ def close(self):
+ # this is a no-op provided for compatibility
+ pass
+
+
+class _RemoteVariable(object):
+ def __init__(self, var, maskandscale):
+ self._var = var
+ self._maskandscale = maskandscale
+ self.dtype = var.type
+ self.shape = var.shape
+ self.dimensions = var.dimensions
+ self.__dict__.update(var.attributes)
+
+ def __getitem__(self, index):
+ datout = squeeze(self._var.__getitem__(index))
+ # automatically
+ # - remove singleton dimensions
+ # - create a masked array using missing_value or _FillValue attribute
+ # - apply scale_factor and add_offset to packed integer data
+ if self._maskandscale:
+ return _maskandscale(self,datout)
+ else:
+ return datout
+
+ def typecode(self):
+ return _typecodes[self.dtype]
+
+
+class _LocalFile(object):
+ """A NetCDF file reader. API is the same as Scientific.IO.NetCDF."""
+
+ def __init__(self, file, maskandscale):
+ self._buffer = open(file, 'rb')
+ self._maskandscale = maskandscale
+ self._parse()
+
+ def read(self, size=-1):
+ """Alias for reading the file buffer."""
+ return self._buffer.read(size)
+
+ def _parse(self):
+ """Initial parsing of the header."""
+ # Check magic bytes.
+ assert self.read(3) == 'CDF'
+
+ # Read version byte.
+ byte = self.read(1)
+ self.version_byte = struct.unpack('>b', byte)[0]
+
+ # Read header info.
+ self._numrecs()
+ self._dim_array()
+ self._gatt_array()
+ self._var_array()
+
+ def _numrecs(self):
+ """Read number of records."""
+ self._nrecs = self._unpack_int()
+
+ def _dim_array(self):
+ """Read a dict with dimensions names and sizes."""
+ assert self.read(4) in [ZERO, NC_DIMENSION]
+ count = self._unpack_int()
+
+ self.dimensions = {}
+ self._dims = []
+ for dim in range(count):
+ name = self._read_string()
+ length = self._unpack_int()
+ if length == 0: length = None # record dimension
+ self.dimensions[name] = length
+ self._dims.append(name) # preserve dim order
+
+ def _gatt_array(self):
+ """Read global attributes."""
+ self.attributes = self._att_array()
+
+ # Update __dict__ for compatibility with S.IO.N
+ self.__dict__.update(self.attributes)
+
+ def _att_array(self):
+ """Read a dict with attributes."""
+ assert self.read(4) in [ZERO, NC_ATTRIBUTE]
+ count = self._unpack_int()
+
+ # Read attributes.
+ attributes = {}
+ for attribute in range(count):
+ name = self._read_string()
+ nc_type = self._unpack_int()
+ n = self._unpack_int()
+
+ # Read value for attributes.
+ attributes[name] = self._read_values(n, nc_type)
+
+ return attributes
+
+ def _var_array(self):
+ """Read all variables."""
+ assert self.read(4) in [ZERO, NC_VARIABLE]
+
+ # Read size of each record, in bytes.
+ self._read_recsize()
+
+ # Read variables.
+ self.variables = {}
+ count = self._unpack_int()
+ for variable in range(count):
+ name = self._read_string()
+ self.variables[name] = self._read_var()
+
+ def _read_recsize(self):
+ """Read all variables and compute record bytes."""
+ pos = self._buffer.tell()
+ 
+ recsize = 0
+ count = self._unpack_int()
+ for variable in range(count):
+ name = self._read_string()
+ n = self._unpack_int()
+ isrec = False
+ for i in range(n):
+ dimid = self._unpack_int()
+ name = self._dims[dimid]
+ dim = self.dimensions[name]
+ if dim is None and i == 0:
+ isrec = True
+ attributes = self._att_array()
+ nc_type = self._unpack_int()
+ vsize = self._unpack_int()
+ begin = [self._unpack_int, self._unpack_int64][self.version_byte-1]()
+
+ if isrec: recsize += vsize
+
+ self._recsize = recsize
+ self._buffer.seek(pos)
+
+ def _read_var(self):
+ dimensions = []
+ shape = []
+ n = self._unpack_int()
+ isrec = False
+ for i in range(n):
+ dimid = self._unpack_int()
+ name = self._dims[dimid]
+ dimensions.append(name)
+ dim = self.dimensions[name]
+ if dim is None and i == 0:
+ dim = self._nrecs
+ isrec = True
+ shape.append(dim)
+ dimensions = tuple(dimensions)
+ shape = tuple(shape)
+
+ attributes = self._att_array()
+ nc_type = self._unpack_int()
+ vsize = self._unpack_int()
+ 
+ # Read offset.
+ begin = [self._unpack_int, self._unpack_int64][self.version_byte-1]()
+
+ return _LocalVariable(self._buffer.fileno(), nc_type, vsize, begin, shape, dimensions, attributes, isrec, self._recsize, maskandscale=self._maskandscale)
+
+ def _read_values(self, n, nc_type):
+ bytes = [1, 1, 2, 4, 4, 8]
+ typecodes = ['b', 'c', 'h', 'i', 'f', 'd']
+ 
+ count = n * bytes[nc_type-1]
+ values = self.read(count)
+ padding = self.read((4 - (count % 4)) % 4)
+ 
+ typecode = typecodes[nc_type-1]
+ if nc_type != 2: # not char 
+ values = struct.unpack('>%s' % (typecode * n), values)
+ values = array(values, dtype=typecode) 
+ else:
+ # Remove EOL terminator.
+ if values.endswith('\x00'): values = values[:-1]
+
+ return values
+
+ def _unpack_int(self):
+ return struct.unpack('>i', self.read(4))[0]
+ _unpack_int32 = _unpack_int
+
+ def _unpack_int64(self):
+ return struct.unpack('>q', self.read(8))[0]
+
+ def _read_string(self):
+ count = struct.unpack('>i', self.read(4))[0]
+ s = self.read(count)
+ # Remove EOL terminator.
+ if s.endswith('\x00'): s = s[:-1]
+ padding = self.read((4 - (count % 4)) % 4)
+ return s
+
+ def close(self):
+ self._buffer.close()
+
+
+class _LocalVariable(object):
+ def __init__(self, fileno, nc_type, vsize, begin, shape, dimensions, attributes, isrec=False, recsize=0, maskandscale=True):
+ self._nc_type = nc_type
+ self._vsize = vsize
+ self._begin = begin
+ self.shape = shape
+ self.dimensions = dimensions
+ self.attributes = attributes # for ``dap.plugins.netcdf``
+ self.__dict__.update(attributes)
+ self._is_record = isrec
+ self._maskandscale = maskandscale
+
+ # Number of bytes and type.
+ self._bytes = [1, 1, 2, 4, 4, 8][self._nc_type-1]
+ type_ = ['i', 'S', 'i', 'i', 'f', 'f'][self._nc_type-1]
+ dtype = '>%s%d' % (type_, self._bytes)
+ bytes = self._begin + self._vsize 
+
+ if isrec:
+ # Record variables are not stored contiguosly on disk, so we 
+ # need to create a separate array for each record.
+ self.__array_data__ = empty(shape, dtype)
+ bytes += (shape[0] - 1) * recsize
+ for n in range(shape[0]):
+ offset = self._begin + (n * recsize)
+ mm = mmap.mmap(fileno, bytes, access=mmap.ACCESS_READ)
+ self.__array_data__[n] = ndarray.__new__(ndarray, shape[1:], dtype=dtype, buffer=mm, offset=offset, order=0)
+ else:
+ # Create buffer and data.
+ mm = mmap.mmap(fileno, bytes, access=mmap.ACCESS_READ)
+ self.__array_data__ = ndarray.__new__(ndarray, shape, dtype=dtype, buffer=mm, offset=self._begin, order=0)
+
+ # N-D array interface
+ self.__array_interface__ = {'shape' : shape,
+ 'typestr': dtype,
+ ...
 
[truncated message content]
From: <js...@us...> - 2008年01月10日 14:31:50
Revision: 4851
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4851&view=rev
Author: jswhit
Date: 2008年01月10日 06:31:37 -0800 (2008年1月10日)
Log Message:
-----------
re-enable python 2.3 support
Modified Paths:
--------------
 trunk/toolkits/basemap/Changelog
 trunk/toolkits/basemap/README
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog	2008年01月10日 14:05:56 UTC (rev 4850)
+++ trunk/toolkits/basemap/Changelog	2008年01月10日 14:31:37 UTC (rev 4851)
@@ -1,10 +1,11 @@
-version 0.9.9.2
+version 0.99
 * Now lives in mpl_toolkits.basemap. Instead
 of 'from matplotlib.toolkits.basemap import Basemap',
 use 'from mpl_toolkits.basemap import Basemap'.
 All examples changed. Uses matplotlib mpl_toolkits
 namespace package, so basemap can now be installed
- if matplotlib is installed as an egg.
+ if matplotlib is installed as an egg. Python 2.3
+ support re-enabled.
 version 0.9.9.1 (svn revision 4808)
 * require python 2.4 (really only needed for building).
 Once namespace packages are re-enabled in matplotlib,
Modified: trunk/toolkits/basemap/README
===================================================================
--- trunk/toolkits/basemap/README	2008年01月10日 14:05:56 UTC (rev 4850)
+++ trunk/toolkits/basemap/README	2008年01月10日 14:31:37 UTC (rev 4851)
@@ -5,9 +5,9 @@
 
 **Requirements**
 
-python 2.4 (or higher)
+python 2.3 (or higher)
 
-matplotlib 0.90 (or higher)
+matplotlib 0.98 (or higher)
 
 numpy 1.0 (or higher)
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 14:06:03
Revision: 4850
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4850&view=rev
Author: jswhit
Date: 2008年01月10日 06:05:56 -0800 (2008年1月10日)
Log Message:
-----------
move to mpl_toolkits
Modified Paths:
--------------
 trunk/toolkits/basemap/MANIFEST.in
Modified: trunk/toolkits/basemap/MANIFEST.in
===================================================================
--- trunk/toolkits/basemap/MANIFEST.in	2008年01月10日 14:05:09 UTC (rev 4849)
+++ trunk/toolkits/basemap/MANIFEST.in	2008年01月10日 14:05:56 UTC (rev 4850)
@@ -65,13 +65,14 @@
 include examples/plotprecip.py
 include examples/nws_precip_conus_20061222.nc
 include examples/README
-include lib/matplotlib/toolkits/basemap/__init__.py
-include lib/matplotlib/toolkits/basemap/basemap.py
-include lib/matplotlib/toolkits/basemap/proj.py
-include lib/matplotlib/toolkits/basemap/pyproj.py
-include lib/matplotlib/toolkits/basemap/cm.py
-include lib/matplotlib/toolkits/basemap/pupynere.py
-include lib/matplotlib/toolkits/basemap/netcdftime.py
+include lib/mpl_toolkits/__init__.py
+include lib/mpl_toolkits/basemap/__init__.py
+include lib/mpl_toolkits/basemap/basemap.py
+include lib/mpl_toolkits/basemap/proj.py
+include lib/mpl_toolkits/basemap/pyproj.py
+include lib/mpl_toolkits/basemap/cm.py
+include lib/mpl_toolkits/basemap/pupynere.py
+include lib/mpl_toolkits/basemap/netcdftime.py
 include pyshapelib/README pyshapelib/COPYING pyshapelib/ChangeLog pyshapelib/NEWS
 include pyshapelib/*.i pyshapelib/*.c pyshapelib/*.py pyshapelib/*.h
 include pyshapelib/*.shp pyshapelib/*.shx pyshapelib/*.dbf
@@ -82,54 +83,54 @@
 recursive-include lib/httplib2 *
 recursive-include lib/dbflib *
 recursive-include lib/shapelib *
-include lib/matplotlib/toolkits/basemap/data/5minmask.bin
-include lib/matplotlib/toolkits/basemap/data/GL27
-include lib/matplotlib/toolkits/basemap/data/countries_c.dat
-include lib/matplotlib/toolkits/basemap/data/countries_h.dat
-include lib/matplotlib/toolkits/basemap/data/countries_i.dat
-include lib/matplotlib/toolkits/basemap/data/countries_l.dat
-include lib/matplotlib/toolkits/basemap/data/countriesmeta_c.dat
-include lib/matplotlib/toolkits/basemap/data/countriesmeta_h.dat
-include lib/matplotlib/toolkits/basemap/data/countriesmeta_i.dat
-include lib/matplotlib/toolkits/basemap/data/countriesmeta_l.dat
-include lib/matplotlib/toolkits/basemap/data/epsg
-include lib/matplotlib/toolkits/basemap/data/esri
-include lib/matplotlib/toolkits/basemap/data/esri.extra
-include lib/matplotlib/toolkits/basemap/data/gshhs_c.dat
-include lib/matplotlib/toolkits/basemap/data/gshhs_h.dat
-include lib/matplotlib/toolkits/basemap/data/gshhs_i.dat
-include lib/matplotlib/toolkits/basemap/data/gshhs_l.dat
-include lib/matplotlib/toolkits/basemap/data/gshhsmeta_c.dat
-include lib/matplotlib/toolkits/basemap/data/gshhsmeta_h.dat
-include lib/matplotlib/toolkits/basemap/data/gshhsmeta_i.dat
-include lib/matplotlib/toolkits/basemap/data/gshhsmeta_l.dat
-include lib/matplotlib/toolkits/basemap/data/nad.lst
-include lib/matplotlib/toolkits/basemap/data/nad27
-include lib/matplotlib/toolkits/basemap/data/nad83
-include lib/matplotlib/toolkits/basemap/data/ntv2_out.dist
-include lib/matplotlib/toolkits/basemap/data/other.extra
-include lib/matplotlib/toolkits/basemap/data/pj_out27.dist
-include lib/matplotlib/toolkits/basemap/data/pj_out83.dist
-include lib/matplotlib/toolkits/basemap/data/proj_def.dat
-include lib/matplotlib/toolkits/basemap/data/rivers_c.dat
-include lib/matplotlib/toolkits/basemap/data/rivers_h.dat
-include lib/matplotlib/toolkits/basemap/data/rivers_i.dat
-include lib/matplotlib/toolkits/basemap/data/rivers_l.dat
-include lib/matplotlib/toolkits/basemap/data/riversmeta_c.dat
-include lib/matplotlib/toolkits/basemap/data/riversmeta_h.dat
-include lib/matplotlib/toolkits/basemap/data/riversmeta_i.dat
-include lib/matplotlib/toolkits/basemap/data/riversmeta_l.dat
-include lib/matplotlib/toolkits/basemap/data/states_c.dat
-include lib/matplotlib/toolkits/basemap/data/states_h.dat
-include lib/matplotlib/toolkits/basemap/data/states_i.dat
-include lib/matplotlib/toolkits/basemap/data/states_l.dat
-include lib/matplotlib/toolkits/basemap/data/statesmeta_c.dat
-include lib/matplotlib/toolkits/basemap/data/statesmeta_h.dat
-include lib/matplotlib/toolkits/basemap/data/statesmeta_i.dat
-include lib/matplotlib/toolkits/basemap/data/statesmeta_l.dat
-include lib/matplotlib/toolkits/basemap/data/td_out.dist
-include lib/matplotlib/toolkits/basemap/data/test27
-include lib/matplotlib/toolkits/basemap/data/test83
-include lib/matplotlib/toolkits/basemap/data/testntv2
-include lib/matplotlib/toolkits/basemap/data/testvarious
-include lib/matplotlib/toolkits/basemap/data/world
+include lib/mpl_toolkits/basemap/data/5minmask.bin
+include lib/mpl_toolkits/basemap/data/GL27
+include lib/mpl_toolkits/basemap/data/countries_c.dat
+include lib/mpl_toolkits/basemap/data/countries_h.dat
+include lib/mpl_toolkits/basemap/data/countries_i.dat
+include lib/mpl_toolkits/basemap/data/countries_l.dat
+include lib/mpl_toolkits/basemap/data/countriesmeta_c.dat
+include lib/mpl_toolkits/basemap/data/countriesmeta_h.dat
+include lib/mpl_toolkits/basemap/data/countriesmeta_i.dat
+include lib/mpl_toolkits/basemap/data/countriesmeta_l.dat
+include lib/mpl_toolkits/basemap/data/epsg
+include lib/mpl_toolkits/basemap/data/esri
+include lib/mpl_toolkits/basemap/data/esri.extra
+include lib/mpl_toolkits/basemap/data/gshhs_c.dat
+include lib/mpl_toolkits/basemap/data/gshhs_h.dat
+include lib/mpl_toolkits/basemap/data/gshhs_i.dat
+include lib/mpl_toolkits/basemap/data/gshhs_l.dat
+include lib/mpl_toolkits/basemap/data/gshhsmeta_c.dat
+include lib/mpl_toolkits/basemap/data/gshhsmeta_h.dat
+include lib/mpl_toolkits/basemap/data/gshhsmeta_i.dat
+include lib/mpl_toolkits/basemap/data/gshhsmeta_l.dat
+include lib/mpl_toolkits/basemap/data/nad.lst
+include lib/mpl_toolkits/basemap/data/nad27
+include lib/mpl_toolkits/basemap/data/nad83
+include lib/mpl_toolkits/basemap/data/ntv2_out.dist
+include lib/mpl_toolkits/basemap/data/other.extra
+include lib/mpl_toolkits/basemap/data/pj_out27.dist
+include lib/mpl_toolkits/basemap/data/pj_out83.dist
+include lib/mpl_toolkits/basemap/data/proj_def.dat
+include lib/mpl_toolkits/basemap/data/rivers_c.dat
+include lib/mpl_toolkits/basemap/data/rivers_h.dat
+include lib/mpl_toolkits/basemap/data/rivers_i.dat
+include lib/mpl_toolkits/basemap/data/rivers_l.dat
+include lib/mpl_toolkits/basemap/data/riversmeta_c.dat
+include lib/mpl_toolkits/basemap/data/riversmeta_h.dat
+include lib/mpl_toolkits/basemap/data/riversmeta_i.dat
+include lib/mpl_toolkits/basemap/data/riversmeta_l.dat
+include lib/mpl_toolkits/basemap/data/states_c.dat
+include lib/mpl_toolkits/basemap/data/states_h.dat
+include lib/mpl_toolkits/basemap/data/states_i.dat
+include lib/mpl_toolkits/basemap/data/states_l.dat
+include lib/mpl_toolkits/basemap/data/statesmeta_c.dat
+include lib/mpl_toolkits/basemap/data/statesmeta_h.dat
+include lib/mpl_toolkits/basemap/data/statesmeta_i.dat
+include lib/mpl_toolkits/basemap/data/statesmeta_l.dat
+include lib/mpl_toolkits/basemap/data/td_out.dist
+include lib/mpl_toolkits/basemap/data/test27
+include lib/mpl_toolkits/basemap/data/test83
+include lib/mpl_toolkits/basemap/data/testntv2
+include lib/mpl_toolkits/basemap/data/testvarious
+include lib/mpl_toolkits/basemap/data/world
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4849
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4849&view=rev
Author: jswhit
Date: 2008年01月10日 06:05:09 -0800 (2008年1月10日)
Log Message:
-----------
remove unintentional commit
Removed Paths:
-------------
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_geod.so
Deleted: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_geod.so
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 4848
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4848&view=rev
Author: jswhit
Date: 2008年01月10日 06:04:44 -0800 (2008年1月10日)
Log Message:
-----------
remove unintentional commit
Removed Paths:
-------------
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_proj.so
Deleted: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_proj.so
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 13:59:50
Revision: 4847
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4847&view=rev
Author: jswhit
Date: 2008年01月10日 05:59:29 -0800 (2008年1月10日)
Log Message:
-----------
move matplotlit/toolkits to mpl_toolkits
Modified Paths:
--------------
 trunk/toolkits/basemap/API_CHANGES
 trunk/toolkits/basemap/Changelog
 trunk/toolkits/basemap/setup.py
 trunk/toolkits/basemap/setupegg.py
Added Paths:
-----------
 trunk/toolkits/basemap/lib/mpl_toolkits/
 trunk/toolkits/basemap/lib/mpl_toolkits/__init__.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_geod.so
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_proj.so
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/basemap.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/cm.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/5minmask.bin
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/GL27
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/README
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/__init__.py
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countries_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countries_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countries_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countries_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countries_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countriesmeta_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countriesmeta_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countriesmeta_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countriesmeta_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/countriesmeta_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/epsg
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/esri
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/esri.extra
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhs_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhs_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhs_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhs_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhs_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhsmeta_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhsmeta_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhsmeta_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhsmeta_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/gshhsmeta_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/nad.lst
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/nad27
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/nad83
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/ntv2_out.dist
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/other.extra
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/pj_out27.dist
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/pj_out83.dist
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/proj_def.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/rivers_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/rivers_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/rivers_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/rivers_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/rivers_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/riversmeta_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/riversmeta_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/riversmeta_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/riversmeta_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/riversmeta_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/states_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/states_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/states_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/states_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/states_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/statesmeta_c.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/statesmeta_f.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/statesmeta_h.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/statesmeta_i.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/statesmeta_l.dat
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/td_out.dist
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/test27
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/test83
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/testntv2
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/testvarious
 trunk/toolkits/basemap/lib/mpl_toolkits/basemap/data/world
Removed Paths:
-------------
 trunk/toolkits/basemap/lib/matplotlib/
Modified: trunk/toolkits/basemap/API_CHANGES
===================================================================
--- trunk/toolkits/basemap/API_CHANGES	2008年01月10日 13:38:37 UTC (rev 4846)
+++ trunk/toolkits/basemap/API_CHANGES	2008年01月10日 13:59:29 UTC (rev 4847)
@@ -1,3 +1,5 @@
+version 0.99: now must be imported as mpl_toolkits.basemap instead
+ of matplotlib.toolkits.basemap.
 version 0.9.8: remove linestyle kwarg from drawparallels and drawmeridians.
 add fill_color kwarg to drawmapboundary.
 version 0.9.7: added lake_color kwarg to fillcontinents.
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog	2008年01月10日 13:38:37 UTC (rev 4846)
+++ trunk/toolkits/basemap/Changelog	2008年01月10日 13:59:29 UTC (rev 4847)
@@ -1,3 +1,10 @@
+version 0.9.9.2
+ * Now lives in mpl_toolkits.basemap. Instead
+ of 'from matplotlib.toolkits.basemap import Basemap',
+ use 'from mpl_toolkits.basemap import Basemap'.
+ All examples changed. Uses matplotlib mpl_toolkits
+ namespace package, so basemap can now be installed
+ if matplotlib is installed as an egg.
 version 0.9.9.1 (svn revision 4808)
 * require python 2.4 (really only needed for building).
 Once namespace packages are re-enabled in matplotlib,
Added: trunk/toolkits/basemap/lib/mpl_toolkits/__init__.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/__init__.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/__init__.py	2008年01月10日 13:59:29 UTC (rev 4847)
@@ -0,0 +1,4 @@
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ pass # must not have setuptools
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py	2008年01月10日 13:59:29 UTC (rev 4847)
@@ -0,0 +1,2 @@
+from basemap import __doc__, __version__
+from basemap import *
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_geod.so
===================================================================
(Binary files differ)
Property changes on: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_geod.so
___________________________________________________________________
Name: svn:mime-type
 + application/octet-stream
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_proj.so
===================================================================
(Binary files differ)
Property changes on: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/_proj.so
___________________________________________________________________
Name: svn:mime-type
 + application/octet-stream
Added: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/basemap.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/basemap.py	 (rev 0)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/basemap.py	2008年01月10日 13:59:29 UTC (rev 4847)
@@ -0,0 +1,2981 @@
+"""
+Module for plotting data on maps with matplotlib.
+
+Contains the Basemap class (which does most of the 
+heavy lifting), and the following functions:
+
+NetCDFFile: Read local and remote NetCDF datasets.
+
+interp: bilinear interpolation between rectilinear grids.
+
+shiftgrid: shifts global lat/lon grids east or west.
+
+addcyclic: Add cyclic (wraparound) point in longitude.
+
+num2date: convert from a numeric time value to a datetime object.
+
+date2num: convert from a datetime object to a numeric time value.
+"""
+from matplotlib import __version__ as _matplotlib_version
+from matplotlib.cbook import is_scalar, dedent
+# check to make sure matplotlib is not too old.
+_mpl_required_version = '0.98'
+if _matplotlib_version < _mpl_required_version:
+ msg = dedent("""
+ your matplotlib is too old - basemap requires version %s or 
+ higher, you have version %s""" % 
+ (_mpl_required_version,_matplotlib_version))
+ raise ImportError(msg)
+from matplotlib import rcParams, is_interactive, _pylab_helpers
+from matplotlib.collections import LineCollection
+from matplotlib.patches import Ellipse, Circle, Polygon
+from matplotlib.lines import Line2D
+import pyproj, sys, os, math, dbflib
+from proj import Proj
+import numpy as npy
+from numpy import linspace, squeeze, ma
+from shapelib import ShapeFile
+import _geos, pupynere, netcdftime
+
+# basemap data files now installed in lib/matplotlib/toolkits/basemap/data
+basemap_datadir = os.sep.join([os.path.dirname(__file__), 'data'])
+
+__version__ = '0.99'
+
+# supported map projections.
+_projnames = {'cyl' : 'Cylindrical Equidistant',
+ 'merc' : 'Mercator',
+ 'tmerc' : 'Transverse Mercator',
+ 'omerc' : 'Oblique Mercator',
+ 'mill' : 'Miller Cylindrical',
+ 'lcc' : 'Lambert Conformal',
+ 'laea' : 'Lambert Azimuthal Equal Area',
+ 'nplaea' : 'North-Polar Lambert Azimuthal',
+ 'splaea' : 'South-Polar Lambert Azimuthal',
+ 'eqdc' : 'Equidistant Conic',
+ 'aeqd' : 'Azimuthal Equidistant',
+ 'npaeqd' : 'North-Polar Azimuthal Equidistant',
+ 'spaeqd' : 'South-Polar Azimuthal Equidistant',
+ 'aea' : 'Albers Equal Area',
+ 'stere' : 'Stereographic',
+ 'npstere' : 'North-Polar Stereographic',
+ 'spstere' : 'South-Polar Stereographic',
+ 'cass' : 'Cassini-Soldner',
+ 'poly' : 'Polyconic',
+ 'ortho' : 'Orthographic',
+ 'geos' : 'Geostationary',
+ 'sinu' : 'Sinusoidal',
+ 'moll' : 'Mollweide',
+ 'robin' : 'Robinson',
+ 'gnom' : 'Gnomonic',
+ }
+supported_projections = []
+for _items in _projnames.iteritems():
+ supported_projections.append("'%s' = %s\n" % (_items))
+supported_projections = ''.join(supported_projections)
+
+# projection specific parameters.
+projection_params = {'cyl' : 'corners only (no width/height)',
+ 'merc' : 'corners plus lat_ts (no width/height)',
+ 'tmerc' : 'lon_0,lat_0',
+ 'omerc' : 'lon_0,lat_0,lat_1,lat_2,lon_1,lon_2,no width/height',
+ 'mill' : 'corners only (no width/height)',
+ 'lcc' : 'lon_0,lat_0,lat_1,lat_2',
+ 'laea' : 'lon_0,lat_0',
+ 'nplaea' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'splaea' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'eqdc' : 'lon_0,lat_0,lat_1,lat_2',
+ 'aeqd' : 'lon_0,lat_0',
+ 'npaeqd' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'spaeqd' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'aea' : 'lon_0,lat_0,lat_1',
+ 'stere' : 'lon_0,lat_0,lat_ts',
+ 'npstere' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'spstere' : 'bounding_lat,lon_0,lat_0,no corners or width/height',
+ 'cass' : 'lon_0,lat_0',
+ 'poly' : 'lon_0,lat_0',
+ 'ortho' : 'lon_0,lat_0',
+ 'geos' : 'lon_0,lat_0,satellite_height',
+ 'sinu' : 'lon_0,lat_0,no corners or width/height',
+ 'moll' : 'lon_0,lat_0,no corners or width/height',
+ 'robin' : 'lon_0,lat_0,no corners or width/height',
+ 'gnom' : 'lon_0,lat_0',
+ }
+
+# The __init__ docstring is pulled out here because it is so long;
+# Having it in the usual place makes it hard to get from the
+# __init__ argument list to the code that uses the arguments.
+_Basemap_init_doc = """
+ create a Basemap instance.
+
+ This sets up a basemap with specified map projection.
+ and creates the coastline data structures in native map projection
+ coordinates.
+
+ arguments:
+
+ projection - map projection. Supported projections are:
+%(supported_projections)s
+ Default is 'cyl'.
+
+ For most map projections, the map projection region can either be
+ specified by setting these keywords:
+
+ llcrnrlon - longitude of lower left hand corner of the desired map domain (degrees).
+ llcrnrlat - latitude of lower left hand corner of the desired map domain (degrees).
+ urcrnrlon - longitude of upper right hand corner of the desired map domain (degrees).
+ urcrnrlat - latitude of upper right hand corner of the desired map domain (degrees).
+
+ or these keywords:
+
+ width - width of desired map domain in projection coordinates (meters).
+ height - height of desired map domain in projection coordinates (meters).
+ lon_0 - center of desired map domain (in degrees).
+ lat_0 - center of desired map domain (in degrees).
+
+ For 'sinu', 'moll', 'npstere', 'spstere', 'nplaea', 'splaea', 'nplaea',
+ 'splaea', 'npaeqd', 'spaeqd' or 'robin', the values of
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat,width and height are ignored
+ (because either they are computed internally, or entire globe is
+ always plotted). For the cylindrical projections
+ ('cyl','merc' and 'mill'), the default is to use
+ llcrnrlon=-180,llcrnrlat=-90, urcrnrlon=180 and urcrnrlat=90). For all other
+ projections except 'ortho' and 'geos', either the lat/lon values of the
+ corners or width and height must be specified by the user.
+ For 'ortho' and 'geos', the lat/lon values of the corners may be specified,
+ but if they are not, the entire globe is plotted.
+
+ resolution - resolution of boundary database to use. Can be 'c' (crude),
+ 'l' (low), 'i' (intermediate), 'h' (high), 'f' (full) or None.
+ If None, no boundary data will be read in (and class methods
+ such as drawcoastlines will raise an exception if invoked).
+ Resolution drops off by roughly 80%%
+ between datasets. Higher res datasets are much slower to draw.
+ Default 'c'. Coastline data is from the GSHHS
+ (http://www.soest.hawaii.edu/wessel/gshhs/gshhs.html).
+ State, country and river datasets from the Generic Mapping
+ Tools (http://gmt.soest.hawaii.edu).
+
+ area_thresh - coastline or lake with an area smaller than area_thresh
+ in km^2 will not be plotted. Default 10000,1000,100,10,1 for resolution
+ 'c','l','i','h','f'.
+
+ rsphere - radius of the sphere used to define map projection (default
+ 6370997 meters, close to the arithmetic mean radius of the earth). If
+ given as a sequence, the first two elements are interpreted as
+ the the radii of the major and minor axes of an ellipsoid. Note: sometimes
+ an ellipsoid is specified by the major axis and an 'inverse flattening
+ parameter' (if). The minor axis (b) can be computed from the major axis (a)
+ and the inverse flattening parameter using the formula if = a/(a-b).
+
+ suppress_ticks - suppress automatic drawing of axis ticks and labels
+ in map projection coordinates. Default False, so parallels and meridians
+ can be labelled instead. If parallel or meridian labelling is requested
+ (using drawparallels and drawmeridians methods), automatic tick labelling
+ will be supressed even is suppress_ticks=False. suppress_ticks=False
+ is useful if you want to use your own custom tick formatter, or
+ if you want to let matplotlib label the axes in meters
+ using native map projection coordinates
+
+ anchor - determines how map is placed in axes rectangle (passed to
+ axes.set_aspect). Default is 'C', which means map is centered.
+ Allowed values are ['C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'].
+
+ ax - set default axes instance (default None - pylab.gca() may be used
+ to get the current axes instance). If you don't want pylab to be imported,
+ you can either set this to a pre-defined axes instance, or use the 'ax'
+ keyword in each Basemap method call that does drawing. In the first case,
+ all Basemap method calls will draw to the same axes instance. In the
+ second case, you can draw to different axes with the same Basemap instance.
+ You can also use the 'ax' keyword in individual method calls to
+ selectively override the default axes instance.
+
+ The following parameters are map projection parameters which all default to
+ None. Not all parameters are used by all projections, some are ignored.
+ The module variable 'projection_params' is a dictionary which
+ lists which parameters apply to which projections.
+
+ lat_ts - latitude of true scale for mercator projection, optional
+ for stereographic projection.
+ lat_1 - first standard parallel for lambert conformal, albers
+ equal area projection and equidistant conic projections. Latitude of one
+ of the two points on the projection centerline for oblique mercator.
+ If lat_1 is not given, but lat_0 is, lat_1 is set to lat_0 for
+ lambert conformal, albers equal area and equidistant conic.
+ lat_2 - second standard parallel for lambert conformal, albers
+ equal area projection and equidistant conic projections. Latitude of one
+ of the two points on the projection centerline for oblique mercator.
+ If lat_2 is not given, it is set to lat_1 for
+ lambert conformal, albers equal area and equidistant conic.
+ lon_1 - longitude of one of the two points on the projection centerline
+ for oblique mercator.
+ lon_2 - longitude of one of the two points on the projection centerline
+ for oblique mercator.
+ lat_0 - central latitude (y-axis origin) - used by all projections,
+ Must be equator for mercator projection.
+ lon_0 - central meridian (x-axis origin) - used by all projections,
+ boundinglat - bounding latitude for pole-centered projections (npstere,spstere,
+ nplaea,splaea,npaeqd,spaeqd). These projections are square regions centered
+ on the north or south pole. The longitude lon_0 is at 6-o'clock, and the
+ latitude circle boundinglat is tangent to the edge of the map at lon_0.
+ satellite_height - height of satellite (in m) above equator -
+ only relevant for geostationary projections ('geos'). Default 35,786 km.
+
+ Here are the most commonly used class methods (see the docstring
+ for each for more details):
+
+ To draw a graticule grid (labelled latitude and longitude lines)
+ use the drawparallels and drawmeridians methods.
+
+ To draw coastline, rivers and political boundaries, use the
+ the drawcontinents, drawrivers, drawcountries and drawstates methods.
+
+ To fill the continents and inland lakes, use the fillcontinents method.
+
+ To draw the boundary of the map projection region, and fill the 
+ interior a certain color, use the drawmapboundary method.
+
+ The contour, contourf, pcolor, pcolormesh, plot, scatter
+ quiver and imshow methods use the corresponding matplotlib axes
+ methods to draw on the map.
+
+ The transform_scalar method can be used to interpolate regular
+ lat/lon grids of scalar data to native map projection grids.
+
+ The transform_vector method can be used to interpolate and rotate
+ regular lat/lon grids of vector data to native map projection grids.
+
+ The rotate_vector method rotates a vector field from lat/lon
+ coordinates into map projections coordinates, without doing any 
+ interpolation.
+
+ The readshapefile method can be used to read in data from ESRI
+ shapefiles.
+
+ The drawgreatcircle method draws great circles on the map.
+""" % locals()
+
+# unsupported projection error message.
+_unsupported_projection = ["'%s' is an unsupported projection.\n"]
+_unsupported_projection.append("The supported projections are:\n")
+_unsupported_projection.append(supported_projections)
+_unsupported_projection = ''.join(_unsupported_projection)
+
+def _validated_ll(param, name, minval, maxval):
+ param = float(param)
+ if param > maxval or param < minval:
+ raise ValueError('%s must be between %f and %f degrees' %
+ (name, minval, maxval))
+ return param
+
+def _insert_validated(d, param, name, minval, maxval):
+ if param is not None:
+ d[name] = _validated_ll(param, name, minval, maxval)
+
+class Basemap(object):
+ """
+ Class for plotting data on map projections with matplotlib.
+ See __init__ docstring for details on how to create a class
+ instance for a given map projection.
+
+ Useful instance variables:
+
+ projection - map projection. Print the module variable
+ "supported_projections" to see a list.
+ aspect - map aspect ratio (size of y dimension / size of x dimension).
+ llcrnrlon - longitude of lower left hand corner of the desired map domain.
+ llcrnrlon - latitude of lower left hand corner of the desired map domain.
+ urcrnrlon - longitude of upper right hand corner of the desired map domain.
+ urcrnrlon - latitude of upper right hand corner of the desired map domain.
+ llcrnrx,llcrnry,urcrnrx,urcrnry - corners of map domain in projection coordinates.
+ rmajor,rminor - equatorial and polar radii of ellipsoid used (in meters).
+ resolution - resolution of boundary dataset being used ('c' for crude,
+ 'l' for low, etc.). If None, no boundary dataset is associated with the
+ Basemap instance.
+ srs - a string representing the 'spatial reference system' for the map
+ projection as defined by PROJ.4.
+
+ Example Usage:
+
+ >>> from mpl_toolkits.basemap import Basemap
+ >>> from pylab import load, meshgrid, title, arange, show
+ >>> # read in topo data (on a regular lat/lon grid)
+ >>> etopo = load('etopo20data.gz')
+ >>> lons = load('etopo20lons.gz')
+ >>> lats = load('etopo20lats.gz')
+ >>> # create Basemap instance for Robinson projection.
+ >>> m = Basemap(projection='robin',lon_0=0.5*(lons[0]+lons[-1]))
+ >>> # compute native map projection coordinates for lat/lon grid.
+ >>> x, y = m(*meshgrid(lons,lats))
+ >>> # make filled contour plot.
+ >>> cs = m.contourf(x,y,etopo,30,cmap=cm.jet)
+ >>> m.drawcoastlines() # draw coastlines
+ >>> m.drawmapboundary() # draw a line around the map region
+ >>> m.drawparallels(arange(-90.,120.,30.),labels=[1,0,0,0]) # draw parallels
+ >>> m.drawmeridians(arange(0.,420.,60.),labels=[0,0,0,1]) # draw meridians
+ >>> title('Robinson Projection') # add a title
+ >>> show()
+
+ [this example (simpletest.py) plus many others can be found in the
+ examples directory of source distribution. The "OO" version of this
+ example (which does not use pylab) is called "simpletest_oo.py".]
+ """
+
+ def __init__(self, llcrnrlon=None, llcrnrlat=None,
+ urcrnrlon=None, urcrnrlat=None,
+ width=None, height=None,
+ projection='cyl', resolution='c',
+ area_thresh=None, rsphere=6370997.0,
+ lat_ts=None,
+ lat_1=None, lat_2=None,
+ lat_0=None, lon_0=None,
+ lon_1=None, lon_2=None,
+ suppress_ticks=True,
+ satellite_height=35786000,
+ boundinglat=None,
+ anchor='C',
+ ax=None):
+ # docstring is added after __init__ method definition
+
+ # where to put plot in figure (default is 'C' or center)
+ self.anchor = anchor
+ # map projection.
+ self.projection = projection
+
+ # set up projection parameter dict.
+ projparams = {}
+ projparams['proj'] = projection
+ try:
+ if rsphere[0] > rsphere[1]:
+ projparams['a'] = rsphere[0]
+ projparams['b'] = rsphere[1]
+ else:
+ projparams['a'] = rsphere[1]
+ projparams['b'] = rsphere[0]
+ except:
+ if projection == 'tmerc':
+ # use bR_a instead of R because of obscure bug
+ # in proj4 for tmerc projection.
+ projparams['bR_a'] = rsphere
+ else:
+ projparams['R'] = rsphere
+ # set units to meters.
+ projparams['units']='m'
+ # check for sane values of lon_0, lat_0, lat_ts, lat_1, lat_2
+ _insert_validated(projparams, lat_0, 'lat_0', -90, 90)
+ _insert_validated(projparams, lat_1, 'lat_1', -90, 90)
+ _insert_validated(projparams, lat_2, 'lat_2', -90, 90)
+ _insert_validated(projparams, lat_ts, 'lat_ts', -90, 90)
+ _insert_validated(projparams, lon_0, 'lon_0', -360, 720)
+ _insert_validated(projparams, lon_1, 'lon_1', -360, 720)
+ _insert_validated(projparams, lon_2, 'lon_2', -360, 720)
+ if projection == 'geos':
+ projparams['h'] = satellite_height
+ # check for sane values of projection corners.
+ using_corners = (None not in [llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat])
+ if using_corners:
+ self.llcrnrlon = _validated_ll(llcrnrlon, 'llcrnrlon', -360, 720)
+ self.urcrnrlon = _validated_ll(urcrnrlon, 'urcrnrlon', -360, 720)
+ self.llcrnrlat = _validated_ll(llcrnrlat, 'llcrnrlat', -90, 90)
+ self.urcrnrlat = _validated_ll(urcrnrlat, 'urcrnrlat', -90, 90)
+
+ # for each of the supported projections,
+ # compute lat/lon of domain corners
+ # and set values in projparams dict as needed.
+
+ if projection in ['lcc', 'eqdc', 'aea']:
+ # if lat_0 is given, but not lat_1,
+ # set lat_1=lat_0
+ if lat_1 is None and lat_0 is not None:
+ lat_1 = lat_0
+ projparams['lat_1'] = lat_1
+ if lat_1 is None or lon_0 is None:
+ raise ValueError('must specify lat_1 or lat_0 and lon_0 for %s basemap (lat_2 is optional)' % _projnames[projection])
+ if lat_2 is None:
+ projparams['lat_2'] = lat_1
+ if not using_corners:
+ if width is None or height is None:
+ raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ if lon_0 is None or lat_0 is None:
+ raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection == 'stere':
+ if lat_0 is None or lon_0 is None:
+ raise ValueError, 'must specify lat_0 and lon_0 for Stereographic basemap (lat_ts is optional)'
+ if not using_corners:
+ if width is None or height is None:
+ raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ if lon_0 is None or lat_0 is None:
+ raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection in ['spstere', 'npstere',
+ 'splaea', 'nplaea',
+ 'spaeqd', 'npaeqd']:
+ if boundinglat is None or lon_0 is None:
+ raise ValueError('must specify boundinglat and lon_0 for %s basemap' % _projnames[projection])
+ if projection[0] == 's':
+ sgn = -1
+ else:
+ sgn = 1
+ rootproj = projection[2:]
+ projparams['proj'] = rootproj
+ if rootproj == 'stere':
+ projparams['lat_ts'] = sgn * 90.
+ projparams['lat_0'] = sgn * 90.
+ self.llcrnrlon = lon_0 - sgn*45.
+ self.urcrnrlon = lon_0 + sgn*135.
+ proj = pyproj.Proj(projparams)
+ x,y = proj(lon_0,boundinglat)
+ lon,self.llcrnrlat = proj(math.sqrt(2.)*y,0.,inverse=True)
+ self.urcrnrlat = self.llcrnrlat
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % _projnames[projection]
+ elif projection == 'laea':
+ if lat_0 is None or lon_0 is None:
+ raise ValueError, 'must specify lat_0 and lon_0 for Lambert Azimuthal basemap'
+ if not using_corners:
+ if width is None or height is None:
+ raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ if lon_0 is None or lat_0 is None:
+ raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection == 'merc':
+ if lat_ts is None:
+ raise ValueError, 'must specify lat_ts for Mercator basemap'
+ # clip plot region to be within -89.99S to 89.99N
+ # (mercator is singular at poles)
+ if not using_corners:
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ if llcrnrlat < -89.99: llcrnrlat = -89.99
+ if llcrnrlat > 89.99: llcrnrlat = 89.99
+ if urcrnrlat < -89.99: urcrnrlat = -89.99
+ if urcrnrlat > 89.99: urcrnrlat = 89.99
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ elif projection in ['tmerc','gnom','cass','poly'] :
+ if lat_0 is None or lon_0 is None:
+ raise ValueError, 'must specify lat_0 and lon_0 for Transverse Mercator, Gnomonic, Cassini-Soldnerr Polyconic basemap'
+ if not using_corners:
+ if width is None or height is None:
+ raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ if lon_0 is None or lat_0 is None:
+ raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection == 'ortho':
+ if not projparams.has_key('R'):
+ raise ValueError, 'orthographic projection only works for perfect spheres - not ellipsoids'
+ if lat_0 is None or lon_0 is None:
+ raise ValueError, 'must specify lat_0 and lon_0 for Orthographic basemap'
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ if not using_corners:
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ self._fulldisk = True
+ else:
+ self._fulldisk = False
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ # FIXME: won't work for points exactly on equator??
+ if npy.abs(lat_0) < 1.e-2: lat_0 = 1.e-2
+ projparams['lat_0'] = lat_0
+ elif projection == 'geos':
+ if lon_0 is None:
+ raise ValueError, 'must specify lon_0 for Geostationary basemap'
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ if not using_corners:
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ self._fulldisk = True
+ else:
+ self._fulldisk = False
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection in ['moll','robin','sinu']:
+ if lon_0 is None:
+ raise ValueError, 'must specify lon_0 for Robinson, Mollweide, or Sinusoidal basemap'
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection == 'omerc':
+ if lat_1 is None or lon_1 is None or lat_2 is None or lon_2 is None:
+ raise ValueError, 'must specify lat_1,lon_1 and lat_2,lon_2 for Oblique Mercator basemap'
+ projparams['lat_1'] = lat_1
+ projparams['lon_1'] = lon_1
+ projparams['lat_2'] = lat_2
+ projparams['lon_2'] = lon_2
+ if not using_corners:
+ raise ValueError, 'cannot specify map region with width and height keywords for this projection, please specify lat/lon values of corners'
+ elif projection == 'aeqd':
+ if lat_0 is None or lon_0 is None:
+ raise ValueError, 'must specify lat_0 and lon_0 for Azimuthal Equidistant basemap'
+ if not using_corners:
+ if width is None or height is None:
+ raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ if lon_0 is None or lat_0 is None:
+ raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ elif projection == 'mill':
+ if not using_corners:
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ elif projection == 'cyl':
+ if not using_corners:
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
+ self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
+ if width is not None or height is not None:
+ print 'warning: width and height keywords ignored for %s projection' % self.projection
+ else:
+ raise ValueError(_unsupported_projection % projection)
+
+ # initialize proj4
+ proj = Proj(projparams,self.llcrnrlon,self.llcrnrlat,self.urcrnrlon,self.urcrnrlat)
+
+ # make sure axis ticks are suppressed.
+ self.noticks = suppress_ticks
+
+ # make Proj instance a Basemap instance variable.
+ self.projtran = proj
+ # copy some Proj attributes.
+ atts = ['rmajor','rminor','esq','flattening','ellipsoid','projparams']
+ for att in atts:
+ self.__dict__[att] = proj.__dict__[att]
+ # these only exist for geostationary projection.
+ if hasattr(proj,'_width'):
+ self.__dict__['_width'] = proj.__dict__['_width']
+ if hasattr(proj,'_height'):
+ self.__dict__['_height'] = proj.__dict__['_height']
+ # spatial reference string (useful for georeferencing output
+ # images with gdal_translate).
+ if hasattr(self,'_proj4'):
+ self.srs = proj._proj4.srs
+ else:
+ pjargs = []
+ for key,value in self.projparams.iteritems():
+ # 'cyl' projection translates to 'eqc' in PROJ.4
+ if projection == 'cyl' and key == 'proj':
+ value = 'eqc'
+ # ignore x_0 and y_0 settings for 'cyl' projection
+ # (they are not consistent with what PROJ.4 uses)
+ elif projection == 'cyl' and key in ['x_0','y_0']:
+ continue
+ pjargs.append('+'+key+"="+str(value)+' ')
+ self.srs = ''.join(pjargs)
+ # set instance variables defining map region.
+ self.xmin = proj.xmin
+ self.xmax = proj.xmax
+ self.ymin = proj.ymin
+ self.ymax = proj.ymax
+ if projection == 'cyl':
+ self.aspect = (self.urcrnrlat-self.llcrnrlat)/(self.urcrnrlon-self.llcrnrlon)
+ else:
+ self.aspect = (proj.ymax-proj.ymin)/(proj.xmax-proj.xmin)
+ self.llcrnrx = proj.llcrnrx
+ self.llcrnry = proj.llcrnry
+ self.urcrnrx = proj.urcrnrx
+ self.urcrnry = proj.urcrnry
+
+ # set min/max lats for projection domain.
+ if projection in ['mill','cyl','merc']:
+ self.latmin = self.llcrnrlat
+ self.latmax = self.urcrnrlat
+ elif projection in ['ortho','geos','moll','robin','sinu']:
+ self.latmin = -90.
+ self.latmax = 90.
+ else:
+ lons, lats = self.makegrid(101,101)
+ self.latmin = lats.min()
+ self.latmax = lats.max()
+
+ # if ax == None, pylab.gca may be used.
+ self.ax = ax
+ self.lsmask = None
+
+ # set defaults for area_thresh.
+ self.resolution = resolution
+ if area_thresh is None and resolution is not None:
+ if resolution == 'c':
+ area_thresh = 10000.
+ elif resolution == 'l':
+ area_thresh = 1000.
+ elif resolution == 'i':
+ area_thresh = 100.
+ elif resolution == 'h':
+ area_thresh = 10.
+ elif resolution == 'f':
+ area_thresh = 1.
+ else:
+ raise ValueError, "boundary resolution must be one of 'c','l','i','h' or 'f'"
+ self.area_thresh = area_thresh
+ # define map boundary polygon (in lat/lon coordinates)
+ self._boundarypolyll, self._boundarypolyxy = self._getmapboundary()
+ # read in coastline polygons, only keeping those that
+ # intersect map boundary polygon.
+ if self.resolution is not None:
+ self.coastsegs, self.coastpolygontypes = self._readboundarydata('gshhs')
+ # reformat for use in matplotlib.patches.Polygon.
+ self.coastpolygons = []
+ # also, split coastline segments that jump across entire plot.
+ coastsegs = []
+ for seg in self.coastsegs:
+ x, y = zip(*seg)
+ self.coastpolygons.append((x,y))
+ x = npy.array(x,npy.float64); y = npy.array(y,npy.float64)
+ xd = (x[1:]-x[0:-1])**2
+ yd = (y[1:]-y[0:-1])**2
+ dist = npy.sqrt(xd+yd)
+ split = dist > 5000000.
+ if npy.sum(split) and self.projection not in ['merc','cyl','mill']:
+ ind = (npy.compress(split,squeeze(split*npy.indices(xd.shape)))+1).tolist()
+ iprev = 0
+ ind.append(len(xd))
+ for i in ind:
+ # don't add empty lists.
+ if len(range(iprev,i)): 
+ coastsegs.append(zip(x[iprev:i],y[iprev:i]))
+ iprev = i
+ else:
+ coastsegs.append(seg)
+ self.coastsegs = coastsegs
+ # set __init__'s docstring
+ __init__.__doc__ = _Basemap_init_doc
+
+ def __call__(self,x,y,inverse=False):
+ """
+ Calling a Basemap class instance with the arguments lon, lat will
+ convert lon/lat (in degrees) to x/y native map projection
+ coordinates (in meters). If optional keyword 'inverse' is
+ True (default is False), the inverse transformation from x/y
+ to lon/lat is performed.
+
+ For cylindrical equidistant projection ('cyl'), this
+ does nothing (i.e. x,y == lon,lat).
+
+ For non-cylindrical projections, the inverse transformation
+ always returns longitudes between -180 and 180 degrees. For
+ cylindrical projections (self.projection == 'cyl','mill' or 'merc')
+ the inverse transformation will return longitudes between
+ self.llcrnrlon and self.llcrnrlat.
+
+ input arguments lon, lat can be either scalar floats or N arrays.
+ """
+ return self.projtran(x,y,inverse=inverse)
+
+ def makegrid(self,nx,ny,returnxy=False):
+ """
+ return arrays of shape (ny,nx) containing lon,lat coordinates of
+ an equally spaced native projection grid.
+ if returnxy = True, the x,y values of the grid are returned also.
+ """
+ return self.projtran.makegrid(nx,ny,returnxy=returnxy)
+
+ def _readboundarydata(self,name):
+ """
+ read boundary data, clip to map projection region.
+ """
+ msg = dedent("""
+ Unable to open boundary dataset file. Only the 'crude', 'low',
+ 'intermediate' and 'high' resolution datasets are installed by default.
+ If you are requesting a 'full' resolution dataset, you may need to
+ download and install those files separately
+ (see the basemap README for details).""")
+ try:
+ bdatfile = open(os.path.join(basemap_datadir,name+'_'+self.resolution+'.dat'),'rb')
+ bdatmetafile = open(os.path.join(basemap_datadir,name+'meta_'+self.resolution+'.dat'),'r')
+ except:
+ raise IOError, msg
+ polygons = []
+ polygon_types = []
+ # coastlines are polygons, other boundaries are line segments.
+ if name == 'gshhs':
+ Shape = _geos.Polygon
+ else:
+ Shape = _geos.LineString
+ # see if map projection region polygon contains a pole.
+ NPole = _geos.Point(self(0.,90.))
+ SPole = _geos.Point(self(0.,-90.))
+ boundarypolyxy = self._boundarypolyxy
+ boundarypolyll = self._boundarypolyll
+ hasNP = NPole.within(boundarypolyxy)
+ hasSP = SPole.within(boundarypolyxy)
+ containsPole = hasNP or hasSP
+ # these projections cannot cross pole.
+ if containsPole and\
+ self.projection in ['tmerc','cass','omerc','merc','mill','cyl','robin','moll','sinu','geos']:
+ raise ValueError('%s projection cannot cross pole'%(self.projection))
+ # make sure orthographic projection has containsPole=True
+ # we will compute the intersections in stereographic
+ # coordinates, then transform to orthographic.
+ if self.projection == 'ortho' and name == 'gshhs':
+ containsPole = True
+ lon_0=self.projparams['lon_0']
+ lat_0=self.projparams['lat_0']
+ re = self.projparams['R']
+ # center of stereographic projection restricted to be 
+ # nearest one of 6 points on the sphere (every 90 deg lat/lon).
+ lon0 = 90.*(npy.around(lon_0/90.))
+ lat0 = 90.*(npy.around(lat_0/90.))
+ if npy.abs(int(lat0)) == 90: lon0=0.
+ maptran = pyproj.Proj(proj='stere',lon_0=lon0,lat_0=lat0,R=re)
+ # boundary polygon for orthographic projection
+ # in stereographic coorindates.
+ b = self._boundarypolyll.boundary
+ blons = b[:,0]; blats = b[:,1]
+ b[:,0], b[:,1] = maptran(blons, blats)
+ boundarypolyxy = _geos.Polygon(b)
+ for line in bdatmetafile:
+ linesplit = line.split()
+ area = float(linesplit[1])
+ south = float(linesplit[3])
+ north = float(linesplit[4])
+ if area < 0.: area = 1.e30
+ useit = self.latmax>=south and self.latmin<=north and area>self.area_thresh
+ if useit:
+ type = int(linesplit[0])
+ npts = int(linesplit[2])
+ offsetbytes = int(linesplit[5])
+ bytecount = int(linesplit[6])
+ bdatfile.seek(offsetbytes,0)
+ # read in binary string convert into an npts by 2
+ # numpy array (first column is lons, second is lats).
+ polystring = bdatfile.read(bytecount)
+ # binary data is little endian.
+ b = npy.array(npy.fromstring(polystring,dtype='<f4'),'f8')
+ b.shape = (npts,2)
+ b2 = b.copy()
+ # if map boundary polygon is a valid one in lat/lon
+ # coordinates (i.e. it does not contain either pole),
+ # the intersections of the boundary geometries
+ # and the map projection region can be computed before
+ # transforming the boundary geometry to map projection
+ # coordinates (this saves time, especially for small map
+ # regions and high-resolution boundary geometries).
+ if not containsPole:
+ # close Antarctica.
+ if name == 'gshhs' and south < -68 and area > 10000:
+ lons = b[:,0]
+ lats = b[:,1]
+ lons2 = lons[:-2][::-1]
+ lats2 = lats[:-2][::-1]
+ lons1 = lons2 - 360.
+ lons3 = lons2 + 360.
+ lons = lons1.tolist()+lons2.tolist()+lons3.tolist()
+ lats = lats2.tolist()+lats2.tolist()+lats2.tolist()
+ lonstart,latstart = lons[0], lats[0]
+ lonend,latend = lons[-1], lats[-1]
+ lons.insert(0,lonstart)
+ lats.insert(0,-90.)
+ lons.append(lonend)
+ lats.append(-90.)
+ b = npy.empty((len(lons),2),npy.float64)
+ b[:,0] = lons; b[:,1] = lats
+ poly = _geos.Polygon(b)
+ antart = True
+ else:
+ poly = Shape(b)
+ antart = False
+ # create duplicate polygons shifted by -360 and +360
+ # (so as to properly treat polygons that cross
+ # Greenwich meridian).
+ if not antart:
+ b2[:,0] = b[:,0]-360
+ poly1 = Shape(b2)
+ b2[:,0] = b[:,0]+360
+ poly2 = Shape(b2)
+ polys = [poly1,poly,poly2]
+ else: # Antartica already extends from -360 to +720.
+ polys = [poly]
+ for poly in polys:
+ # if polygon instersects map projection
+ # region, process it.
+ if poly.intersects(boundarypolyll):
+ # if geometry intersection calculation fails,
+ # just move on.
+ try:
+ geoms = poly.intersection(boundarypolyll)
+ except:
+ continue
+ # iterate over geometries in intersection.
+ for psub in geoms:
+ # only coastlines are polygons,
+ # which have a 'boundary' attribute.
+ # otherwise, use 'coords' attribute
+ # to extract coordinates.
+ b = psub.boundary
+ blons = b[:,0]; blats = b[:,1]
+ # transformation from lat/lon to
+ # map projection coordinates.
+ bx, by = self(blons, blats)
+ polygons.append(zip(bx,by))
+ polygon_types.append(type)
+ # if map boundary polygon is not valid in lat/lon
+ # coordinates, compute intersection between map
+ # projection region and boundary geometries in map
+ # projection coordinates.
+ else:
+ # transform coordinates from lat/lon
+ # to map projection coordinates.
+ # special case for ortho, compute coastline polygon
+ # vertices in stereographic coords.
+ if name == 'gshhs' and self.projection == 'ortho':
+ b[:,0], b[:,1] = maptran(b[:,0], b[:,1])
+ else:
+ b[:,0], b[:,1] = self(b[:,0], b[:,1])
+ goodmask = npy.logical_and(b[:,0]<1.e20,b[:,1]<1.e20)
+ # if less than two points are valid in
+ # map proj coords, skip this geometry.
+ if npy.sum(goodmask) <= 1: continue
+ if name != 'gshhs':
+ # if not a polygon,
+ # just remove parts of geometry that are undefined
+ # in this map projection.
+ bx = npy.compress(goodmask, b[:,0])
+ by = npy.compress(goodmask, b[:,1])
+ # for orthographic projection, all points
+ # outside map projection region are eliminated
+ # with the above step, so we're done.
+ if self.projection == 'ortho':
+ polygons.append(zip(bx,by))
+ polygon_types.append(type)
+ continue
+ # create a GEOS geometry object.
+ poly = Shape(b)
+ # if geometry instersects map projection
+ # region, and doesn't have any invalid points, process it.
+ if goodmask.all() and poly.intersects(boundarypolyxy):
+ # if geometry intersection calculation fails,
+ # just move on.
+ try:
+ geoms = poly.intersection(boundarypolyxy)
+ except:
+ continue
+ # iterate over geometries in intersection.
+ for psub in geoms:
+ b = psub.boundary
+ # if projection == 'ortho',
+ # transform polygon from stereographic
+ # to orthographic coordinates.
+ if self.projection == 'ortho':
+ # if coastline polygon covers more than 99%
+ # of map region for fulldisk projection,
+ # it's probably bogus, so skip it.
+ areafrac = psub.area()/boundarypolyxy.area()
+ if name == 'gshhs' and\
+ self._fulldisk and\
+ areafrac > 0.99: continue
+ # inverse transform from stereographic
+ # to lat/lon.
+ b[:,0], b[:,1] = maptran(b[:,0], b[:,1], inverse=True)
+ # orthographic.
+ b[:,0], b[:,1]= self(b[:,0], b[:,1])
+ polygons.append(zip(b[:,0],b[:,1]))
+ polygon_types.append(type)
+ return polygons, polygon_types
+
+ def _getmapboundary(self):
+ """
+ create map boundary polygon (in lat/lon and x/y coordinates)
+ """
+ nx = 100
+ ny = 100
+ maptran = self
+ if self.projection in ['ortho','geos']:
+ # circular region.
+ thetas = linspace(0.,2.*npy.pi,2*nx*ny)[:-1]
+ if self.projection == 'ortho':
+ rminor = self.rmajor
+ rmajor = self.rmajor
+ else:
+ rminor = self._height
+ rmajor = self._width
+ x = rmajor*npy.cos(thetas) + rmajor
+ y = rminor*npy.sin(thetas) + rminor
+ b = npy.empty((len(x),2),npy.float64)
+ b[:,0]=x; b[:,1]=y
+ boundaryxy = _geos.Polygon(b)
+ # compute proj instance for full disk, if necessary.
+ if not self._fulldisk:
+ projparms = self.projparams
+ del projparms['x_0']
+ del projparms['y_0']
+ if self.projection == 'ortho':
+ llcrnrx = -self.rmajor
+ llcrnry = -self.rmajor
+ urcrnrx = -llcrnrx
+ urcrnry = -llcrnry
+ else:
+ llcrnrx = -self._width
+ llcrnry = -self._height
+ urcrnrx = -llcrnrx
+ urcrnry = -llcrnry
+ projparms['x_0']=-llcrnrx
+ projparms['y_0']=-llcrnry
+ maptran = pyproj.Proj(projparms)
+ elif self.projection in ['moll','robin','sinu']:
+ # quasi-elliptical region.
+ lon_0 = self.projparams['lon_0']
+ # left side
+ lats1 = linspace(-89.9,89.9,ny).tolist()
+ lons1 = len(lats1)*[lon_0-179.9]
+ # top.
+ lons2 = linspace(lon_0-179.9,lon_0+179.9,nx).tolist()
+ lats2 = len(lons2)*[89.9]
+ # right side
+ lats3 = linspace(89.9,-89.9,ny).tolist()
+ lons3 = len(lats3)*[lon_0+179.9]
+ # bottom.
+ lons4 = linspace(lon_0+179.9,lon_0-179.9,nx).tolist()
+ lats4 = len(lons4)*[-89.9]
+ lons = npy.array(lons1+lons2+lons3+lons4,npy.float64)
+ lats = npy.array(lats1+lats2+lats3+lats4,npy.float64)
+ x, y = maptran(lons,lats)
+ b = npy.empty((len(x),2),npy.float64)
+ b[:,0]=x; b[:,1]=y
+ boundaryxy = _geos.Polygon(b)
+ else: # all other projections are rectangular.
+ # left side (x = xmin, ymin <= y <= ymax)
+ yy = linspace(self.ymin, self.ymax, ny)[:-1]
+ x = len(yy)*[self.xmin]; y = yy.tolist()
+ # top (y = ymax, xmin <= x <= xmax)
+ xx = npy.linspace(self.xmin, self.xmax, nx)[:-1]
+ x = x + xx.tolist()
+ y = y + len(xx)*[self.ymax]
+ # right side (x = xmax, ymin <= y <= ymax)
+ yy = linspace(self.ymax, self.ymin, ny)[:-1]
+ x = x + len(yy)*[self.xmax]; y = y + yy.tolist()
+ # bottom (y = ymin, xmin <= x <= xmax)
+ xx = linspace(self.xmax, self.xmin, nx)[:-1]
+ x = x + xx.tolist()
+ y = y + len(xx)*[self.ymin]
+ x = npy.array(x,npy.float64)
+ y = npy.array(y,npy.float64)
+ b = npy.empty((4,2),npy.float64)
+ b[:,0]=[self.xmin,self.xmin,self.xmax,self.xmax]
+ b[:,1]=[self.ymin,self.ymax,self.ymax,self.ymin]
+ boundaryxy = _geos.Polygon(b)
+ if self.projection in ['mill','merc','cyl']:
+ # make sure map boundary doesn't quite include pole.
+ if self.urcrnrlat > 89.9999:
+ urcrnrlat = 89.9999
+ else:
+ urcrnrlat = self.urcrnrlat
+ if self.llcrnrlat < -89.9999:
+ llcrnrlat = -89.9999
+ else:
+ llcrnrlat = self.llcrnrlat
+ lons = [self.llcrnrlon, self.llcrnrlon, self.urcrnrlon, self.urcrnrlon]
+ lats = [llcrnrlat, urcrnrlat, urcrnrlat, llcrnrlat]
+ x, y = self(lons, lats)
+ b = npy.empty((len(x),2),npy.float64)
+ b[:,0]=x; b[:,1]=y
+ boundaryxy = _geos.Polygon(b)
+ else:
+ if self.projection not in ['moll','robin','sinu']:
+ lons, lats = maptran(x,y,inverse=True)
+ # fix lons so there are no jumps.
+ n = 1
+ lonprev = lons[0]
+ for lon,lat in zip(lons[1:],lats[1:]):
+ if npy.abs(lon-lonprev) > 90.:
+ if lonprev < 0:
+ lon = lon - 360.
+ else:
+ lon = lon + 360
+ lons[n] = lon
+ lonprev = lon
+ n = n + 1
+ b = npy.empty((len(lons),2),npy.float64)
+ b[:,0]=lons; b[:,1]=lats
+ boundaryll = _geos.Polygon(b)
+ return boundaryll, boundaryxy
+
+
+ def drawmapboundary(self,color='k',linewidth=1.0,fill_color=None,\
+ zorder=None,ax=None):
+ """
+ draw boundary around map projection region, optionally
+ filling interior of region.
+
+ linewidth - line width for boundary (default 1.)
+ color - color of boundary line (default black)
+ fill_color - fill the map region background with this
+ color (default is no fill or fill with axis background color).
+ zorder - sets the zorder for filling map background
+ (default 0).
+ ax - axes instance to use (default None, use default axes 
+ instance).
+ """
+ # get current axes instance (if none specified).
+ if ax is None and...
 
[truncated message content]
From: <md...@us...> - 2008年01月10日 13:38:46
Revision: 4846
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4846&view=rev
Author: mdboom
Date: 2008年01月10日 05:38:37 -0800 (2008年1月10日)
Log Message:
-----------
Merge Darren's win32 build changes to the maintenance branch (since
they'll be handy there also).
Modified Paths:
--------------
 branches/v0_91_maint/CHANGELOG
 branches/v0_91_maint/setup.py
Modified: branches/v0_91_maint/CHANGELOG
===================================================================
--- branches/v0_91_maint/CHANGELOG	2008年01月10日 13:38:31 UTC (rev 4845)
+++ branches/v0_91_maint/CHANGELOG	2008年01月10日 13:38:37 UTC (rev 4846)
@@ -1,3 +1,10 @@
+2008年01月10日 Fix bug when displaying a tick value offset with scientific
+ notation. (Manifests itself as a warning that the \times
+ symbol can not be found). - MGD
+
+2008年01月10日 Use setup.cfg to set the default parameters (tkagg,
+ numpy) when building windows installers - DSD
+
 ===============================================================
 2008年01月06日 Released 0.91.2 at revision 4802
 
Modified: branches/v0_91_maint/setup.py
===================================================================
--- branches/v0_91_maint/setup.py	2008年01月10日 13:38:31 UTC (rev 4845)
+++ branches/v0_91_maint/setup.py	2008年01月10日 13:38:37 UTC (rev 4846)
@@ -8,7 +8,7 @@
 """
 
 # This dict will be updated as we try to select the best option during
-# the build process. However, values in setup.cfg will be used, if 
+# the build process. However, values in setup.cfg will be used, if
 # defined.
 rc = {'backend':'Agg', 'numerix':'numpy'}
 
@@ -36,7 +36,7 @@
 
 if major==2 and minor1<3 or major<2:
 raise SystemExit("""matplotlib requires Python 2.3 or later.""")
- 
+
 import glob
 from distutils.core import setup
 from setupext import build_agg, build_gtkagg, build_tkagg, build_wxagg,\
@@ -112,7 +112,7 @@
 subprocess_dir = os.path.dirname(subprocess.__file__)
 if subprocess_dir.endswith('.egg/subprocess'):
 havesubprocess = False
- 
+
 if not havesubprocess:
 packages.append('subprocess')
 if sys.platform == 'win32':
@@ -120,7 +120,7 @@
 
 if not check_for_freetype():
 sys.exit(1)
- 
+
 build_ft2font(ext_modules, packages)
 build_ttconv(ext_modules, packages)
 build_contour(ext_modules, packages)
@@ -145,7 +145,7 @@
 build_windowing(ext_modules, packages)
 
 # the options can be True, False, or 'auto'. If True, try to build
-# regardless of the lack of dependencies. If auto, silently skip 
+# regardless of the lack of dependencies. If auto, silently skip
 # when dependencies are missing.
 if options['build_tkagg']:
 if check_for_tk() or (options['build_tkagg'] is True):
@@ -188,12 +188,12 @@
 
 if hasdatetime: # dates require python23 datetime
 # only install pytz and dateutil if the user hasn't got them
- 
+
 def add_pytz():
 packages.append('pytz')
 resources = ['zone.tab', 'locales/pytz.pot']
 # install pytz subdirs
- for dirpath, dirname, filenames in os.walk(os.path.join('lib', 'pytz', 
+ for dirpath, dirname, filenames in os.walk(os.path.join('lib', 'pytz',
 'zoneinfo')):
 if '.svn' not in dirpath:
 # remove the 'lib/pytz' part of the path
@@ -237,12 +237,8 @@
 print_line()
 
 # Write the default matplotlibrc file
-if sys.platform=='win32':
- rc['backend'] = 'TkAgg'
- rc['numerix'] = 'numpy'
-else:
- if options['backend']: rc['backend'] = options['backend']
- if options['numerix']: rc['numerix'] = options['numerix']
+if options['backend']: rc['backend'] = options['backend']
+if options['numerix']: rc['numerix'] = options['numerix']
 template = file('matplotlibrc.template').read()
 file('lib/matplotlib/mpl-data/matplotlibrc', 'w').write(template%rc)
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 13:38:39
Revision: 4845
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4845&view=rev
Author: jswhit
Date: 2008年01月10日 05:38:31 -0800 (2008年1月10日)
Log Message:
-----------
moved into mpl_toolkits
Modified Paths:
--------------
 trunk/toolkits/mplsizer/demo/demo_basic.py
 trunk/toolkits/mplsizer/demo/demo_gridsizer.py
 trunk/toolkits/mplsizer/demo/demo_gridsizer2.py
 trunk/toolkits/mplsizer/demo/demo_minsize.py
 trunk/toolkits/mplsizer/setup.py
Added Paths:
-----------
 trunk/toolkits/mplsizer/mpl_toolkits/
 trunk/toolkits/mplsizer/mpl_toolkits/__init__.py
 trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/
 trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/__init__.py
 trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/mplsizer.py
Removed Paths:
-------------
 trunk/toolkits/mplsizer/matplotlib/
Modified: trunk/toolkits/mplsizer/demo/demo_basic.py
===================================================================
--- trunk/toolkits/mplsizer/demo/demo_basic.py	2008年01月10日 13:33:03 UTC (rev 4844)
+++ trunk/toolkits/mplsizer/demo/demo_basic.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -63,7 +63,7 @@
 if 1:
 # Now perform the mplsizer stuff
 
- import matplotlib.toolkits.mplsizer as mplsizer
+ import mpl_toolkits.mplsizer as mplsizer
 
 frame = mplsizer.MplSizerFrame( fig )
 sizer = mplsizer.MplBoxSizer()
Modified: trunk/toolkits/mplsizer/demo/demo_gridsizer.py
===================================================================
--- trunk/toolkits/mplsizer/demo/demo_gridsizer.py	2008年01月10日 13:33:03 UTC (rev 4844)
+++ trunk/toolkits/mplsizer/demo/demo_gridsizer.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -47,7 +47,7 @@
 if 1:
 # Now perform the mplsizer stuff
 
- import matplotlib.toolkits.mplsizer as mplsizer
+ import mpl_toolkits.mplsizer as mplsizer
 
 frame = mplsizer.MplSizerFrame( fig )
 sizer = mplsizer.MplBoxSizer()#orientation='horizontal')
Modified: trunk/toolkits/mplsizer/demo/demo_gridsizer2.py
===================================================================
--- trunk/toolkits/mplsizer/demo/demo_gridsizer2.py	2008年01月10日 13:33:03 UTC (rev 4844)
+++ trunk/toolkits/mplsizer/demo/demo_gridsizer2.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -16,7 +16,7 @@
 # simply return a previous Axes instance with the same bounding box,
 # assign a different label to each Axes instance.
 
-import matplotlib.toolkits.mplsizer as mplsizer
+import mpl_toolkits.mplsizer as mplsizer
 
 frame = mplsizer.MplSizerFrame( fig )
 sizer = mplsizer.MplBoxSizer()#orientation='horizontal')
Modified: trunk/toolkits/mplsizer/demo/demo_minsize.py
===================================================================
--- trunk/toolkits/mplsizer/demo/demo_minsize.py	2008年01月10日 13:33:03 UTC (rev 4844)
+++ trunk/toolkits/mplsizer/demo/demo_minsize.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -1,5 +1,5 @@
 import pylab
-import matplotlib.toolkits.mplsizer as mplsizer
+import mpl_toolkits.mplsizer as mplsizer
 
 # Demonstration of minsize use.
 
Added: trunk/toolkits/mplsizer/mpl_toolkits/__init__.py
===================================================================
--- trunk/toolkits/mplsizer/mpl_toolkits/__init__.py	 (rev 0)
+++ trunk/toolkits/mplsizer/mpl_toolkits/__init__.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -0,0 +1,4 @@
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ pass # must not have setuptools
Added: trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/__init__.py
===================================================================
--- trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/__init__.py	 (rev 0)
+++ trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/__init__.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -0,0 +1 @@
+from mplsizer import *
Added: trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/mplsizer.py
===================================================================
--- trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/mplsizer.py	 (rev 0)
+++ trunk/toolkits/mplsizer/mpl_toolkits/mplsizer/mplsizer.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -0,0 +1,500 @@
+from __future__ import division
+import math
+import matplotlib.numerix as nx
+from matplotlib.axes import Axes
+
+_axes_sizer_elements = {}
+_sizer_flags = ['left','right','bottom','top','all',
+ 'expand',
+ 'align_centre',
+ 'align_centre_vertical',
+ 'align_centre_horizontal',
+ 'align_right',
+ 'align_bottom',
+ ]
+
+def as_sizer_element(ax,**kwargs):
+ if ax in _axes_sizer_elements:
+ el = _axes_sizer_elements[ax]
+ return el
+
+ if isinstance(ax,Axes):
+ el = MplAxesSizerElement(ax,**kwargs)
+ _axes_sizer_elements[ax] = el # allow warning when adding twice
+ return el
+
+ else:
+ raise ValueError("")
+
+class MplSizerElement:
+ """encapsulates anything that can be an element in a sizer"""
+ def __init__(self,**kwargs):
+ self.option = 0 # "weight" along sizer direction
+ self.flag = {}
+ self.border = 0 # in inches
+ self.minsize = (1.0,1.0) # width, height in inches
+ self.name = ''
+ self._border_rect = None
+ self._rect = None
+ self._update_sizer_element_kwargs(**kwargs)
+ def _update_sizer_element_kwargs(self,**kwargs):
+ for key,value in kwargs.iteritems():
+ if key in ['option','border','minsize','name']:
+ setattr(self,key,value)
+ elif key in _sizer_flags:
+ self.flag[key]=value
+ else:
+ raise ValueError('key "%s" is not understood'%key) # hint: try centre instead of center
+ self.Update() # update self.minsize and self.minsize_bordered
+ 
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplSizerElement\n'
+ return buf
+ 
+ def Update(self):
+ # updates self.minsize and self.minsize_bordered
+ 
+ left = self.flag.get('left',False) or self.flag.get('all',False)
+ right = self.flag.get('right',False) or self.flag.get('all',False)
+ bottom = self.flag.get('bottom',False) or self.flag.get('all',False)
+ top = self.flag.get('top',False) or self.flag.get('all',False)
+
+ hborder = 0
+ vborder = 0
+ if left: hborder += self.border
+ if right: hborder += self.border
+ if bottom: vborder += self.border
+ if top: vborder += self.border
+
+ # self.minsize already set
+ self.minsize_bordered = [self.minsize[0]+hborder,
+ self.minsize[1]+vborder]
+
+ if 0:
+ print self.name,'MplSizerElement.Update() setting minsize_bordered',self.minsize_bordered
+ print self.name,'MplSizerElement.Update() setting minsize',self.minsize
+ print
+ return
+ 
+ def _layout(self,lbrt_inch,fig_w_inch,fig_h_inch,eps=1e-10):
+ #print 'MplSizerElement._layout',self,self.name,lbrt_inch
+
+ # check if we have to request larger size
+ # check size allocation, which must include room for this element's borders
+ request_w_inch = None
+ request_h_inch = None
+ if self.minsize_bordered[0]-eps > (lbrt_inch[2]-lbrt_inch[0]):
+ request_w_inch = self.minsize_bordered[0]
+## print 'self.minsize_bordered[0]',repr(self.minsize_bordered[0])
+## print '(lbrt_inch[2]-lbrt_inch[0])',repr((lbrt_inch[2]-lbrt_inch[0]))
+## print 'requesting width increase',self,self.name,request_w_inch
+## print
+ if self.minsize_bordered[1]-eps > (lbrt_inch[3]-lbrt_inch[1]):
+ request_h_inch = self.minsize_bordered[1]
+# print 'requesting height increase',self,self.name,request_h_inch
+ if (request_w_inch is not None) or (request_h_inch is not None):
+ return request_w_inch, request_h_inch
+
+ w_inch = lbrt_inch[2]-lbrt_inch[0]
+ h_inch = lbrt_inch[3]-lbrt_inch[1]
+ self._border_rect = (lbrt_inch[0]/fig_w_inch, lbrt_inch[1]/fig_h_inch,
+ w_inch/fig_w_inch, h_inch/fig_h_inch )
+
+ # remove border sizes
+ l,b,r,t = lbrt_inch
+ left = self.flag.get('left',False) or self.flag.get('all',False)
+ right = self.flag.get('right',False) or self.flag.get('all',False)
+ bottom = self.flag.get('bottom',False) or self.flag.get('all',False)
+ top = self.flag.get('top',False) or self.flag.get('all',False)
+ if left: l+=self.border
+ if bottom: b+=self.border
+ if right: r-=self.border
+ if top: t-=self.border
+ lbrt_inch = l,b,r,t
+
+ # calculate MPL coords
+ w_inch = lbrt_inch[2]-lbrt_inch[0]
+ h_inch = lbrt_inch[3]-lbrt_inch[1]
+ self._rect = (lbrt_inch[0]/fig_w_inch, lbrt_inch[1]/fig_h_inch,
+ w_inch/fig_w_inch, h_inch/fig_h_inch )
+ 
+ # call derived class layout_core (where the action is)
+ return self._layout_core(lbrt_inch,fig_w_inch,fig_h_inch)
+ 
+ def _layout_core(self,lbrt_inch,fig_w_inch,fig_h_inch):
+ # does nothing in this base class -- override for interesting behavior
+ return None,None
+ 
+class MplAxesSizerElement( MplSizerElement ):
+ def __init__(self,ax,**kwargs):
+ self.ax = ax
+ MplSizerElement.__init__(self,**kwargs)
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplAxesSizerElement: %s\n'%repr(self.ax)
+ return buf
+ def _layout_core(self,lbrt_inch,fig_w_inch,fig_h_inch):
+ if self.ax is not None:
+ self.ax.set_position(self._rect)
+## if 1:
+## print 'assigning "%s" to MPL'%self.name,self.ax,'(%.2f,%.2f,%.2f,%.2f)'%self._rect
+## print ' from:',lbrt_inch,fig_w_inch,fig_h_inch
+## print
+ return None,None
+
+class MplSizer( MplSizerElement ):
+ """abstract sizer class that holds elements"""
+ def __init__(self):
+ self.elements = []
+ MplSizerElement.__init__(self)
+ def Add(self, element, **kwargs):
+ if not isinstance(element,MplSizerElement):
+ element = as_sizer_element(element,**kwargs)
+ else:
+ element._update_sizer_element_kwargs(**kwargs)
+ if element in self.elements:
+ raise ValueError("element already in MplSizer")
+ # update
+ self.elements.append( element )
+ self.Update()
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplSizer:\n'
+ for el in self.elements:
+ buf += el._show_contents(indent=indent+2)
+ return buf
+ 
+class MplBoxSizer( MplSizer ):
+ """vertical or horizontal sizer"""
+ def __init__(self,orientation=None):
+ if orientation is None:
+ orientation='vertical'
+ if orientation not in ['vertical','horizontal']:
+ raise ValueError("only horizontal and vertical orientations allowed")
+ self.orientation = orientation
+ MplSizer.__init__(self)
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplBoxSizer:\n'
+ buf += MplSizer._show_contents(self,indent+2)
+ return buf
+
+ def Update(self):
+ # calculate minsize based on minsize_bordered of children
+ if self.orientation.startswith('v'):
+ vertical=True
+ elif self.orientation.startswith('h'):
+ vertical=False
+ else: ValueError("only vertical and horizontal supported")
+
+ if vertical:
+ dir_idx=1
+ other_idx=0
+ else:
+ dir_idx=0
+ other_idx=1
+ 
+ minsize = [0,0]
+ for el in self.elements:
+ el.Update() # updates minsize, may not be necessary
+ dir_minsize = el.minsize_bordered[dir_idx]
+ other_minsize = el.minsize_bordered[other_idx]
+ 
+ minsize[dir_idx] = minsize[dir_idx] + dir_minsize
+ minsize[other_idx] = max(minsize[other_idx],other_minsize)
+ 
+ self.minsize = minsize
+ #print self.name,'MplBoxSizer.Update() setting minsize',self.minsize
+ MplSizer.Update(self) # call base class (sets self.minsize_bordered)
+
+ def _layout_core(self,lbrt_inch,fig_w_inch,fig_h_inch):
+ #print 'MplBoxSizer._layout_core',self,self.name,lbrt_inch
+ 
+ if self.orientation.startswith('v'):
+ vertical=True
+ elif self.orientation.startswith('h'):
+ vertical=False
+ else: ValueError("only vertical and horizontal supported")
+ 
+ if vertical:
+ dir_idx = 1
+ sizer_width_inch = lbrt_inch[2]-lbrt_inch[0]
+ else:
+ dir_idx = 0
+ sizer_height_inch = lbrt_inch[3]-lbrt_inch[1]
+
+ start = lbrt_inch[dir_idx+0]
+ stop = lbrt_inch[dir_idx+2]
+ dist_avail = stop-start
+ total_weight = 0
+ 
+ # first iteration -- find inches remaining after borders and minsizes allocated
+ optioned_minimum = 0
+ for el in self.elements:
+ if el.option == 0:
+ dist_avail -= el.minsize_bordered[dir_idx]
+ else:
+ # make sure we don't give less than requested
+ optioned_minimum += el.minsize_bordered[dir_idx]
+ total_weight += el.option
+
+ use_option = False
+ if dist_avail > optioned_minimum:
+ # OK, we can allocate using expansion options
+ use_option = True
+ if total_weight > 0:
+ dist_inc = dist_avail/total_weight
+ else:
+ dist_inc = None
+
+ if vertical:
+ # go top to bottom
+ current_location_inch = lbrt_inch[3]
+ dir = -1
+ else:
+ # go left to right
+ current_location_inch = lbrt_inch[0]
+ dir = 1
+
+ req_w_inch = None
+ req_h_inch = None
+
+ for el in self.elements:
+ #print 'self, el, el.flag',self, el, el.flag
+ # calculate the bordered region and call element's ._layout()
+ # the element itself must deal with removing the border
+ el_lt = current_location_inch
+ if (el.option > 0) and use_option:
+ current_location_inch += dir*dist_inc*el.option
+ #print 'boxsizer',self.name,'el %s dir=%f dist_inc=%f option=%f'%(el.name,
+ # dir,
+ # dist_inc,
+ # el.option)
+ else:
+ current_location_inch += dir*el.minsize_bordered[dir_idx]
+ el_rb = current_location_inch
+ 
+ if vertical:
+ el_bottom = el_rb
+ el_top = el_lt
+ #print 'vert boxsizer',self.name,'el',el.name
+ #print 'vert boxsizer',self.name,'el top',el_top
+ #print 'vert boxsizer',self.name,'el bottom',el_bottom
+ if el.flag.get('expand',False):
+ # expand horizontally
+ el_lbrt_inch = (lbrt_inch[0], el_bottom,
+ lbrt_inch[2], el_top)
+ else:
+ minwidth = el.minsize_bordered[0]
+ if (el.flag.get('align_centre_horizontal',False) or
+ el.flag.get('align_centre',False)):
+ w0 = sizer_width_inch/2-minwidth/2
+ w1 = sizer_width_inch/2+minwidth/2
+ el_lbrt_inch = (lbrt_inch[0]+w0, el_bottom,
+ lbrt_inch[0]+w1, el_top)
+ elif el.flag.get('align_right',False):
+ #print 'aligning right!'
+ el_lbrt_inch = (lbrt_inch[2]-minwidth, el_bottom,
+ lbrt_inch[2], el_top)
+ else:
+ el_lbrt_inch = (lbrt_inch[0], el_bottom,
+ lbrt_inch[0]+minwidth, el_top)
+ 
+ else: #horizonal
+ el_left = el_lt
+ el_right = el_rb
+ if el.flag.get('expand',False):
+ # expand vertically
+ el_lbrt_inch = (el_left, lbrt_inch[1], el_right, lbrt_inch[3])
+ else:
+ minheight = el.minsize_bordered[1]
+ if (el.flag.get('align_centre_vertical',False) or
+ el.flag.get('align_centre',False)):
+ #print 'sizer_height_inch',sizer_height_inch
+ #print 'minheight',minheight
+ h0 = sizer_height_inch/2-minheight/2
+ h1 = sizer_height_inch/2+minheight/2
+ #print 'h0',h0
+ #print 'h1',h1
+ el_lbrt_inch = (el_left, lbrt_inch[1]+h0,
+ el_right, lbrt_inch[1]+h1)
+ elif el.flag.get('align_bottom',False):
+ el_lbrt_inch = (el_left, lbrt_inch[1],
+ el_right, lbrt_inch[1]+minheight)
+ else:
+ el_lbrt_inch = (el_left, lbrt_inch[3]-minheight,
+ el_right, lbrt_inch[3])
+ #print 'BoxSizer',self.name,'allocating',el_lbrt_inch,'to',el.name
+ this_req_w_inch, this_req_h_inch = el._layout(el_lbrt_inch,
+ fig_w_inch,fig_h_inch)
+ req_w_inch = max(req_w_inch,this_req_w_inch)
+ req_h_inch = max(req_h_inch,this_req_h_inch)
+ #print 'MplBoxSizer',self,'req_w_inch, req_h_inch',req_w_inch, req_h_inch
+
+ # call base class
+ return req_w_inch, req_h_inch
+
+class MplGridSizer( MplSizer ):
+ """vertical or horizontal sizer"""
+ def __init__(self,cols=2,hgap=0.0,vgap=0.0,append_horiz=True):
+ self.cols = cols
+ self.hgap_inch = hgap
+ self.vgap_inch = vgap
+ self.append_horiz = append_horiz # if true, add horizontally
+ MplSizer.__init__(self)
+ 
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplGridSizer:\n'
+ buf += MplSizer._show_contents(self,indent+2)
+ return buf
+
+ def Update(self):
+ # calculate minsize based on minsize_bordered of children
+ maxel = [0,0]
+ for el in self.elements:
+ el.Update() # updates minsize, may not be necessary
+ maxel[0] = max(maxel[0],el.minsize_bordered[0])
+ maxel[1] = max(maxel[1],el.minsize_bordered[1])
+
+ n_hgaps = max(0,self.cols-1)
+ total_hgap = n_hgaps*self.hgap_inch
+ rows = int(math.ceil(len(self.elements)/self.cols))
+ n_vgaps = max(0,rows-1)
+ total_vgap = n_vgaps*self.vgap_inch
+ minsize0 = maxel[0]*self.cols + total_hgap
+ minsize1 = maxel[1]*rows + total_vgap
+ self.minsize = (minsize0,minsize1)
+ #print self.name,'MplGridSizer.Update() setting minsize',self.minsize
+ MplSizer.Update(self) # call base class (sets self.minsize_bordered)
+
+ def _layout_core(self,lbrt_inch,fig_w_inch,fig_h_inch):
+ #print
+ #print 'MplGridSizer._layout_core',self,self.name,lbrt_inch
+
+## print 'len(self.elements)',len(self.elements)
+## print 'self.cols',self.cols
+## print 'len(self.elements)/self.cols',len(self.elements)/self.cols
+ rows = int(math.ceil(len(self.elements)/self.cols))
+## print 'rows',rows
+
+ n_hgaps = max(0,self.cols-1)
+ total_hgap = n_hgaps*self.hgap_inch
+ 
+ if self.flag.get('expand',False):
+ total_width_inches = lbrt_inch[2]-lbrt_inch[0]
+ else:
+ total_width_inches = self.minsize[0]
+ col_width = (total_width_inches-total_hgap)/self.cols
+ col_stride = col_width + self.hgap_inch
+ 
+ n_vgaps = max(0,rows-1)
+ total_vgap = n_vgaps*self.vgap_inch
+
+ if self.flag.get('expand',False):
+ total_height_inches = lbrt_inch[3]-lbrt_inch[1]
+ else:
+ total_height_inches = self.minsize[1]
+ row_height = (total_height_inches-total_vgap)/rows
+ row_stride = row_height + self.vgap_inch
+
+ req_w_inch = None
+ req_h_inch = None
+ 
+ for i in range(rows):
+ y1 = lbrt_inch[3] - i*row_stride # top
+ y0 = lbrt_inch[3] - i*row_stride - row_height # bottom
+ #print 'i',i
+ #print 'y0,y1',y0,y1
+ for j in range(self.cols):
+ if self.append_horiz:
+ idx = i*self.cols+j
+ else:
+ idx = j*rows+i
+ if idx >= len(self.elements):
+ continue
+
+ el = self.elements[idx]
+ 
+ x0 = lbrt_inch[0] + j*col_stride
+ x1 = lbrt_inch[0] + j*col_stride + col_width
+
+ if el.flag.get('expand',False):
+ el_lbrt_inch = (x0,y0,x1,y1)
+ else:
+ x05 = (x0+x1)/2
+ y05 = (y0+y1)/2
+ w = el.minsize_bordered[0]
+ h = el.minsize_bordered[1]
+ w2 = w/2
+ h2 = h/2
+ if el.flag.get('align_centre',False):
+ el_lbrt_inch = (x05-w2,y05-h2,
+ x05+w2,y05+h2)
+ elif el.flag.get('align_centre_horizontal',False):
+ el_lbrt_inch = (x05-w2,y1-h,
+ x05+w2,y1)
+ elif el.flag.get('align_centre_vertical',False):
+ el_lbrt_inch = (x0, y05-h2,
+ x0+w,y05+h2)
+ # XXX more needed
+ else:
+ # top left default
+ el_lbrt_inch = (x0, y1-h,
+ x0+w,y1)
+ #print 'el_lbrt_inch',el_lbrt_inch
+ this_req_w_inch, this_req_h_inch = el._layout(el_lbrt_inch,
+ fig_w_inch,fig_h_inch)
+ req_w_inch = max(req_w_inch,this_req_w_inch)
+ req_h_inch = max(req_h_inch,this_req_h_inch)
+
+ if req_w_inch is not None:
+ req_w_inch = self.cols*req_w_inch
+ 
+ if req_h_inch is not None:
+ req_h_inch = rows*req_h_inch
+ 
+ # call base class
+ return req_w_inch, req_h_inch
+ 
+class MplSizerFrame:
+ def __init__(self,fig):
+ self.fig = fig
+ self.sizer = None
+ def _show_contents(self,indent=0):
+ buf = (' '*indent)+'MplSizerFrame:\n'
+ buf += self.sizer._show_contents(indent+2)
+ return buf
+ def SetSizer(self,sizer, **kwargs):
+ """like Add but only a single sizer can be added"""
+ sizer._update_sizer_element_kwargs(**kwargs)
+ sizer.Update() # calculate minsize requirements
+ self.sizer = sizer
+ 
+ def Layout(self):
+ self.sizer.Update() # calculate minsize requirements
+ 
+ fig_w_inch = self.fig.get_figwidth()
+ fig_h_inch = self.fig.get_figheight()
+ lbrt_inch = (0,0,fig_w_inch,fig_h_inch) # bounding box within figure
+ req_w_inch, req_h_inch = self.sizer._layout(lbrt_inch,fig_w_inch,fig_h_inch)
+# print '1: req_w_inch, req_h_inch',repr(req_w_inch), repr(req_h_inch)
+
+ # this is a mini-hack to deal with floating point imprecision
+ max_tries = 1
+ eps=1e-8
+ for ntry in range(max_tries):
+ if (req_w_inch is not None) or (req_h_inch is not None):
+ # request was made to enlarge the figure
+ if req_w_inch is not None:
+ self.fig.set_figwidth(req_w_inch+ntry*eps)
+ if req_h_inch is not None:
+ self.fig.set_figheight(req_h_inch+ntry*eps)
+
+ fig_w_inch = self.fig.get_figwidth()
+## print 'fig_w_inch',fig_w_inch
+ fig_h_inch = self.fig.get_figheight()
+## print 'fig_h_inch',fig_h_inch
+ lbrt_inch = (0,0,fig_w_inch,fig_h_inch) # bounding box within figure
+
+ req_w_inch, req_h_inch = self.sizer._layout(lbrt_inch,fig_w_inch,fig_h_inch)
+## print 'ntry %d: req_w_inch, req_h_inch'%(ntry,),repr(req_w_inch), repr(req_h_inch)
+ if (req_w_inch is not None) or (req_h_inch is not None):
+ raise RuntimeError('failed to layout')
+ 
Modified: trunk/toolkits/mplsizer/setup.py
===================================================================
--- trunk/toolkits/mplsizer/setup.py	2008年01月10日 13:33:03 UTC (rev 4844)
+++ trunk/toolkits/mplsizer/setup.py	2008年01月10日 13:38:31 UTC (rev 4845)
@@ -16,6 +16,6 @@
 version='0.1',
 license='MIT',
 url='http://matplotlib.sourceforge.net/',
- packages=['matplotlib.toolkits.mplsizer'],
- namespace_packages = ['matplotlib.toolkits'],
+ packages=['mpl_toolkits','mpl_toolkits.mplsizer'],
+ namespace_packages = ['mpl_toolkits'],
 )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2008年01月10日 13:33:11
Revision: 4844
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4844&view=rev
Author: mdboom
Date: 2008年01月10日 05:33:03 -0800 (2008年1月10日)
Log Message:
-----------
Merged revisions 4826-4843 via svnmerge from 
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_91_maint
........
 r4826 | mdboom | 2008年01月08日 17:13:08 -0500 (2008年1月08日) | 1 line
 
 Undoing last commit. Testing was successful.
........
 r4841 | mdboom | 2008年01月10日 08:28:01 -0500 (2008年1月10日) | 1 line
 
 Fix offset labels (so the times symbol is displayed correctly)
........
Modified Paths:
--------------
 trunk/matplotlib/CHANGELOG
 trunk/matplotlib/lib/matplotlib/ticker.py
Property Changed:
----------------
 trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Name: svnmerge-integrated
 - /branches/v0_91_maint:1-4816
 + /branches/v0_91_maint:1-4843
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG	2008年01月10日 13:29:16 UTC (rev 4843)
+++ trunk/matplotlib/CHANGELOG	2008年01月10日 13:33:03 UTC (rev 4844)
@@ -1,7 +1,7 @@
 2008年01月10日 Moved toolkits to mpl_toolkits, made mpl_toolkits
 a namespace package - JSWHIT
 
-2008年01月10日 Use setup.cfg to set the default parameters (tkagg, 
+2008年01月10日 Use setup.cfg to set the default parameters (tkagg,
 numpy) when building windows installers - DSD
 
 ===============================================================
Modified: trunk/matplotlib/lib/matplotlib/ticker.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/ticker.py	2008年01月10日 13:29:16 UTC (rev 4843)
+++ trunk/matplotlib/lib/matplotlib/ticker.py	2008年01月10日 13:33:03 UTC (rev 4844)
@@ -327,12 +327,16 @@
 if self.offset > 0: offsetStr = '+' + offsetStr
 if self.orderOfMagnitude:
 if self._usetex or self._useMathText:
- sciNotStr = r'\times'+self.format_data(10**self.orderOfMagnitude)
+ sciNotStr = self.format_data(10**self.orderOfMagnitude)
 else:
- sciNotStr = u'\xd7'+'1e%d'% self.orderOfMagnitude
+ sciNotStr = '1e%d'% self.orderOfMagnitude
 if self._useMathText:
- return ''.join(('$\mathdefault{',sciNotStr,offsetStr,'}$'))
+ if sciNotStr != '':
+ sciNotStr = r'\times\mathdefault{%s}' % sciNotStr
+ return ''.join(('$',sciNotStr,r'\mathdefault{',offsetStr,'}$'))
 elif self._usetex:
+ if sciNotStr != '':
+ sciNotStr = u'\xd7%s' % sciNotStr
 return ''.join(('$',sciNotStr,offsetStr,'$'))
 else:
 return ''.join((sciNotStr,offsetStr))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <js...@us...> - 2008年01月10日 13:29:29
Revision: 4843
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4843&view=rev
Author: jswhit
Date: 2008年01月10日 05:29:16 -0800 (2008年1月10日)
Log Message:
-----------
change docstring to reflect move to mpl_toolkits
Modified Paths:
--------------
 trunk/matplotlib/lib/mpl_toolkits/exceltools.py
 trunk/matplotlib/lib/mpl_toolkits/gtktools.py
Modified: trunk/matplotlib/lib/mpl_toolkits/exceltools.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/exceltools.py	2008年01月10日 13:29:16 UTC (rev 4842)
+++ trunk/matplotlib/lib/mpl_toolkits/exceltools.py	2008年01月10日 13:29:16 UTC (rev 4843)
@@ -4,7 +4,7 @@
 Example usage:
 
 import matplotlib.mlab as mlab
- import matplotlib.toolkits.exceltools as exceltools
+ import mpl_toolkits.exceltools as exceltools
 
 r = mlab.csv2rec('somefile.csv', checkrows=0)
 
Modified: trunk/matplotlib/lib/mpl_toolkits/gtktools.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/gtktools.py	2008年01月10日 13:29:16 UTC (rev 4842)
+++ trunk/matplotlib/lib/mpl_toolkits/gtktools.py	2008年01月10日 13:29:16 UTC (rev 4843)
@@ -7,7 +7,7 @@
 Example usage
 
 import matplotlib.mlab as mlab
- import matplotlib.toolkits.gtktools as gtktools
+ import mpl_toolkits.gtktools as gtktools
 
 r = mlab.csv2rec('somefile.csv', checkrows=0)
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

Showing results of 120

<< < 1 2 3 4 5 > >> (Page 3 of 5)
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /