Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7dda386

Browse files
committed
Merge pull request matplotlib#505 from efiring/geo_divide_zero
Geo divide zero
2 parents e933ef6 + 533e5fb commit 7dda386

File tree

1 file changed

+30
-18
lines changed
  • lib/matplotlib/projections

1 file changed

+30
-18
lines changed

lib/matplotlib/projections/geo.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,16 @@ def transform(self, ll):
271271
cos_latitude = np.cos(latitude)
272272

273273
alpha = np.arccos(cos_latitude * np.cos(half_long))
274-
# Mask this array, or we'll get divide-by-zero errors
274+
# Mask this array or we'll get divide-by-zero errors
275275
alpha = ma.masked_where(alpha == 0.0, alpha)
276+
# The numerators also need to be masked so that masked
277+
# division will be invoked.
276278
# We want unnormalized sinc. numpy.sinc gives us normalized
277279
sinc_alpha = ma.sin(alpha) / alpha
278280

279-
x = (cos_latitude * np.sin(half_long)) / sinc_alpha
280-
y = (np.sin(latitude) / sinc_alpha)
281-
x.set_fill_value(0.0)
282-
y.set_fill_value(0.0)
283-
return np.concatenate((x.filled(), y.filled()), 1)
281+
x = (cos_latitude * ma.sin(half_long)) / sinc_alpha
282+
y = (ma.sin(latitude) / sinc_alpha)
283+
return np.concatenate((x.filled(0), y.filled(0)), 1)
284284
transform.__doc__ = Transform.transform.__doc__
285285

286286
transform_non_affine = transform
@@ -436,23 +436,35 @@ def __init__(self, resolution):
436436
def transform(self, ll):
437437
def d(theta):
438438
delta = -(theta + np.sin(theta) - pi_sin_l) / (1 + np.cos(theta))
439-
return delta, abs(delta) > 0.001
439+
return delta, np.abs(delta) > 0.001
440440

441-
longitude = ll[:, 0:1]
442-
latitude = ll[:, 1:2]
441+
longitude = ll[:, 0]
442+
latitude = ll[:, 1]
443+
444+
clat = np.pi/2 - np.abs(latitude)
445+
ihigh = clat < 0.087 # within 5 degrees of the poles
446+
ilow = ~ihigh
447+
aux = np.empty(latitude.shape, dtype=np.float)
443448

444-
pi_sin_l = np.pi * np.sin(latitude)
445-
theta = 2.0 * latitude
446-
delta, large_delta = d(theta)
447-
while np.any(large_delta):
448-
theta += np.where(large_delta, delta, 0)
449+
if ilow.any(): # Newton-Raphson iteration
450+
pi_sin_l = np.pi * np.sin(latitude[ilow])
451+
theta = 2.0 * latitude[ilow]
449452
delta, large_delta = d(theta)
450-
aux = theta / 2
453+
while np.any(large_delta):
454+
theta[large_delta] += delta[large_delta]
455+
delta, large_delta = d(theta)
456+
aux[ilow] = theta / 2
451457

452-
x = (2.0 * np.sqrt(2.0) * longitude * np.cos(aux)) / np.pi
453-
y = (np.sqrt(2.0) * np.sin(aux))
458+
if ihigh.any(): # Taylor series-based approx. solution
459+
e = clat[ihigh]
460+
d = 0.5 * (3 * np.pi * e**2) ** (1.0/3)
461+
aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh])
454462

455-
return np.concatenate((x, y), 1)
463+
xy = np.empty(ll.shape, dtype=np.float)
464+
xy[:,0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux)
465+
xy[:,1] = np.sqrt(2.0) * np.sin(aux)
466+
467+
return xy
456468
transform.__doc__ = Transform.transform.__doc__
457469

458470
transform_non_affine = transform

0 commit comments

Comments
 (0)