In [1]:
# --+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
# I need the time axis labels in italian,
# it's usually better to do this at first
from locale import setlocale, LC_TIME ; setlocale(LC_TIME, 'italian')
# astro's computations will be done using ephem
import ephem as x
# not every important city is includes in ephem city database
from ephem.cities import _city_data, city
_city_data.update({
'Monza':('45.577721','9.300896',160.0),
'Cabiate':('45.679350','9.165230',255.0),
'Meda':('45.661400','9.155734',223.0),
})
# we need to fiddle a bit with the labeling of the time axis
from matplotlib.ticker import MultipleLocator
from matplotlib.dates import MonthLocator, DateFormatter
# the preferred format for inline plots, alternatives are 'png' and 'svg'
%config InlineBackend.figure_format = 'png'
# the time unit is a day, here we define day, hour, etc
d, h, m, s = 1.0, 1.0/24, 1.0/24/60, 1.0/24/60/60
In [2]:
my_city = 'Cabiate'
me = city(my_city)
me2 = city(my_city)
Finally, we need a moon.
In [3]:
moon = x.Moon()
For a given date, i.e., moment in time,
In [4]:
def velocity(date):
me2.date=date-0.1*s
moon.compute(me2) ; alt0 = moon.alt
me2.date=date+0.1*s
moon.compute(me2) ; alt1 = moon.alt
return alt1/0.2/s - alt0/0.2/s
Given that the maximum heigth is reached when the moon is close to transit, after a bit of initialization,
.datetime() call)me.date = me.date + d),break otherwise repeat the cycle.The container (a Python list) is converted to an array, so that we can index it with a [i,j] notation.
In [5]:
me.date = "2013/01/01 00:00:01"
next_year = x.date("2014/01/01 00:00:01")
container = []
while 1:
moon.compute(me)
mtt = moon.transit_time
if mtt:
time = x.Date(x.newton(velocity,mtt-0.2*h,mtt+0.2*h))
container.append( (time.datetime(), 180*moon.alt/x.pi))
me.date = me.date + d
if me.date>next_year: break
container=array(container)
In [6]:
date = x.Date('2013/01/01') ; moons = []
while 1:
date = x.next_last_quarter_moon(date)
if date>next_year: break
moons.append((date.datetime(),3))
date = x.next_new_moon(date)
if date>next_year: break
moons.append((date.datetime(),0))
date = x.next_first_quarter_moon(date)
if date>next_year: break
moons.append((date.datetime(),1))
date = x.next_full_moon(date)
if date>next_year: break
moons.append((date.datetime(),2))
moons = array(moons)
We want to superimpose the envelope curve with different symbols for each phase of the moon. For now
In [7]:
i = 0 ; delendo = []
for m in moons:
tm, phase = m
while container[i,0]<tm:
i = i+1
t0, alt0 = container[i-1,:]; t0 = x.Date(t0)
t1, alt1 = container[ i ,:]; t1 = x.Date(t1)
altm = alt0 + (x.Date(tm)-t0)*(alt1-alt0)/(t1-t0)
delendo.append((tm,altm,phase))
moons = array(delendo) ; del delendo
When applying a test on some elements of an array, we obtain an array of boolean values (i.e., true vs false) of the same length of the tested sequence.
In [8]:
new = moons[:,2] == 0
full = moons[:,2] == 2
qrtr = moons[:,2] %2 == 1
The important fact is that we can use these boolean arrays to index an array... e.g.,
we print the new array and then we use it to print the first 3 new moons.
In [9]:
print new
print moons[new][:3]
Show our current results.
In [10]:
# size of the figure in inches
figsize(10,2.5)
# in this figure there is one x-y graph
subplot(111)
# save the current figure and the current x-y graph
f = gcf() ; ax = gca() ; close()
# the margins of the x-y are fractions of the figure,
# having increased the figsize we narrow the margins
f.subplots_adjust(left=0.06, right=0.96, bottom=0.08, top=0.92)
# adjust the limits of the axes
ax.axis(ymin=0, ymax=90,
xmin=x.Date("2013-01-01").datetime(),
xmax=x.Date("2014/01/01").datetime())
ax.xaxis.set_minor_locator(MultipleLocator(1))
ax.xaxis.set_major_locator(MonthLocator(bymonth=range(13)))
ax.xaxis.set_major_formatter(DateFormatter("%b %Y"))
ax.set_axisbelow(True)
ax.grid(c='#B0B0B0', linestyle='-', linewidth=0.1)
show_all = True
if show_all: f.show()
In [12]:
ax.tick_params(axis='x', which='minor', length=4, width=0.2, color='#909090')
[tik.set_size('xx-small') for tik in ax.get_xticklabels()]
[tik.set_size('xx-small') for tik in ax.get_yticklabels()]
[tik.set_rotation(90.0) for tik in ax.get_yticklabels()]
if show_all: f.show()
In [13]:
# the title and a label for the ordinates
ax.set_title(
'La Luna vista da %s (lat = %s, lon = %s, altezza = %5.1f mslm).'%
(me.name,x.degrees(me.lat),x.degrees(me.lon), me.elevation),
size='small')
ax.set_ylabel('Inviluppo dell\'altezza lunare, in gradi', size='x-small')
if show_all: f.show()
In [14]:
# plot the envelope of moon altitudes two times, first with a continuous line
# & later with the smallest of the available dot typess
ax.plot(container[:,0],container[:,1],'-',color='lightgray', linewidth=0.3)
ax.plot(container[:,0],container[:,1],',',color="black")
if show_all: f.show()
In [15]:
# plot the postion of a) new moons, b) full moons and c) both first quarter and last quarter
# of the moon
# first time, with circles of different colors
ax.plot(moons[new, 0],moons[new, 1],'o',markersize=5, color='#202090', alpha=0.75)
ax.plot(moons[full,0],moons[full,1],'o',markersize=5, color="#ffff00", alpha=0.75)
ax.plot(moons[qrtr,0],moons[qrtr,1],'o',markersize=5, color="lightgray", alpha=0.75)
# second time, with small black dots
ax.plot(moons[:,0],moons[:,1],'.k',markersize=2)
if show_all: f.show()
In [16]:
xpos = x.Date('2013/07/1').datetime()
ax.annotate('''I cerchi sul grafico indicano la posizione delle lune piene (cerchi gialli),
delle lune nuove (cerchi blu) e dei quarti di luna (cerchi grigi).''', (xpos,12),
size='x-small', ha='center', va='center',
bbox=dict(boxstyle="round,pad=0.5",fc='white',ec='lightgray'))
if show_all: f.show()
In [17]:
ax.annotate('',(moons[-2,0],moons[-2,1]), xytext=(10./12.,0.85), textcoords='axes fraction', ha='right',
arrowprops=dict(width=0.1,headwidth=4.0,shrink=0.15,color='gray'))
ax.annotate(u'''Le due ultime lune piene di autunno saliranno molto alte nel
cielo e le tre notti della luna piena saranno molto luminose.''',
(moons[-6,0],moons[-6,1]), xytext=(10./12.,0.85), textcoords='axes fraction', ha='right',
name='sans', size='xx-small', color='#404090',
arrowprops=dict(width=0.1,headwidth=4.0,shrink=0.25,color='gray',),
bbox={"boxstyle":"round,pad=0.5","fc":"#feffff","alpha":0.9,'ec':'#b0b0ff'})
f.show()
In [18]:
f.savefig('Moon_at_%s.pdf'%(me.name,))
In [18]:
In [18]:
In [ ]: