Ejemplo n.º 1
0
def plot_sky_map(objs, date=None, new_window=False, airmass_high=None,
      tel_alt=90, tel_az=45, imsize=5, crop=90):
   '''Plots the objects for a given night for the given objects (expected to
   be of type Objects).  Returns two strings:  the first is the binary
   PNG file that is the graph, the second is the <map> HTML that will be used
   to make the points in the graph "hot spots"'''
   if date is None:
      date = ephem.now()
   else:
      date = ephem.Date(date)

   MWO = genMWO(date)

   # Setup the graph
   fig = Figure((imsize,imsize), frameon=False, 
         subplotpars=SubplotParams(left=0.00,right=1.0, bottom=0.0, top=1.))
   fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
   canvas = FigureCanvasAgg(fig)
   ax = fig.add_subplot(111)
   lines = []
   names = []
   ids = []
   maxrho = 0
   
   for obj in objs:
      obj.epoch = date
      theta = obj.azimuth()*pi/180
      rho = 90 - obj.altitude()
      maxrho = max(rho, maxrho)
      x = rho*sin(theta)
      y = rho*cos(theta)
      tobj = ax.text(x, y, osymb(obj.objtype), va='center', ha='center')
            
      lines.append(tobj)
      names.append(obj.name + "*"*obj.rating)
      ids.append(obj.pk)
   # Telescope pos
   theta = -(float(tel_az)*pi/180-pi/2)
   rho = 90 - float(tel_alt)
   ax.plot([rho*cos(theta)],[rho*sin(theta)], "o", ms=15, mfc='none', mec='red')
   ax.plot([rho*cos(theta)],[rho*sin(theta)], "o", ms=10, mfc='none', mec='red')

   # draw grid lines:
   for rho in arange(15,maxrho+16,15):
      c = Circle((0,0), radius=rho, ec='0.5', fc='none', zorder=0)
      ax.add_artist(c)
   for theta in arange(0,pi,pi/6):
      ax.plot([rho*cos(theta), rho*cos(theta+pi)],
              [rho*sin(theta),rho*sin(theta+pi)], '-', color='0.5', zorder=0)

   clipper=c
   ax.axis('off')
   ax.set_xlim(-100,100)
   ax.set_ylim(-100,100)

   # Try some constellations
   for cons in d:
      ras,decs = d[cons]
      xs,ys = [],[]
      draw = False
      for i in range(len(ras)):
         if ras[i] is not None:
            x,y,clip = RAhDecd2xy(ras[i],decs[i],MWO)
            if not clip:
               # at least part of constellation is visible
               draw = True
         else:
            x,y = None,None
         xs.append(x); ys.append(y)
      if draw:
         ax.plot(xs,ys, '-', color='0.8', zorder=0, clip_path=clipper)


   # Now we save to a string and also convert to a PIL image, so we can get 
   #  the size.
   output = StringIO.StringIO()
   canvas.print_figure(output, dpi=150, pad_inches=0)
   output.seek(0)
   img = Image.open(output)
   output2 = StringIO.StringIO()
   xsize,ysize = img.size
   img = img.crop((crop,crop,xsize-crop,ysize-crop))
   img.save(output2, 'PNG')
   img_str = 'data:image/png,' + urllib.quote(output2.getvalue())
   #output.seek(0)
   # Get the window coordinates of the points
   bboxes = [o.get_window_extent().inverse_transformed(fig.transFigure) \
         for o in lines]
   coords = [(b.x0, 1-b.y1, b.x1, 1-b.y0) for b in bboxes]
   
   HTML = "<img style=\"margin-left:-10px;\" src=\"%s\" usemap=\"#map\" >" % img_str
   HTML += "<map name=\"map\">\n"
   for i in range(len(names)):
      HTML += "<area shape=rect coords=\"%d %d %d %d\" title=\"%s\" href=\"../navigator/%d/\"" \
            % (int(coords[i][0]*xsize)-crop,
               int(coords[i][1]*ysize)-crop,
               int(coords[i][2]*xsize)-crop,
               int(coords[i][3]*ysize)-crop,
               names[i], ids[i])
      if new_window:
         HTML += " target=\"object_window\">\n"
      else:
         HTML += ">\n"

   HTML += '''
   </map>
   </body>
   </html>'''

   return(HTML)
