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

Skip to content

Commit 9602112

Browse files
committed
Improve speed
1 parent a2ddfc0 commit 9602112

File tree

1 file changed

+47
-37
lines changed
  • lib/matplotlib/projections

1 file changed

+47
-37
lines changed

lib/matplotlib/projections/geo.py

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import math
12
import numpy as np
23

34
from matplotlib import _api, rcParams
@@ -52,8 +53,8 @@ def cla(self):
5253

5354
self.grid(rcParams['axes.grid'])
5455

55-
Axes.set_xlim(self, -np.pi, np.pi)
56-
Axes.set_ylim(self, -np.pi / 2.0, np.pi / 2.0)
56+
Axes.set_xlim(self, -math.pi, math.pi)
57+
Axes.set_ylim(self, -math.pi / 2.0, math.pi / 2.0)
5758

5859
def _set_lim_and_transforms(self):
5960
# A (possibly non-linear) projection on the (already scaled) data
@@ -88,7 +89,7 @@ def _set_lim_and_transforms(self):
8889
Affine2D().translate(0, -4)
8990

9091
# This is the transform for latitude ticks.
91-
yaxis_stretch = Affine2D().scale(np.pi * 2, 1).translate(-np.pi, 0)
92+
yaxis_stretch = Affine2D().scale(math.pi * 2, 1).translate(-math.pi, 0)
9293
yaxis_space = Affine2D().scale(1, 1.1)
9394
self._yaxis_transform = \
9495
yaxis_stretch + \
@@ -108,8 +109,8 @@ def _set_lim_and_transforms(self):
108109

109110
def _get_affine_transform(self):
110111
transform = self._get_core_transform(1)
111-
xscale, _ = transform.transform((np.pi, 0))
112-
_, yscale = transform.transform((0, np.pi/2))
112+
xscale, _ = transform.transform((math.pi, 0))
113+
_, yscale = transform.transform((0, math.pi / 2))
113114
return Affine2D() \
114115
.scale(0.5 / xscale, 0.5 / yscale) \
115116
.translate(0.5, 0.5)
@@ -261,14 +262,17 @@ def transform_non_affine(self, ll):
261262
longitude, latitude = ll.T
262263

263264
# Pre-compute some values
264-
half_long = longitude / 2.0
265-
cos_latitude = np.cos(latitude)
265+
half_long = longitude / 2
266+
cos_half = np.cos(half_long)
267+
sin_half = np.cos(half_long)
268+
cos_latitude = cos_half*cos_half - sin_half*sin_half
266269

267-
alpha = np.arccos(cos_latitude * np.cos(half_long))
268-
sinc_alpha = np.sinc(alpha / np.pi) # np.sinc is sin(pi*x)/(pi*x).
270+
alpha = np.arccos(cos_latitude * cos_half)
271+
# np.sinc is sin(pi*x)/(pi*x).
272+
sinc_alpha = np.sinc(alpha / math.pi)
269273

270-
x = (cos_latitude * np.sin(half_long)) / sinc_alpha
271-
y = np.sin(latitude) / sinc_alpha
274+
x = (cos_latitude * sin_half) / sinc_alpha
275+
y = 2.0 * sin_half * cos_half / sinc_alpha # sin(lat) / sinc_alpha
272276
return np.column_stack([x, y])
273277

274278
def inverted(self):
@@ -287,7 +291,7 @@ def inverted(self):
287291
return AitoffAxes.AitoffTransform(self._resolution)
288292

289293
def __init__(self, *args, **kwargs):
290-
self._longitude_cap = np.pi / 2.0
294+
self._longitude_cap = math.pi / 2
291295
super().__init__(*args, **kwargs)
292296
self.set_aspect(0.5, adjustable='box', anchor='C')
293297
self.cla()
@@ -305,12 +309,14 @@ class HammerTransform(_GeoTransform):
305309
def transform_non_affine(self, ll):
306310
# docstring inherited
307311
longitude, latitude = ll.T
308-
half_long = longitude / 2.0
309-
cos_latitude = np.cos(latitude)
310-
sqrt2 = np.sqrt(2.0)
311-
alpha = np.sqrt(1.0 + cos_latitude * np.cos(half_long))
312-
x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
313-
y = (sqrt2 * np.sin(latitude)) / alpha
312+
half_long = longitude / 2
313+
cos_half = np.cos(half_long)
314+
sin_half = np.cos(half_long)
315+
cos_latitude = cos_half*cos_half - sin_half*sin_half
316+
sqrt8 = 8 ** (1/2)
317+
alpha = np.sqrt(1.0 + cos_latitude * cos_half)
318+
x = (sqrt8 * cos_latitude * sin_half) / alpha
319+
y = (sqrt8 * cos_half * sin_half) / alpha # sin(lat)
314320
return np.column_stack([x, y])
315321

316322
def inverted(self):
@@ -324,15 +330,15 @@ def transform_non_affine(self, xy):
324330
x, y = xy.T
325331
z = np.sqrt(1 - (x / 4) ** 2 - (y / 2) ** 2)
326332
longitude = 2 * np.arctan((z * x) / (2 * (2 * z ** 2 - 1)))
327-
latitude = np.arcsin(y*z)
333+
latitude = np.arcsin(y * z)
328334
return np.column_stack([longitude, latitude])
329335

330336
def inverted(self):
331337
# docstring inherited
332338
return HammerAxes.HammerTransform(self._resolution)
333339

