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)
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)