def get_SMO_pos(): global lat_i, long_i, RA_i, DEC_i, times, tname_i, option, places global coords_s, coords_m, coords_o, dist_sun, dist_moon, loc """read in from entry boxes""" ##handle if there is a look up to be done site = option.get() if (site is 'Anywhere Else'): lat = float(lat_i.get()) long = float(long_i.get()) else: if (places.get(site) is None): Label(master, bg='red', text='SITE NAME {} IS NOT VALID'.format(site.upper())).grid( row=5, column=3) return None else: lat, long = places[site] #loc = coordinates.EarthLocation(lat=lat*u.deg, lon=long*u.deg) loc = Observer(longitude=long * u.degree, latitude=lat * u.degree, name=site) tname = str(tname_i.get()) if (tname is ''): RA = float(RA_i.get()) DEC = float(DEC_i.get()) """target's RA and DEC""" coords_o = coordinates.SkyCoord(ra=RA * u.hour, dec=DEC * u.degree, frame='gcrs') else: coords_o = coordinates.SkyCoord.from_name(tname, frame='gcrs') """Sun's RA and DEC throughout the given time""" coords_s = loc.sun_altaz(times) """Moon's RA and DEC at the location, throughout the given time""" coords_m = loc.moon_altaz(times) """get separation angles in radians for the Sun and Moon""" """this returns a value in the range [-180, 180]""" dist_sun = (coords_s.separation(coords_o).degree) dist_moon = (coords_m.separation(coords_o).degree) """change button after press""" WHERE_button.config(fg='black', bg='#FFE100')
def timeline(request): # get location location = EarthLocation( lon=settings.OBSERVER_LOCATION['longitude'] * u.deg, lat=settings.OBSERVER_LOCATION['latitude'] * u.deg, height=settings.OBSERVER_LOCATION['elevation'] * u.m) # get observer and now now = Time.now() observer = Observer(location=location) # night or day? is_day = observer.sun_altaz(now).alt.degree > 0. # get sunset to start with sunset = observer.sun_set_time(now, which='next' if is_day else 'previous') # list of events events = [] events.append(sunset.isot) # twilight at sunset sunset_twilight = observer.sun_set_time(sunset, which='next', horizon=-12. * u.deg) events.append(sunset_twilight.isot) # twilight at sunrise sunrise_twilight = observer.sun_rise_time(sunset_twilight, which='next', horizon=-12. * u.deg) events.append(sunrise_twilight.isot) # sunrise sunrise = observer.sun_rise_time(sunset_twilight, which='next') events.append(sunrise.isot) # return all return JsonResponse({'time': now.isot, 'events': events})
def good_weather(request): # get changes in status from last 24 hours changes = [{ 'time': g.time, 'good': g.good } for g in GoodWeather.objects.filter(time__gt=datetime.utcnow() - timedelta(days=1)).all()] # if None, return last one if len(changes) == 0: last = GoodWeather.objects.last() if last is not None: changes = [{'time': last.time, 'good': last.good}] # get location location = EarthLocation( lon=settings.OBSERVER_LOCATION['longitude'] * u.deg, lat=settings.OBSERVER_LOCATION['latitude'] * u.deg, height=settings.OBSERVER_LOCATION['elevation'] * u.m) # get observer and now now = Time.now() observer = Observer(location=location) # get solar elevation for last 12 hours times = [now - TimeDelta((1. - x) * u.day) for x in np.linspace(0, 1, 100)] sun = [s.alt.degree for s in observer.sun_altaz(times)] # return all return JsonResponse({ 'changes': changes, 'sun': { 'time': [t.isot for t in times], 'alt': sun } })
def createPicture(name, times): rcParams['font.size'] = 13 rcParams['lines.linewidth'] = 3 rcParams['lines.markersize'] = 0 rcParams['grid.linestyle'] = '--' rcParams['axes.titlepad'] = 13 rcParams['xtick.direction'] = 'in' rcParams['ytick.direction'] = 'in' rcParams['xtick.top'] = True rcParams['ytick.right'] = True rcParams['font.family'] = 'serif' rcParams['mathtext.fontset'] = 'dejavuserif' rc('legend', fontsize=13) rc('xtick.major', size=5, width=1.5) rc('ytick.major', size=5, width=1.5) rc('xtick.minor', size=3, width=1) rc('ytick.minor', size=3, width=1) star_name = name star_style = {'linestyle': '--', 'linewidth': 4, 'color': 'tomato'} star = FixedTarget.from_name(star_name) longitude_kgo = 42.6675 * u.deg latitude_kgo = 43.73611 * u.deg elevation_kgo = 2112 * u.m kgo = Observer(longitude=longitude_kgo, latitude=latitude_kgo, elevation=elevation_kgo, name="KGO", timezone="Europe/Moscow") # start_time = Time('2020-01-01 '+ times) # end_time = Time('2020-02-01 '+ times) # delta_t = end_time - start_time # observe_time = start_time + delta_t*np.linspace(0, 1, 32) observe_time = Time(times) # sunset_tonight = kgo.sun_set_time(observe_time, which="nearest") # sunrise_tonight = kgo.sun_rise_time(observe_time, which="nearest") # star_rise = list(map(lambda observe_time : kgo.target_rise_time(observe_time, star) + 5*u.minute, observe_time)) # star_set = list(map(lambda observe_time: kgo.target_set_time(observe_time, star) + 5*u.minute, observe_time)) # sunset_tonight = list(map(lambda observe_time: kgo.sun_set_time(observe_time, which="nearest"), observe_time)) # sunrise_tonight = list(map(lambda observe_time: kgo.sun_rise_time(observe_time, which="nearest"), observe_time)) visible_time = observe_time + np.linspace(-10, +10, 25) * u.hour #visible_time = start + (end - start)*np.linspace(0, 1, 25) stars_alts = kgo.altaz(visible_time, star).alt sun_alts = kgo.sun_altaz(visible_time).alt moon_coord = kgo.moon_altaz(visible_time) star_coord = kgo.altaz(visible_time, star) angle = moon_coord.separation(star_coord) moon_star = angle.deg #print(stars_alts) #t = Time(visible_time, format='iso', scale='utc') # start = Time(list(map(lambda x,y: np.max([x, y]), sunset_tonight, star_rise))) # end = Time(list(map(lambda x,y: np.min([x,y]), sunrise_tonight, star_set))) #visible_time = (end-start) #time_final = abs(visible_time.value*24) locator = mdates.MonthLocator() fmt = mdates.DateFormatter('%b') canvas = FigureCanvasAgg(plt.figure(1)) plt.figure(figsize=(8, 7)) plt.subplot(211) plt.plot_date(visible_time.plot_date, stars_alts, linestyle='-.', color='mediumslateblue', label=star_name) plt.plot_date(visible_time.plot_date, sun_alts, linestyle='-.', color='gold', label='Sun') plt.ylim(0, np.max([stars_alts, sun_alts]) + 5) plt.ylabel('Altitude, degrees') plt.legend(shadow=True, loc="best") plt.gcf().autofmt_xdate() plt.grid() plt.subplot(212) plt.plot_date(visible_time.plot_date, moon_star, linestyle='-', color='slategrey', label='star_name' + '\n' + times) plt.ylabel('Moon-Star angle, degrees') plt.gcf().autofmt_xdate() plt.grid() data = BytesIO() plt.savefig(data, format='png') return data.getvalue()
return places numDays = 365 oneDay = TimeDelta(1.0,format='jd') firstDay = Time('2018-01-01 00:00:00',scale='utc') allDays = [ firstDay + i*oneDay for i in range(numDays) ] #places = get_places_fromlist(loc_names,loc_coord) places = get_places(loc_names) elevations = np.zeros((len(places.locations),len(allDays))) for ind,(loc,coord) in enumerate(zip(places.locations,places.coordinates)): print(f"Computing sun elevations for {loc}") observer = Observer(location=coord) noons = [ observer.noon(h,which=u'next') for h in allDays ] sunpos = [ observer.sun_altaz(h) for h in noons ] elevations[ind,:] = [ az.alt/u.deg for az in sunpos ] df = pd.DataFrame([d.to_datetime() for d in allDays]) df.columns = [ 'Day' ] dfelevs = pd.DataFrame(elevations.transpose(),columns=places.locations) df = df.join(dfelevs).set_index('Day') dfs = df.stack().reset_index() dfs.columns = ['day','location','elevation'] p = ggplot(dfs,aes(x='day',y='elevation',color='location')) + geom_line() p = p + ggtitle('Sun elevations by date and location') p = p + xlab('Day of year') + ylab('Elevation (degrees)') p.draw()
def main(args=None): p = parser() opts = p.parse_args(args) # Late imports import operator import sys from astroplan import Observer from astroplan.plots import plot_airmass from astropy.coordinates import EarthLocation, SkyCoord from astropy.table import Table from astropy.time import Time from astropy import units as u from matplotlib import dates from matplotlib.cm import ScalarMappable from matplotlib.colors import Normalize from matplotlib.patches import Patch from matplotlib import pyplot as plt from tqdm import tqdm import pytz from ..io import fits from .. import moc from .. import plot # noqa from ..extern.quantile import percentile if opts.site is None: if opts.site_longitude is None or opts.site_latitude is None: p.error('must specify either --site or both ' '--site-longitude and --site-latitude') location = EarthLocation(lon=opts.site_longitude * u.deg, lat=opts.site_latitude * u.deg, height=(opts.site_height or 0) * u.m) if opts.site_timezone is not None: location.info.meta = {'timezone': opts.site_timezone} observer = Observer(location) else: if not ((opts.site_longitude is None) and (opts.site_latitude is None) and (opts.site_height is None) and (opts.site_timezone is None)): p.error('argument --site not allowed with arguments ' '--site-longitude, --site-latitude, ' '--site-height, or --site-timezone') observer = Observer.at_site(opts.site) m = fits.read_sky_map(opts.input.name, moc=True) # Make an empty airmass chart. t0 = Time(opts.time) if opts.time is not None else Time.now() t0 = observer.midnight(t0) ax = plot_airmass([], observer, t0, altitude_yaxis=True) # Remove the fake source and determine times that were used for the plot. del ax.lines[:] times = Time(np.linspace(*ax.get_xlim()), format='plot_date') theta, phi = moc.uniq2ang(m['UNIQ']) coords = SkyCoord(phi, 0.5 * np.pi - theta, unit='rad') prob = moc.uniq2pixarea(m['UNIQ']) * m['PROBDENSITY'] levels = np.arange(90, 0, -10) nlevels = len(levels) percentiles = np.concatenate((50 - 0.5 * levels, 50 + 0.5 * levels)) airmass = np.column_stack([ percentile(condition_secz(coords.transform_to(observer.altaz(t)).secz), percentiles, weights=prob) for t in tqdm(times) ]) cmap = ScalarMappable(Normalize(0, 100), plt.get_cmap()) for level, lo, hi in zip(levels, airmass[:nlevels], airmass[nlevels:]): ax.fill_between( times.plot_date, clip_verylarge(lo), # Clip infinities to large but finite values clip_verylarge(hi), # because fill_between cannot handle inf color=cmap.to_rgba(level), zorder=2) ax.legend([Patch(facecolor=cmap.to_rgba(level)) for level in levels], ['{}%'.format(level) for level in levels]) # ax.set_title('{} from {}'.format(m.meta['objid'], observer.name)) # Adapted from astroplan start = times[0] twilights = [ (times[0].datetime, 0.0), (observer.sun_set_time(Time(start), which='next').datetime, 0.0), (observer.twilight_evening_civil(Time(start), which='next').datetime, 0.1), (observer.twilight_evening_nautical(Time(start), which='next').datetime, 0.2), (observer.twilight_evening_astronomical(Time(start), which='next').datetime, 0.3), (observer.twilight_morning_astronomical(Time(start), which='next').datetime, 0.4), (observer.twilight_morning_nautical(Time(start), which='next').datetime, 0.3), (observer.twilight_morning_civil(Time(start), which='next').datetime, 0.2), (observer.sun_rise_time(Time(start), which='next').datetime, 0.1), (times[-1].datetime, 0.0), ] twilights.sort(key=operator.itemgetter(0)) for i, twi in enumerate(twilights[1:], 1): if twi[1] != 0: ax.axvspan(twilights[i - 1][0], twilights[i][0], ymin=0, ymax=1, color='grey', alpha=twi[1], linewidth=0) if twi[1] != 0.4: ax.axvspan(twilights[i - 1][0], twilights[i][0], ymin=0, ymax=1, color='white', alpha=0.8 - 2 * twi[1], zorder=3, linewidth=0) # Add local time axis timezone = (observer.location.info.meta or {}).get('timezone') if timezone: tzinfo = pytz.timezone(timezone) ax2 = ax.twiny() ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(ax.get_xticks()) ax2.xaxis.set_major_formatter(dates.DateFormatter('%H:%M', tz=tzinfo)) plt.setp(ax2.get_xticklabels(), rotation=-30, ha='right') ax2.set_xlabel("Time from {} [{}]".format( min(times).to_datetime(tzinfo).date(), timezone)) if opts.verbose: # Write airmass table to stdout. times.format = 'isot' table = Table(masked=True) table['time'] = times table['sun_alt'] = np.ma.masked_greater_equal( observer.sun_altaz(times).alt, 0) table['sun_alt'].format = lambda x: '{}'.format(int(np.round(x))) for p, data in sorted(zip(percentiles, airmass)): table[str(p)] = np.ma.masked_invalid(data) table[str(p)].format = lambda x: '{:.01f}'.format(np.around(x, 1)) table.write(sys.stdout, format='ascii.fixed_width') # Show or save output. opts.output()
"""used to make all further calculations substantially faster""" times = astropy.time.Time([(t + (i * step) * u.minute) for i in range((60 // step) * 24 * ndays)]) """labels for the plot later""" window = [i.datetime for i in times] if ndays <= 60: window_x = [ i.date().strftime('%m-%d') for i in window[::(60 // step) * 24] ] else: window_x = window[::(60 // step) * 24] window_y = [i for i in window[0:(60 // step) * 24 + (60 // step) + 1]] loc = Observer(longitude=long * u.degree, latitude=lat * u.degree, name=site) """Sun's RA and DEC throughout the given time""" coords_s = loc.sun_altaz(times) """get separation angles in radians for the Sun and Moon""" """whether or not the altitudes are low enough""" alt_s = (sun_alt - coords_s.alt.degree) fig = plt.figure(figsize=(18, 9)) ax = plt.subplot(111) """set the proper number of ticks""" if ndays <= 60: ext = (0, (60 // step) * 24, 0, (60 // step) * 24) xticks = range(0, (60 // step) * 24, (60 // step) * 24 // ndays) plt.xticks(xticks) ax.set_xticklabels(window_x, rotation=90) else: ext = (0, ndays, 0, (60 // step) * 24)
def sassy_cron_airmass(_log=None, _folder=''): # define observer, observatory, time, frame, sun and moon _observatory = EarthLocation(lat=MMT_LATITUDE*u.deg, lon=MMT_LONGITUDE * u.deg, height=MMT_ELEVATION * u.m) _observer = Observer(location=_observatory, name='MMT', timezone='US/Arizona') _now_isot = get_isot(0) _now = Time(_now_isot) _start_time = Time(_now_isot.replace('T', ' ')) + 1.0*u.day * np.linspace(0.0, 1.0, int(24.0*60.0/5.0)) _frame = AltAz(obstime=_start_time, location=_observatory) _moon = _observer.moon_altaz(_start_time) _moon_time = _moon.obstime _moon_alt = _moon.alt _moon_az = _moon.az _sun = _observer.sun_altaz(_start_time) _sun_time = _sun.obstime _sun_alt = _sun.alt _sun_az = _sun.az # get record(s) _s = db_connect() _query = _s.query(SassyCron) for _q in _query.all(): # get data _zoid, _zra, _zdec = _q.zoid, _q.zra, _q.zdec _base = f"{_folder}/{_q.dpng}" _replace = 'difference' if _base == '': _base = f"{_folder}/{_q.spng}" _replace = 'science' if _base == '': _base = f"{_folder}/{_q.tpng}" _replace = 'template' if _base == '': return _airmass = _base.replace(_replace, 'airmass') if _log: _log.info(f"_zoid={_zoid}, _zra={_zra}, _zdec={_zdec}, _base={_base}, _replace={_replace}, _airmass={_airmass}") # convert _ra = ra_to_hms(_zra) _dec = dec_to_dms(_zdec) _dec = f"{_dec}".replace("+", "") _title = f"{_zoid} Airmass @ MMT\nRA={_ra} ({_zra:.3f}), Dec={_dec} ({_zdec:.3f})" # get target _coords = SkyCoord(ra=_zra*u.deg, dec=_zdec*u.deg) _target = _coords.transform_to(_frame) _target_time = _target.obstime _target_alt = _target.alt _target_az = _target.az # plot data _time = str(_target_time[0]).split()[0] fig, ax = plt.subplots() _ax_scatter = ax.plot(_moon_time.datetime, _moon_alt.degree, 'g--', label='Moon') _ax_scatter = ax.plot(_sun_time.datetime, _sun_alt.degree, 'r--', label='Sun') _ax_scatter = ax.scatter(_target_time.datetime, _target_alt.degree, c=np.array(_target_az.degree), lw=0, s=8, cmap='viridis') ax.plot([_now.datetime, _now.datetime], [ASTRONOMICAL_DAWN, 90.0], 'orange') ax.plot([_target_time.datetime[0], _target_time.datetime[-1]], [0.0, 0.0], 'black') ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) plt.gcf().autofmt_xdate() plt.colorbar(_ax_scatter, ax=ax).set_label(f'Azimuth ({OBS_DEGREE})') ax.set_ylim([ASTRONOMICAL_DAWN, 90.0]) ax.set_xlim([_target_time.datetime[0], _target_time.datetime[-1]]) ax.set_title(f'{_title}') ax.set_ylabel(f'Altitude ({OBS_DEGREE})') ax.set_xlabel(f'{_time} (UTC)') plt.legend(loc='upper left') plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN*u.deg, 90.0*u.deg, _sun_alt < 0.0*u.deg, color='0.80', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN*u.deg, 90.0*u.deg, _sun_alt < CIVIL_DAWN*u.deg, color='0.60', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN*u.deg, 90.0*u.deg, _sun_alt < NAUTICAL_DAWN*u.deg, color='0.40', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN*u.deg, 90.0*u.deg, _sun_alt < ASTRONOMICAL_DAWN*u.deg, color='0.20', zorder=0) # save plot _buf = io.BytesIO() plt.savefig(_airmass) plt.savefig(_buf, format='png', dpi=100, bbox_inches='tight') plt.close() if _log: _log.info(f"exit ... _airmass={_airmass}") db_disconnect(_s)
win_time = midnight + delta_md night = win_time # day = (midnight + 12*u.hour) + delta_md day = (midnight + 12 * u.hour) + np.linspace(0, 3, 30) * u.hour # GMS op = pd.read_csv('op.csv', index_col='nama') ra = op.ra dec = op.dec sunset = lokasi.sun_set_time(time) sunrise = lokasi.sun_rise_time(time) moonrise = lokasi.moon_rise_time(time) moonset = lokasi.moon_set_time(time) moon_ill = lokasi.moon_illumination(time) moonaltaz = lokasi.moon_altaz(time) moonaltaz.name = 'moon' sunaltaz = lokasi.sun_altaz(time) sunaltaz.name = 'sun' def objek(nama, ra, dec): op = SkyCoord(ra, dec, frame='icrs', unit='deg') op_name = FixedTarget(coord=op, name=nama) # betelgeus = SkyCoord.from_name('betelgeuse') # altaz_frame = lokasi.altaz(time) # ubah lokasi pengamat ke altaz frame # betelgeus_altaz = betelgeus.transform_to(altaz_frame) # ubah target ke altaz altaz = lokasi.altaz(win_time, op) terbit = lokasi.target_rise_time(win_time, op) transit = lokasi.target_meridian_transit_time(win_time, op) terbenam = lokasi.target_set_time(win_time, op) return op_name, altaz, terbit, transit, terbenam
def plot_tel_airmass(_log=None, _ra=math.nan, _dec=math.nan, _oid='', _tel='mmt', _img=''): # define observer, observatory, time, frame, sun and moon if _tel.lower().strip() == 'bok': _observatory = EarthLocation(lat=BOK_LATITUDE * u.deg, lon=BOK_LONGITUDE * u.deg, height=BOK_ELEVATION * u.m) _observer = Observer(location=_observatory, name='BOK', timezone='US/Arizona') elif _tel.lower().strip() == 'greenwich': _observatory = EarthLocation(lat=GREENWICH_LATITUDE * u.deg, lon=GREENWICH_LONGITUDE * u.deg, height=GREENWICH_ELEVATION * u.m) _observer = Observer(location=_observatory, name='GREENWICH', timezone='Greenwich') elif _tel.lower().strip() == 'kuiper': _observatory = EarthLocation(lat=KUIPER_LATITUDE * u.deg, lon=KUIPER_LONGITUDE * u.deg, height=KUIPER_ELEVATION * u.m) _observer = Observer(location=_observatory, name='KUIPER', timezone='US/Arizona') elif _tel.lower().strip() == 'mmt': _observatory = EarthLocation(lat=MMT_LATITUDE * u.deg, lon=MMT_LONGITUDE * u.deg, height=MMT_ELEVATION * u.m) _observer = Observer(location=_observatory, name='MMT', timezone='US/Arizona') elif _tel.lower().strip() == 'steward': _observatory = EarthLocation(lat=STEWARD_LATITUDE * u.deg, lon=STEWARD_LONGITUDE * u.deg, height=STEWARD_ELEVATION * u.m) _observer = Observer(location=_observatory, name='STEWARD', timezone='US/Arizona') elif _tel.lower().strip() == 'vatt': _observatory = EarthLocation(lat=VATT_LATITUDE * u.deg, lon=VATT_LONGITUDE * u.deg, height=VATT_ELEVATION * u.m) _observer = Observer(location=_observatory, name='VATT', timezone='US/Arizona') else: return if _log: _log.info( f"plot_tel_airmass(_ra={_ra:.3f}, _dec={_dec:.3f}, _oid={_oid}, _tel={_tel}, _img={_img}" ) # get sun, moon etc _now_isot = get_isot(0) _now = Time(_now_isot) _start_time = Time(_now_isot.replace( 'T', ' ')) + 1.0 * u.day * np.linspace(0.0, 1.0, int(24.0 * 60.0 / 5.0)) _frame = AltAz(obstime=_start_time, location=_observatory) _moon = _observer.moon_altaz(_start_time) _moon_time = _moon.obstime _moon_alt = _moon.alt _moon_az = _moon.az _sun = _observer.sun_altaz(_start_time) _sun_time = _sun.obstime _sun_alt = _sun.alt _sun_az = _sun.az # convert _oid_s = str(_oid).replace("'", "") _ra_hms = ra_to_hms(_ra) _dec_dms = dec_to_dms(_dec) _dec_dms = f"{_dec_dms}".replace("+", "") _sup_title = f"{_oid} Airmass @ {_tel.upper()}" _sub_title = f"RA={_ra_hms} ({_ra:.3f}), Dec={_dec_dms} ({_dec:.3f})" # get target _coords = SkyCoord(ra=_ra * u.deg, dec=_dec * u.deg) _target = _coords.transform_to(_frame) _target_time = _target.obstime _target_alt = _target.alt _target_az = _target.az # plot data _time = str(_target_time[0]).split()[0] fig, ax = plt.subplots() fig.suptitle(_sup_title.replace("'", "").replace("{", "").replace("}", "")) _ax_scatter = ax.plot(_moon_time.datetime, _moon_alt.degree, 'g--', label='Moon') _ax_scatter = ax.plot(_sun_time.datetime, _sun_alt.degree, 'r--', label='Sun') _ax_scatter = ax.scatter(_target_time.datetime, _target_alt.degree, c=np.array(_target_az.degree), lw=0, s=8, cmap='viridis') ax.plot([_now.datetime, _now.datetime], [ASTRONOMICAL_DAWN, 90.0], 'orange') ax.plot([_target_time.datetime[0], _target_time.datetime[-1]], [0.0, 0.0], 'black') ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) plt.gcf().autofmt_xdate() plt.colorbar(_ax_scatter, ax=ax).set_label(f'Azimuth ({OBS_DEGREE})') ax.set_ylim([ASTRONOMICAL_DAWN, 90.0]) ax.set_xlim([_target_time.datetime[0], _target_time.datetime[-1]]) ax.set_title(_sub_title) ax.set_ylabel(f'Altitude ({OBS_DEGREE})') ax.set_xlabel(f'{_time} (UTC)') plt.legend(loc='upper left') plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN * u.deg, 90.0 * u.deg, _sun_alt < 0.0 * u.deg, color='0.80', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN * u.deg, 90.0 * u.deg, _sun_alt < CIVIL_DAWN * u.deg, color='0.60', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN * u.deg, 90.0 * u.deg, _sun_alt < NAUTICAL_DAWN * u.deg, color='0.40', zorder=0) plt.fill_between(_target_time.datetime, ASTRONOMICAL_DAWN * u.deg, 90.0 * u.deg, _sun_alt < ASTRONOMICAL_DAWN * u.deg, color='0.20', zorder=0) # save plot _buf = io.BytesIO() plt.savefig(_img) plt.savefig(_buf, format='png', dpi=100, bbox_inches='tight') plt.close() # return _img = os.path.abspath(os.path.expanduser(_img)) if os.path.exists(_img): if _log: _log.debug(f"created {_img}") return _img else: if _log: _log.debug(f"created None") return