334340
def __init__(self, *args, **kwargs):
335-
self._longitude_cap = np.pi / 2.0
341+
self._longitude_cap = math.pi / 2
336342
super().__init__(*args, **kwargs)
337343
self.set_aspect(0.5, adjustable='box', anchor='C')
338344
self.cla()
@@ -351,18 +357,18 @@ def transform_non_affine(self, ll):
351357
# docstring inherited
352358
def d(theta):
353359
delta = (-(theta + np.sin(theta) - pi_sin_l)
354-
/ (1 + np.cos(theta)))
360+
/ (1.0 + np.cos(theta)))
355361
return delta, np.abs(delta) > 0.001
356362

357363
longitude, latitude = ll.T
358-
359-
clat = np.pi/2 - np.abs(latitude)
364+
pi_half = math.pi / 2
365+
clat = pi_half - np.abs(latitude)
360366
ihigh = clat < 0.087 # within 5 degrees of the poles
361367
ilow = ~ihigh
362368
aux = np.empty(latitude.shape, dtype=float)
363369

364370
if ilow.any(): # Newton-Raphson iteration
365-
pi_sin_l = np.pi * np.sin(latitude[ilow])
371+
pi_sin_l = math.pi * np.sin(latitude[ilow])
366372
theta = 2.0 * latitude[ilow]
367373
delta, large_delta = d(theta)
368374
while np.any(large_delta):
@@ -372,12 +378,13 @@ def d(theta):
372378

373379
if ihigh.any(): # Taylor series-based approx. solution
374380
e = clat[ihigh]
375-
d = 0.5 * (3 * np.pi * e**2) ** (1.0/3)
376-
aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh])
381+
d = np.cbrt(3.0 * math.pi * e ** 2) / 2
382+
aux[ihigh] = (pi_half - d) * np.sign(latitude[ihigh])
377383

378384
xy = np.empty(ll.shape, dtype=float)
379-
xy[:, 0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux)
380-
xy[:, 1] = np.sqrt(2.0) * np.sin(aux)
385+
sqrt2 = 2 ** (1 / 2)
386+
xy[:, 0] = (sqrt2 / pi_half) * longitude * np.cos(aux)
387+
xy[:, 1] = sqrt2 * np.sin(aux)
381388

382389
return xy
383390

@@ -392,17 +399,18 @@ def transform_non_affine(self, xy):
392399
x, y = xy.T
393400
# from Equations (7, 8) of
394401
# https://mathworld.wolfram.com/MollweideProjection.html
395-
theta = np.arcsin(y / np.sqrt(2))
396-
longitude = (np.pi / (2 * np.sqrt(2))) * x / np.cos(theta)
397-
latitude = np.arcsin((2 * theta + np.sin(2 * theta)) / np.pi)
402+
sqrt2 = 2 ** (1 / 2)
403+
theta = np.arcsin(y / sqrt2)
404+
longitude = (math.pi / (2.0 * sqrt2)) * x / np.cos(theta)
405+
latitude = np.arcsin((2.0 * theta + np.sin(2.0 * theta)) / math.pi)
398406
return np.column_stack([longitude, latitude])
399407

400408
def inverted(self):
401409
# docstring inherited
402410
return MollweideAxes.MollweideTransform(self._resolution)
403411

404412
def __init__(self, *args, **kwargs):
405-
self._longitude_cap = np.pi / 2.0
413+
self._longitude_cap = math.pi / 2.0
406414
super().__init__(*args, **kwargs)
407415
self.set_aspect(0.5, adjustable='box', anchor='C')
408416
self.cla()
@@ -434,15 +442,17 @@ def transform_non_affine(self, ll):
434442
clat = self._center_latitude
435443
cos_lat = np.cos(latitude)
436444
sin_lat = np.sin(latitude)
445+
cos_clat = np.cos(clat)
446+
sin_clat = np.sin(clat)
437447
diff_long = longitude - clong
438448
cos_diff_long = np.cos(diff_long)
439449

440450
inner_k = np.maximum( # Prevent divide-by-zero problems
441-
1 + np.sin(clat)*sin_lat + np.cos(clat)*cos_lat*cos_diff_long,
451+
1.0 + sin_clat*sin_lat + cos_clat*cos_lat*cos_diff_long,
442452
1e-15)
443-
k = np.sqrt(2 / inner_k)
453+
k = np.sqrt(2.0 / inner_k)
444454
x = k * cos_lat*np.sin(diff_long)
445-
y = k * (np.cos(clat)*sin_lat - np.sin(clat)*cos_lat*cos_diff_long)
455+
y = k * (cos_clat*sin_lat - sin_clat*cos_lat*cos_diff_long)
446456

447457
return np.column_stack([x, y])
448458

@@ -466,7 +476,7 @@ def transform_non_affine(self, xy):
466476
clong = self._center_longitude
467477
clat = self._center_latitude
468478
p = np.maximum(np.hypot(x, y), 1e-9)
469-
c = 2 * np.arcsin(0.5 * p)
479+
c = 2.0 * np.arcsin(0.5 * p)
470480
sin_c = np.sin(c)
471481
cos_c = np.cos(c)
472482

@@ -485,7 +495,7 @@ def inverted(self):
485495
self._resolution)
486496

487497
def __init__(self, *args, center_longitude=0, center_latitude=0, **kwargs):
488-
self._longitude_cap = np.pi / 2
498+
self._longitude_cap = math.pi / 2
489499
self._center_longitude = center_longitude
490500
self._center_latitude = center_latitude
491501
super().__init__(*args, **kwargs)

0 commit comments

Comments
 (0)