293293 + ', ' .join (map (repr , PROJS_MISSING ))
294294 + ' . Please consider updating cartopy.'
295295 )
296+ PROJS_TABLE = (
297+ 'The known cartopy projection classes are:\n '
298+ + '\n ' .join (
299+ ' ' + key + ' ' * (max (map (len , PROJS )) - len (key ) + 10 ) + cls .__name__
300+ for key , cls in PROJS .items ()
301+ )
302+ )
296303
297304# Geographic feature properties
298305FEATURES_CARTOPY = { # positional arguments passed to NaturalEarthFeature
@@ -1393,6 +1400,7 @@ def Proj(name, basemap=None, **kwargs):
13931400 basemap = _not_none (basemap , rc ['basemap' ])
13941401 is_crs = Projection is not object and isinstance (name , Projection )
13951402 is_basemap = Basemap is not object and isinstance (name , Basemap )
1403+ include_axes = kwargs .pop ('include_axes' , False ) # for error message
13961404 if is_crs or is_basemap :
13971405 proj = name
13981406 package = 'cartopy' if is_crs else 'basemap'
@@ -1429,18 +1437,18 @@ def Proj(name, basemap=None, **kwargs):
14291437 if 'latlim' in kwargs :
14301438 kwargs ['llcrnrlat' ], kwargs ['urcrnrlat' ] = kwargs .pop ('latlim' )
14311439 name = PROJ_ALIASES .get (name , name )
1432- kwproj = PROJ_DEFAULTS .get (name , {}).copy ()
1433- kwproj .update (kwargs )
1434- kwproj .setdefault ('fix_aspect' , True )
1435- if kwproj .get ('lon_0' , 0 ) > 0 :
1436- kwproj ['lon_0' ] -= 360
1440+ proj_kw = PROJ_DEFAULTS .get (name , {}).copy ()
1441+ proj_kw .update (kwargs )
1442+ proj_kw .setdefault ('fix_aspect' , True )
1443+ if proj_kw .get ('lon_0' , 0 ) > 0 :
1444+ proj_kw ['lon_0' ] -= 360
14371445 if name [:2 ] in ('np' , 'sp' ):
1438- kwproj .setdefault ('round' , True )
1446+ proj_kw .setdefault ('round' , True )
14391447 if name == 'geos' :
1440- kwproj .setdefault ('rsphere' , (6378137.00 , 6356752.3142 ))
1448+ proj_kw .setdefault ('rsphere' , (6378137.00 , 6356752.3142 ))
14411449 reso = _not_none (
1442- reso = kwproj .pop ('reso' , None ),
1443- resolution = kwproj .pop ('resolution' , None ),
1450+ reso = proj_kw .pop ('reso' , None ),
1451+ resolution = proj_kw .pop ('resolution' , None ),
14441452 default = rc ['reso' ]
14451453 )
14461454 if reso in RESOS_BASEMAP :
@@ -1451,43 +1459,45 @@ def Proj(name, basemap=None, **kwargs):
14511459 + ', ' .join (map (repr , RESOS_BASEMAP ))
14521460 + '.'
14531461 )
1454- kwproj .update ({'resolution' : reso , 'projection' : name })
1462+ proj_kw .update ({'resolution' : reso , 'projection' : name })
14551463 try :
1456- proj = mbasemap .Basemap (** kwproj ) # will raise helpful warning
1464+ proj = mbasemap .Basemap (** proj_kw ) # will raise helpful warning
14571465 except ValueError as err :
1458- msg = str (err )
1459- msg = msg .replace ('projection' , 'basemap projection' )
1460- raise ValueError (msg ) from None
1466+ message = str (err )
1467+ message = message .strip ()
1468+ message = message .replace ('projection' , 'basemap projection' )
1469+ message = message .replace ('supported' , 'known' )
1470+ if include_axes :
1471+ from . import axes as paxes # avoid circular imports
1472+ message = message .replace ('projection.' , 'projection or axes subclass.' )
1473+ message += '\n The known axes subclasses are:\n ' + paxes ._cls_table
1474+ raise ValueError (message ) from None
14611475
14621476 # Cartopy
14631477 # NOTE: Error message matches basemap invalid projection message
14641478 else :
14651479 import cartopy .crs as ccrs # noqa: F401
14661480 package = 'cartopy'
1467- kwproj = {
1468- PROJ_ALIASES_KW .get (key , key ): value
1469- for key , value in kwargs .items ()
1470- }
1471- if name in PROJS :
1481+ proj_kw = {PROJ_ALIASES_KW .get (key , key ): value for key , value in kwargs .items ()} # noqa: E501
1482+ if 'boundinglat' in proj_kw :
1483+ raise ValueError ('"boundinglat" must be passed to the ax.format() command for cartopy axes.' ) # noqa: E501
1484+ try :
14721485 crs = PROJS [name ]
1473- else :
1474- maxlen = max (map (len , PROJS ))
1475- raise ValueError (
1476- f'{ name !r} is an unknown cartopy projection class.\n '
1477- 'The known cartopy projection classes are:\n '
1478- + '\n ' .join (
1479- ' ' + key + ' ' * (maxlen - len (key ) + 6 ) + crs .__name__
1480- for key , crs in PROJS .items ()
1481- )
1486+ except KeyError :
1487+ message = f'{ name !r} is an unknown cartopy projection class.\n '
1488+ message += 'The known cartopy projection classes are:\n '
1489+ message += '\n ' .join (
1490+ ' ' + key + ' ' * (max (map (len , PROJS )) - len (key ) + 10 ) + cls .__name__
1491+ for key , cls in PROJS .items ()
14821492 )
1493+ if include_axes :
1494+ from . import axes as paxes # avoid circular imports
1495+ message = message .replace ('projection.' , 'projection or axes subclass.' )
1496+ message += '\n The known axes subclasses are:\n ' + paxes ._cls_table
1497+ raise ValueError (message ) from None
14831498 if name == 'geos' : # fix common mistake
1484- kwproj .pop ('central_latitude' , None )
1485- if 'boundinglat' in kwproj :
1486- raise ValueError (
1487- '"boundinglat" must be passed to the ax.format() command '
1488- 'for cartopy axes.'
1489- )
1490- proj = crs (** kwproj )
1499+ proj_kw .pop ('central_latitude' , None )
1500+ proj = crs (** proj_kw )
14911501
14921502 proj ._proj_package = package
14931503 return proj
0 commit comments