Ejemplo n.º 2
0
def plot_alt_map(objs, date=None, toff=0, new_window=False):
   '''Plots the altitude for a given night for the given objects (expected to
   be of type Objects).  Returns two strings:  the first is the binary
   PNG file that is the graph, the second is the <map> HTML that will be used
   to make the points in the graph "hot spots"'''
   if date is None:
      date = ephem.now()
   toff = toff/24.
   sun = ephem.Sun()
   MWO = genMWO(date=date)
   sun.compute(MWO)

   # Figure out the start and stop time for the night.
   sunset = MWO.next_setting(sun)    # In DJD
   sunrise = MWO.next_rising(sun)
   if sunset > sunrise:
      sunset = MWO.previous_setting(sun)
   #MWO.date = sunset

   # Setup the graph
   fig = Figure(subplotpars=SubplotParams(left=0.07, right=0.99))
   canvas = FigureCanvasAgg(fig)
   ax = fig.add_subplot(111)
   ax.xaxis.set_major_locator(mdates.HourLocator(interval=2))
   ax.xaxis.set_minor_locator(mdates.MinuteLocator(byminute=[0,60]))
   ax.set_xlabel('UTC time')
   ax.set_ylabel('Altitude')
   ax.grid(True, which='both', linestyle='-', color='gray')
   lines = []
   names = []
   ids = []

   sunset = sunset - 60*ephem.minute
   sunrise = sunrise + 60*ephem.minute

   for obj in objs:
      eobj = obj.genobj()
      t0 = obj.rise_time()
      if t0 is None or t0 < sunset: t0 = sunset
      if t0 > sunrise: continue
      t1 = obj.set_time()
      if t1 is None or t1 > sunrise: t1 = sunrise
      if t1 < sunset: 
         continue

      tt = date
      if tt < t0:  tt = t0
      if tt > t1:  tt = t1
      tt = tt*1 + 693595.5
      saved_epoch = obj.epoch
      obj.epoch = date
      aa = obj.altitude()
      ts = arange(t0,t1+ephem.minute,10*ephem.minute)
      alts = []
      for t in ts:
         #obj.epoch = t
         #alts.append(obj.altitude())
         MWO.date = t
         eobj.compute(MWO)
         alts.append(eobj.alt*180.0/pi)
      alts = array(alts)
      mid = argmax(alts)
      merid = ephem.Date(ts[mid]+toff)
      maxalt = alts[mid]
      ts = ts + 693595.5   # convert to matplotlib epochs
      title = "Meridian @ %s (%.1fd)" % (str(merid).split()[1], maxalt)
      ax.text(0.5, 1.1, title, transform=ax.transAxes, ha='center', 
            va='top', fontsize=18)
      ax.plot_date(ts+toff, alts, '-')
      pobj = ax.plot_date([tt+toff],[aa], 'o', mfc='k')
      lines.append(pobj[0])
      names.append(obj.name)
      ids.append(obj.pk)
      obj.epoch = saved_epoch
   
   ax.set_ylim(0, 90.)

   ax.set_xlim(sunset*1+693595.5+toff, sunrise*1+693595.5+toff)
   ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
   for tick in ax.xaxis.get_major_ticks():
      tick.label2On = True
   ax.axvline(date*1+693595.5+toff, color='red')
   ax.axvline(sunset+60*ephem.minute+693595.5+toff, linestyle='--',
         linewidth=2, color='red')
   ax.axvline(sunrise-60*ephem.minute+693595.5+toff, linestyle='--',
         linewidth=2, color='red')
   ax.fill_between([sunset*1+693595.5+toff,sunrise*1+1+693595.5+toff], 0, 30,
         color='0.7', zorder=0)

   # Now we save to a string and also convert to a PIL image, so we can get 
   #  the size.
   output = StringIO.StringIO()
   canvas.print_figure(output)
   img_str = 'data:image/png,' + urllib.quote(output.getvalue())
   output.seek(0)
   img = Image.open(output)
   output.close()
   xsize,ysize = img.size
   
   # Get the window coordinates of the points
   bboxes = [o.get_window_extent(0).inverse_transformed(fig.transFigure) \
         for o in lines]
   coords = [(b.x0, 1-b.y1, b.x1, 1-b.y0) for b in bboxes]
   
   HTML = "<img src=\"%s\" style=\"width: 280px\" usemap=\"#map\" >" % img_str
   HTML += "<map name=\"map\">\n"
   for i in range(len(names)):
      HTML += "<area shape=rect coords=\"%d %d %d %d\" title=\"%s\" href=\"../object/%d/\"" \
            % (int(coords[i][0]*xsize),
               int(coords[i][1]*ysize),
               int(coords[i][2]*xsize),
               int(coords[i][3]*ysize),
               names[i], ids[i])
      if new_window:
         HTML += " target=\"object_window\">\n"
      else:
         HTML += ">\n"
   HTML += '''
   </map>
   </body>
   </html>'''

   return(HTML)