tessellate_plot
ΒΆ
This script plots the tessellated sphere into the 2-D map
To run this script, the Matplotlib Basemap module is needed to be installed.
conda install basemap # Recommended
or
pip install https://github.com/matplotlib/basemap/archive/v1.1.0.tar.gz
#!/usr/bin/env python
''' This script plots the tessellated sphere into the 2-D map
To run this script, the Matplotlib Basemap module is needed to be installed.
::
conda install basemap # Recommended
or
::
pip install https://github.com/matplotlib/basemap/archive/v1.1.0.tar.gz
'''
import sys
import time
import matplotlib
matplotlib.use('Agg')
import logging
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
from pylab import *
import numpy as np
import matplotlib.patches as mpatches
from irfpy.util.tessellatedsphere import TessellatedSphere
def v3ang(v):
r = math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
t = math.acos(v[2] / r) * 180 / math.pi
p = math.atan2(v[1], v[0]) * 180 / math.pi
return (r, t, p)
def isnorm(x, y, z):
return (abs(x-y) <=180 and abs(y-z) < 180. and abs(z-x)< 180.)
def normalize_phi(p0, p1, p2):
''' Normalize if either or more p0=p1 p1=p2 p2=p0 is more than 180 deg.
'''
if isnorm(p0, p1, p2):
return p0, p1, p2
else:
p0m = p0 - 360
p0p = p0 + 360
p1m = p1 - 360
p1p = p1 + 360
p2m = p2 - 360
p2p = p2 + 360
if isnorm(p0m, p1, p2):
return (p0m, p1, p2)
elif isnorm(p0p, p1, p2):
return (p0p, p1, p2)
elif isnorm(p0, p1m, p2):
return (p0, p1m, p2)
elif isnorm(p0, p1p, p2):
return (p0, p1p, p2)
elif isnorm(p0, p1, p2m):
return (p0, p1, p2m)
elif isnorm(p0, p1, p2p):
return (p0, p1, p2p)
raise RuntimeError('Normalization failed.')
def plot_tesselation(ndim=0, filename=None):
logging.info('Given ndim=%d' % ndim)
tt0 = time.time()
tris = TessellatedSphere(ndim=ndim).getTriangles()
logging.info('Tessellation done. %f sec' % (time.time() - tt0))
logging.info('Number of triangles is %d' % len(tris))
fig = figure()
from mpl_toolkits.basemap import Basemap
map = Basemap(projection='moll', lon_0=0.01, resolution = 'l', area_thresh=1000.)
map.drawmapboundary()
triarea = []
for tri in tris:
triarea.append(tri.getArea())
v0, v1, v2 = tri.getVertices()
r0, t0, p0 = v3ang(v0) # r is radius, t is theta, p is phi
r1, t1, p1 = v3ang(v1)
r2, t2, p2 = v3ang(v2)
if abs(r0-1) > 1e-5 or abs(r1-1) > 1e-5 or abs(r2-1) > 1e-5:
raise RuntimeError('Failed! Not normalized! %s' % tri)
t0 = 90 - t0 # theta to be latitude.
t1 = 90 - t1
t2 = 90 - t2
lats = [t0, t1, t2, t0]
lons = [p0, p1, p2, p0]
if not isnorm(p0, p1, p2):
continue
try:
p0, p1, p2 = normalize_phi(p0, p1, p2)
except RuntimeError as e:
logging.warn('Failed the normalization in phi %s' % e)
continue
x, y = list(map(lons, lats))
map.plot(x, y, '-')
triarea = np.array(triarea)
print('Total area = %f' % sum(triarea))
print('Average area = %f' % average(triarea))
print('Total area of sphere = %f' % (4 * np.pi))
print('Average area of sphere with iso-area element = %f' % (4*np.pi / len(triarea)))
if filename != None:
fig.savefig(filename)
else:
plt.show()
if __name__ == '__main__':
if len(sys.argv) < 2:
print("USAGE: %s ndim [figname.png]", file=sys.stderr)
sys.exit(-1)
if len(sys.argv) == 2:
filename = None
else:
filename = sys.argv[2]
plot_tesselation(ndim=int(sys.argv[1]), filename=filename)