def make_plot(flight_data, outfile='overview.pdf', meta=None): if meta is None: meta = {} meta['domain'] = {} meta['domain']['lats'] = [flight_data.lat.min(), flight_data.lat.max()] meta['domain']['lons'] = [flight_data.lon.min(), flight_data.lon.max()] meta['domain']['max_alt'] = int(flight_data.alt.max()) LAT_EXTENT_MIN = 10 LON_EXTENT_MIN = 10 ASPECT_RATIO = 1.2 lon_min = flight_data.lon.min() - 1 lon_max = flight_data.lon.max() + 1 lat_min = flight_data.lat.min() - 1 lat_max = flight_data.lat.max() + 1 if lat_max - lat_min < LAT_EXTENT_MIN: delta = (LAT_EXTENT_MIN - (lat_max - lat_min)) / 2 lat_min = lat_min - delta lat_max = lat_max + delta if lon_max - lon_min < LON_EXTENT_MIN: delta = (LON_EXTENT_MIN - (lon_max - lon_min)) / 2 lon_min = lon_min - delta lon_max = lon_max + delta aspect = (lon_max - lon_min) / (lat_max - lat_min) lat_range = lat_max - lat_min lon_range = lon_max - lon_min if (lon_range < .75 * lat_range): delta = (lat_range - lon_range) / 2 lon_min -= delta lon_max += delta if (lat_range < .75 * lon_range): delta = (lon_range - lat_range) / 2 lat_min -= delta lat_max += delta flight_time = flight_data.index[0] - datetime.timedelta(hours=2) cycle = flight_time.replace(minute=0, second=0, microsecond=0) flight_hour = flight_time.hour cycle_hour = flight_hour - flight_hour % 6 cycle = cycle.replace(hour=cycle_hour) horizon = (flight_hour - cycle_hour) + 1 get_data(cycle, horizon) if lon_max % 360 < lon_min % 360: pan_data('gfs.nc') else: lon_max %= 360 lon_min %= 360 OCEAN = cfeature.NaturalEarthFeature('physical', 'ocean', '50m', edgecolor='face', facecolor=cfeature.COLORS['water']) fig = plt.figure(figsize=(8, 8 * 1.414)) ax = fig.add_axes([.1, .5, .8, .4], projection=ccrs.PlateCarree()) ax2 = fig.add_axes([.1, .25, .8, .2]) hours = mdates.HourLocator() minutes = mdates.MinuteLocator(byminute=range(10, 60, 10)) hours_formatter = mdates.DateFormatter('%Hz') ax2.xaxis.set_major_locator(hours) ax2.xaxis.set_major_formatter(hours_formatter) ax2.xaxis.set_minor_locator(minutes) ax3 = fig.add_axes([.1, .1, .8, .1]) ax3.set_xlim([0, 1]) ax3.set_ylim([0, 1]) ax3.axis('off') ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree()) ax.add_feature(OCEAN) ax.add_feature(cfeature.LAND) ax.coastlines(resolution='50m') ax.add_feature(cfeature.BORDERS, linestyle=':') with Dataset('gfs.nc', 'r') as nc: lat = nc['latitude'][:] lon = nc['longitude'][:] lati_min = nearest(lat, lat_min) - 1 loni_min = nearest(lon, lon_min) - 1 lati_max = nearest(lat, lat_max) + 1 loni_max = nearest(lon, lon_max) + 1 lonr = slice(loni_min, loni_max + 1) latr = slice(lati_min, lati_max + 1) cloud = nc['TCDC_entireatmosphere'][-1, latr, lonr] rain = nc['PRATE_surface'][-1, latr, lonr] mslp = nc['MSLET_meansealevel'][-1, latr, lonr] / 100 h500 = nc['HGT_500mb'][-1, latr, lonr] lat = lat[latr] lon = lon[lonr] for i in range(0, 100, 10): try: ax.contourf(lon, lat, cloud, transform=ccrs.PlateCarree(), levels=[i, i + 10], alpha=i / 100, zorder=990, colors=['gray']) except Exception: break rain_levs = np.arange(0, 0.003, 0.0003) for i, n in enumerate(rain_levs[:-1]): try: ax.contourf(lon, lat, rain, transform=ccrs.PlateCarree(), levels=[rain_levs[i], rain_levs[i + 1]], vmin=0, vmax=np.max(rain_levs), alpha=min([.5, i / len(rain_levs)]), zorder=991) except: continue try: ax.contourf(lon, lat, rain, transform=ccrs.PlateCarree(), levels=[rain_levs[-1], 1], vmin=0, vmax=np.max(rain_levs), zorder=991, extend='above') except: pass cs = ax.contour(lon, lat, mslp, levels=range(920, 1040, 4), colors=('k', ), linewidths=1, zorder=992) ax.clabel(cs, inline=1, fontsize=10, fmt='%d') cs2 = ax.contour(lon, lat, h500, levels=range(4000, 6000, 40), colors=('k', ), linewidths=1, linestyles='--', zorder=993) ax.clabel(cs2, inline=1, fontsize=10, fmt='%d') ax.set_aspect('auto') ax.set_title('Synoptic Overview (GFS {cycle} T+{tplus})'.format( cycle=cycle.strftime('%Y%m%d %Hz'), tplus=horizon)) ax.plot(flight_data.lon, flight_data.lat, transform=ccrs.PlateCarree(), color=[.7, 0, 0], zorder=999) ax2.plot(flight_data.alt, linewidth=3, color=[.7, 0, 0]) ax2.set_title('Altitude (m)') add_text(ax3, meta) fig.savefig(outfile) os.remove('gfs.grb') os.remove('gfs.nc')
def plot_spectro(file, t0plot, t1plot, downsample=1): #--------------------------------------# # Note downsampling allows a bigger time range to be read into RAM. # But it increases the computation time significantly. On an average # machine it may be best to keep full sampling (default), but limit # your plot to 15 minute blocks. runtime0 = datetime.now() f = h5py.File(file, 'r') t_lines = np.shape(f['SUB_ARRAY_POINTING_000/BEAM_000/STOKES_0'])[0] f_lines = np.shape(f['SUB_ARRAY_POINTING_000/BEAM_000/STOKES_0'])[1] target = f.attrs['TARGETS'][0] print('Target: %s' % (target)) #---------------------------------# # Sort out the time arrays # obs_start = f.attrs['OBSERVATION_START_UTC'].decode("utf-8") obs_stop = f.attrs['OBSERVATION_END_UTC'].decode("utf-8") obs_start = datetime.strptime(obs_start[0:-4], "%Y-%m-%dT%H:%M:%S.%f") obs_stop = datetime.strptime(obs_stop[0:-4], "%Y-%m-%dT%H:%M:%S.%f") total_duration = f.attrs['TOTAL_INTEGRATION_TIME'] #in seconds tres = total_duration / t_lines t0sec = t0plot - obs_start t1sec = t1plot - obs_start t0index = int(t0sec.seconds / tres) t1index = int(t1sec.seconds / tres) print('Observation start time: %s' % (obs_start)) print('Observation stop time: %s' % (obs_stop)) print('Total observation duration %s seconds.' % (total_duration)) print('Time resolution: %s seconds.' % (tres * downsample)) tim_mpl = [ dates.date2num(obs_start + timedelta(seconds=tres * (i + t0index))) for i in range(t1index - t0index) ] tim_mpl = tim_mpl[::downsample] #----------------------------------# # Sort out the frequency arrays # start_freq = f.attrs['OBSERVATION_FREQUENCY_MIN'] #in MHz end_freq = f.attrs['OBSERVATION_FREQUENCY_MAX'] fres = (end_freq - start_freq) / f_lines #in MHz freq = np.linspace(start_freq, end_freq, f_lines) print('Frequency resolution: %s MHz.' % (fres * downsample)) #-------------------------------------# # Downsample and background subtract # gigabytes = 4 * f_lines * ( t1index - t0index) / downsample / 1e9 # Data is 32 bit (4 byte). print('Reading in %s GB of data.' % (gigabytes)) #import pdb #pdb.set_trace() data = f['SUB_ARRAY_POINTING_000/BEAM_000/STOKES_0'][ t0index:t1index:downsample, ::downsample] data = np.transpose(data) data = backsub(data) #----------------------------------# # High pass filter # #data_lp = ndimage.gaussian_filter(data, sigma=(10, 10)) #data = data - data_lp xyshape = np.shape(data) print('Array size: %s Mpixels.' % (xyshape[0] * xyshape[1] / 1e6)) #----------------------------------# # Plot the spectrogram # plt.figure(0, figsize=(12, 6)) imshow(data[::-1, ::], aspect='auto', extent=(tim_mpl[0], tim_mpl[-1], start_freq, end_freq), cmap=plt.get_cmap('plasma'), vmin=np.percentile(data, 30.0), vmax=np.percentile(data, 97.9)) yymmdd = f.attrs['OBSERVATION_END_UTC'][0:10] xlabel('Time (UT)') ylabel('Frequency (MHz)') title('LOFAR %s Beam 000 %s' % (yymmdd, target)) np.save('dynamic_spec_hba.npy', data) extent = [tim_mpl[0], tim_mpl[-1], end_freq, start_freq] np.save('extent_hba.npy', extent) ax = plt.gca() ax.set_yscale('log') ax.xaxis_date() ax.xaxis.set_major_locator(dates.MinuteLocator(interval=5)) ax.xaxis.set_minor_locator(dates.SecondLocator(interval=60)) ax.xaxis.set_major_formatter(dates.DateFormatter('%H:%M:%S')) runtime1 = datetime.now() runtime = runtime1 - runtime0 print('Execution time: %s seconds' % (runtime.seconds)) plt.show()
ax.fmt_xdata = DateFormatter('%Y-%m-%d %H:%M:%S') fig.autofmt_xdate() plt.savefig('demo_matplotlib_2.png') ### demo 3: database-connection and plot data print 'demo 3, started at %s' % str(datetime.datetime.now()) import matplotlib.dates as mdates years = mdates.YearLocator() months = mdates.MonthLocator() days = mdates.DayLocator() hours = mdates.HourLocator() minutes = mdates.MinuteLocator() yearsFmt = mdates.DateFormatter('%Y') daysFmt = mdates.DateFormatter('%Y-%m-%d') cur = None try: con = psycopg2.connect(host='123.456.789.123', database='db', user='******', password='******') cur = con.cursor() cur.execute('SELECT version()') version = cur.fetchone() print 'DB Server Version: %s' % version
'journeys, by day of week (07:00-18:00)', 'drakewell-dow.pdf', labels=mon_fri) # =============== Example daily graph fig, ax = plt.subplots(nrows=1, ncols=1) df['2019-04-02'].minutes.plot(style='b.', ax=ax) ax.grid(axis='y') ax.set_ylim([0, 40]) ax.set_xlabel('') ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=60)) ax.xaxis.set_major_formatter( mdates.DateFormatter('%H:%M', tz=pytz.timezone('Europe/London'))) ax.set_xlim( [datetime.datetime(2019, 4, 2, 0), datetime.datetime(2019, 4, 3, 0)]) ax.set_ylabel('Minutes') fig.suptitle('Example journey time (2019-04-02)') plt.savefig('drakewell-example.pdf') plt.close() # =============== Grand summary - Mon-Fri, 07:00-18:00
def genericplot(df, column, outfile, config, device_name): timeframe = config["timeframe"] outfile = outfile.replace(":", ".") logging.info("creating " + outfile) dim = (16, 6) markersize = 1 style = "-" colormapName = "Set1" plt.style.use("seaborn-whitegrid") palette = plt.get_cmap(colormapName) colour = palette(1) # Is this a numeric column? try: column_type = str(df[column].dtype) except AttributeError: column_type = "unknown" if column_type == "float64" or column_type == "int64": logging.debug(column_type) else: return try: dim = parse_tuple("(" + config["plotting"]["dim"] + ")") except KeyError: pass try: markersize = float(config["plotting"]["markersize"]) except KeyError: pass try: style = config["plotting"]["style"] except KeyError: pass fig, ax = plt.subplots(figsize=dim, dpi=80, facecolor="w", edgecolor="dimgrey") if timeframe is not None: ax.plot( df[column][timeframe.split(",")[0]:timeframe.split(",")[1]], alpha=0.7, color=colour, ) else: ax.plot(df[column], alpha=0.7, color=colour) plt.grid(which="both", axis="both", linestyle="--") # vmstat make chart top "100" if column == "us" or column == "sy" or column == "wa" or column == "Total CPU": ax.set_ylim(ymax=100) # y axis ax.get_yaxis().set_major_formatter( plt.FuncFormatter(lambda x, loc: "{:,}".format(float(x)))) ax.set_ylim(ymin=0) # Always zero start if df[column].max() > 999: ax.yaxis.set_major_formatter( matplotlib.ticker.StrMethodFormatter("{x:,.0f}")) else: ax.yaxis.set_major_formatter(ScalarFormatter(useOffset=None)) ax.get_yaxis().get_major_formatter().set_scientific(False) # Try to be smarter with the x axis. more to come if timeframe is not None and timeframe != "": StartTime = datetime.strptime( timeframe.split(",")[0], "%Y-%m-%d %H:%M:%S") EndTime = datetime.strptime( timeframe.split(",")[-1], "%Y-%m-%d %H:%M:%S") TotalMinutes = (EndTime - StartTime).total_seconds() / 60 logging.debug("TF Minutes: " + str(TotalMinutes)) else: StartTime = df.index[0] EndTime = df.index[-1] # logging.debug("Sart Date: "+str(StartTime)) # logging.debug("End Date: "+str(EndTime)) TotalMinutes = (df.index[-1] - df.index[0]).total_seconds() / 60 logging.debug("All Minutes: " + str(TotalMinutes)) if TotalMinutes <= 1: # logging.debug("0 minutes: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M")) ax.xaxis.set_major_locator(mdates.HourLocator()) elif TotalMinutes <= 60: # logging.debug("60 minutes: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S")) ax.xaxis.set_major_locator(mdates.MinuteLocator()) elif TotalMinutes <= 180: # logging.debug("180 minutes: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M")) ax.xaxis.set_major_locator(mdates.MinuteLocator()) elif TotalMinutes <= 720: # logging.debug("720 minutes: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M")) ax.xaxis.set_major_locator(mdates.HourLocator()) elif TotalMinutes <= 1500: # logging.debug("1 Day: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M")) ax.xaxis.set_major_locator(mdates.HourLocator()) elif TotalMinutes <= 3000: # logging.debug("1 Day: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%d-%H:%M")) ax.xaxis.set_major_locator(mdates.HourLocator()) else: # logging.debug("More than 1 Day: " + str(TotalMinutes)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%a %m/%d - %H:%M")) # ax.xaxis.set_major_locator(mdates.HourLocator()) if device_name == "": plt.title(column + " between " + str(StartTime) + " and " + str(EndTime), fontsize=12) else: plt.title( device_name + " : " + column + " between " + str(StartTime) + " and " + str(EndTime), fontsize=12, ) # plt.xlabel("Time", fontsize=10) plt.tick_params(labelsize=10) plt.setp(ax.get_xticklabels(), rotation=45, ha="right") plt.tight_layout() plt.savefig(outfile, bbox_inches="tight") plt.close()
def _deduce_locators_formatters(max_ticks, data): from datetime import timedelta as tdelta import matplotlib.dates as mdates from matplotlib.ticker import FuncFormatter data_interval_seconds = (data[-1] - data[0]) / tdelta(seconds=1) interval_seconds = data_interval_seconds / max_ticks if interval_seconds < tdelta(minutes=0.5).total_seconds(): # print("xticks: seconds") unit_multiple = _next_largest(interval_seconds, INTERVALS['SECONDLY']) timedelta = tdelta(seconds=unit_multiple) return (mdates.SecondLocator(bysecond=range(0, 60, unit_multiple)), FuncFormatter( _get_dynamic_formatter(timedelta, '%M%:S', '%-Hh', '%-d %b'))) elif interval_seconds < tdelta(hours=0.5).total_seconds(): # print("xticks: minutes") unit_multiple = _next_largest( interval_seconds / tdelta(minutes=1).total_seconds(), INTERVALS['MINUTELY']) timedelta = tdelta(minutes=unit_multiple) return (mdates.MinuteLocator(byminute=range(0, 60, unit_multiple)), FuncFormatter( _get_dynamic_formatter(timedelta, '%H%:M', '%-d %b', '%Y'))) elif interval_seconds < tdelta(days=0.5).total_seconds(): # print("xticks: hours") unit_multiple = _next_largest( interval_seconds / tdelta(hours=1).total_seconds(), INTERVALS['HOURLY']) timedelta = tdelta(hours=unit_multiple) return (mdates.HourLocator(byhour=range(0, 24, unit_multiple)), FuncFormatter( _get_dynamic_formatter(timedelta, '%-Hh', '%-d %b', '%Y'))) elif interval_seconds < tdelta(days=3).total_seconds(): # print("xticks: days") unit_multiple = _next_largest( interval_seconds / tdelta(days=1).total_seconds(), INTERVALS['DAILY']) timedelta = tdelta(days=unit_multiple) return (mdates.WeekdayLocator(byweekday=range(0, 7, unit_multiple)), FuncFormatter( _get_dynamic_formatter(timedelta, '%-d', '%b', '%Y'))) elif interval_seconds < tdelta(days=14).total_seconds(): # print("xticks: weeks") unit_multiple = _next_largest( interval_seconds / tdelta(weeks=1).total_seconds(), INTERVALS['WEEKLY']) timedelta = tdelta(days=unit_multiple * 7) return (mdates.WeekdayLocator(byweekday=0, interval=unit_multiple), FuncFormatter( _get_dynamic_formatter(timedelta, '%-d', '%b', '%Y'))) elif interval_seconds < tdelta(weeks=26).total_seconds(): # print("xticks: months") unit_multiple = _next_largest( interval_seconds / tdelta(weeks=4).total_seconds(), INTERVALS['MONTHLY']) timedelta = tdelta(weeks=unit_multiple * 4) return (mdates.MonthLocator(bymonth=range(1, 13, unit_multiple)), FuncFormatter(_get_dynamic_formatter(timedelta, '%b', '%Y'))) else: # print("xticks: years") unit_multiple = _next_largest( interval_seconds / tdelta(weeks=52).total_seconds(), INTERVALS['YEARLY']) return (mdates.YearLocator(base=unit_multiple), mdates.DateFormatter('%Y'))
# But a general re-binning plotter should be used instead. aX = time['center'].array aY = freq['center'].array aZ = specDens['center'].array if specDens.propEq('scaleType','log'): clrscale = colors.LogNorm(vmin=aZ.min(), vmax=aZ.max()) else: clrscale = None (fig, ax0) = pyplot.subplots() im = ax0.pcolormesh(aX, aY, aZ, norm=clrscale, cmap='jet' ) cbar = fig.colorbar(im, ax=ax0) if freq.propEq('scaleType','log'): ax0.set_yscale('log') fig.autofmt_xdate() # Fix date formating ax0.fmt_xdata = dates.DateFormatter("%Y-%m-%dT%H:%M") # High-Res in mouse over ax0.xaxis.set_minor_locator(dates.MinuteLocator(interval=5)) # add minor ticks # Set plot labels, will use matplotlib helpers from das2 module to format labels ax0.set_xlabel(das2.mpl.range_label(time) ) ax0.set_ylabel(das2.mpl.label(freq.props['label'])) cbar.set_label(das2.mpl.label(specDens.props['label']) ) ax0.set_title(das2.mpl.label(ds.props['title']) ) pyplot.savefig('ex02_galileo_pws_spectra.png')
def plot_tog(): fig = plt.figure(figsize=(7, 10)) gss = gridspec.GridSpec(nrows=3, ncols=1, height_ratios=[1, 2,2]) ax1 = plt.subplot(gss[0]) ax2 = plt.subplot(gss[1]) ax3 = plt.subplot(gss[2], sharex=ax2) ax1.plot(gl, color='r', label='GOES 1-8$\mathrm{\AA}$') ax1.plot(gs, color='b', label='GOES 1-8$\mathrm{\AA}$') ax1.set_yscale('log') ax1.set_xlim(flare_ts, flare_te) ax1.xaxis.set_minor_locator(dates.SecondLocator(interval=10)) ax1.xaxis.set_major_locator(dates.MinuteLocator(interval=1)) ax1.legend(loc='upper right') ax1.tick_params(labelbottom=False, which='both', direction='in') ax1.set_ylabel('Flux (Wm$^{-2}$)') ax1.axvline(pul_ts, color='k') ax1.axvline(pul_te, color='k') ax2.plot(norp17, label='NoRP 17GHz', color='darkred', drawstyle='steps-mid') ax2.plot(norp9, label='NoRP 9GHz', color='darkblue', drawstyle='steps-mid') ax2.legend(loc='upper right') ax2.set_ylabel('Flux (SFU)') ax2.set_ylim(0, 200) x1 = dates.date2num(datetime.datetime.strptime(pul_ts, '%Y-%m-%d %H:%M:%S')) # start time x2 = dates.date2num(datetime.datetime.strptime(pul_te, '%Y-%m-%d %H:%M:%S')) # end time xyA = (x1, -0.01) xyB = (0.0, 1) # x and y in axes coordinates coordsA = ax1.get_xaxis_transform() # x in data coords, y in axes coords coordsB = "axes fraction" con_start = ConnectionPatch(xyA=xyA, xyB=xyB, coordsA=coordsA, coordsB=coordsB, axesA=ax1, axesB=ax2, arrowstyle="-") xyC = (x2, -0.01) xyD = (1, 1) # x and y in axes coordinates coordsC = ax1.get_xaxis_transform() # x in data coords, y in axes coords coordsD = "axes fraction" con_end = ConnectionPatch(xyA=xyC, xyB=xyD, coordsA=coordsC, coordsB=coordsD, axesA=ax1, axesB=ax2, arrowstyle="-") ax2.add_artist(con_start) ax2.add_artist(con_end) #ax3 = ax2.twinx() ax3.plot(rhessi_2535, drawstyle='steps-mid', label='RHESSI 25-35keV', color='grey', lw=0.8) ax3.plot(rhessi_35100, drawstyle='steps-mid', label='RHESSI 35-100keV', color='k', lw=0.8) ax3.legend(loc = 'upper right') ax3.set_ylabel('Counts det$^{-1}$ s$^{-1}$') ax3.set_xlabel('Time (UT) 2014-06-11') ax3.set_xlim(pul_ts, pul_te) ax2.xaxis.set_minor_locator(dates.SecondLocator(interval=10)) ax2.xaxis.set_major_locator(dates.MinuteLocator(interval=1)) ax2.xaxis.set_major_formatter(dates.DateFormatter('%H:%M:%S')) ax2.tick_params(which='both', direction='in', labelbottom=False) #ax3.xaxis.set_tick_params(rotation=45, which='both', direction='in') ax3.xaxis.set_tick_params(which='both', direction='in') plt.tight_layout() plt.subplots_adjust(hspace=0.1) plt.savefig('overview_test.png', dpi=200) plt.close()
import time import pandas as pd df = pd.read_csv('20181024.csv') today = dt.datetime.strftime(dt.datetime.now(), '%Y-%m-%d') fig, tx = plt.subplots() tx.plot_date(df['datenum'][-100:-1], df['Temperature'][-100:-1], 'b-') tx.set_xlabel('Date: %s' % today) tx.set_ylabel('Temperature (C)', color='b') tx.xaxis.set_major_formatter(md.DateFormatter('%H')) tx.xaxis.set_major_locator(md.HourLocator()) tx.xaxis.set_minor_locator(md.MinuteLocator()) tx.set_xlim() hx = tx.twinx() hx.plot(df['datenum'][-100:-1], df['Humidity'][-100:-1], 'g-') hx.set_ylabel('Humidity (%)', color='g') fig.tight_layout() plt.savefig(today + ".png") plt.show() def plot_most_recent(df, hours=12):
def plot_data(data, xs, ys, xlims, flims, xlabel, ylabel, plotname, plot_title, minutes=True, gs=False): print("\nPlotting...\n") if gs: cmap = plt.cm.Greys else: cmap = plt.cm.viridis data = np.flip(data, axis=1) if xs is None and ys is None: print("Not using summed axes!") f, ax = plt.subplots(figsize=(12, 6)) f.set_facecolor('white') im = ax.imshow( data.T, aspect='auto', origin='lower', cmap=cmap, vmin=np.nanpercentile(data.T, 5), vmax=np.nanpercentile(data.T, 90), extent=[xlims[0], xlims[1], flims[0].value, flims[1].value]) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="3%", pad=0.05) plt.colorbar(im, cax=cax) ax.xaxis_date() date_format = mdates.DateFormatter('%H:%M:%S.%f') ax.xaxis.set_major_formatter(date_format) if minutes: ax.xaxis.set_minor_locator(mdates.MinuteLocator()) f.autofmt_xdate() ax.set_title(plot_title) ax.set_ylabel(ylabel, fontsize=14) ax.set_xlabel(xlabel, fontsize=14) plt.tight_layout() plt.savefig(plotname, dpi=900) else: f = plt.figure(figsize=(12, 6)) f.set_facecolor('white') spec = gridspec.GridSpec(ncols=2, nrows=2, width_ratios=[6, 1], height_ratios=[1, 4]) ax0 = f.add_subplot(spec[0]) ax2 = f.add_subplot(spec[2]) ax3 = f.add_subplot(spec[3]) ax0.plot(xs, lw=0.5) ax0.set(xticklabels=[], xlim=[0, None]) ax0.tick_params(bottom=False) rot = transforms.Affine2D().rotate_deg(270) ax3.plot(ys[::-1], lw=0.5, transform=rot + plt.gca().transData) ax3.set(yticklabels=[]) ax3.tick_params(left=False) im = ax2.imshow( data.T, aspect='auto', origin='lower', vmin=np.nanpercentile(data.T, 5), vmax=np.nanpercentile(data.T, 90), extent=[xlims[0], xlims[1], flims[0].value, flims[1].value]) ax2.xaxis_date() date_format = mdates.DateFormatter('%H:%M:%S.%f') ax2.xaxis.set_major_formatter(date_format) if minutes: ax2.xaxis.set_minor_locator(mdates.MinuteLocator()) f.autofmt_xdate() ax2.set_title("Uranus observation - Stokes I") ax2.set_ylabel(ylabel, fontsize=14) ax2.set_xlabel(xlabel, fontsize=14) divider = make_axes_locatable(ax2) cax = divider.append_axes("right", size="3%", pad=0.05) plt.colorbar(im, cax=cax) plt.tight_layout() plt.savefig(plotname, dpi=900)
def create_plot(data, ma): temperature = [] humidity = [] pressure = [] timestamp = [] sma = {'temperature': [], 'humidity': [], 'pressure': [], 'time': []} for row in data: temperature.append(row['temperature']) humidity.append(row['humidity']) pressure.append(row['pressure']) timestamp.append(row['timestamp']) time = [datetime.fromtimestamp(t) for t in timestamp] min_time, max_time = min(time), max(time) if ma > 0: for i in range(0, len(time) - ma, ma): p_ma = sum(pressure[i:i + ma]) / ma t_ma = sum(temperature[i:i + ma]) / ma h_ma = sum(humidity[i:i + ma]) / ma sma['temperature'].append(t_ma) sma['pressure'].append(p_ma) sma['humidity'].append(h_ma) t = datetime.fromtimestamp((timestamp[i] + timestamp[i + ma]) / 2) sma['time'].append(t) hfmt = dates.DateFormatter('%m/%d %H:%M') fig, (ax1, ax2, ax3) = plt.subplots(3, sharex=True, sharey=False) fig.suptitle( 'BME280 Sensor data from %s during %s to %s' % (min_time.strftime('%d. %b. %Y'), min_time.strftime('%H:%M:%S'), max_time.strftime('%H:%M:%S'))) ax1.xaxis.set_major_locator(dates.HourLocator(interval=1)) ax1.xaxis.set_minor_locator(dates.MinuteLocator(interval=15)) ax1.xaxis.set_major_formatter(hfmt) ax1.set_xticks(np.arange(0, 24, 1)) ax1.plot(time, temperature, '--b', sma['time'], sma['temperature'], '--r') ax1.set_xlabel('Time') ax1.set_ylabel('Temperature in C') #ax1.set_xlim(min(time),max(time)) ax2.plot(time, humidity, '--b', sma['time'], sma['humidity'], '--r') ax2.set_xlabel('Time') ax2.set_ylabel('Humidity in percentage') ax3.plot(time, pressure, sma['time'], sma['pressure'], '--r') ax3.set_xlabel('Time') ax3.set_ylabel('Pressure in Pa') for ax in fig.axes: plt.sca(ax) ax.grid() if ma > 0: ax.legend(['Actual', 'SMA(%s)' % ma]) plt.xticks(rotation=45) return plt
return mean_squared_error(test['y_hat'],test['blood sugar'])**0.5 rmse_dict = {} for i in range(1,10): rmse_dict[i] = evaluate_ar_model(df_health,i) print(rmse_dict) # 3 lag model produces best outcomes # make chart showing actual blood sugar on one day. along with health data hours = dates.HourLocator(interval=4) minutes = dates.MinuteLocator(interval = 30) hours_ = dates.DateFormatter('%H:%M') day = datetime.date(2018,6,1) oneday = df_health.loc[df_health['date'].dt.date == day] oneday['time'] = oneday['date'].dt.time plt.show() fig = plt.figure() plt.title('Blood Sugar and Step Count\n6/1/2018', fontsize=22) ax1 = fig.add_subplot(111) ax1.set_ylim(0,300) ax1.plot_date(x=oneday.time, y=oneday['blood sugar'],color='blue', marker='o', label = "Blood Sugar") ax1.set_ylabel('Blood Sugar (mg/dL)', fontsize=14) ax1.set_xlabel('Time', fontsize=14) ax1.axhline(y=80,color='black') ax1.axhline(y=180,color='black') ax2 = ax1.twinx()
def plot_datasets(self, data, fname, extra_labels, showreboots=False, output='pdf'): """ Plot timeseries data (of type dataname). The data can be either simple (one or no datapoint at any point in time, or indexed (by indextype). dataname is assumed to be in the form of [title, [label1, label2, ...], [data1, data2, ...]] extra_labels is a list of tuples [(datetime, 'label'), ...] """ sar_parser = self.sar_parser title = data[0][0] unit = data[0][1] axis_labels = data[0][2] datanames = data[1] if not isinstance(datanames, list): raise Exception("plottimeseries expects a list of datanames: %s" % data) fig = plt.figure(figsize=(10.5, 6.5)) axes = fig.add_subplot(111) axes.set_title('{0} time series'.format(title), fontsize=12) axes.set_xlabel('Time') axes.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M')) # Twenty minutes. Could probably make it a parameter axes.xaxis.set_minor_locator(mdates.MinuteLocator(interval=20)) fig.autofmt_xdate() ylabel = title if unit: ylabel += " - " + unit axes.set_ylabel(ylabel) y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) axes.yaxis.set_major_formatter(y_formatter) axes.yaxis.get_major_formatter().set_scientific(False) color_norm = colors.Normalize(vmin=0, vmax=len(datanames) - 1) scalar_map = cm.ScalarMappable(norm=color_norm, cmap=plt.get_cmap('Set1')) timestamps = self.timestamps() counter = 0 for i in datanames: try: dataset = [sar_parser._data[d][i] for d in timestamps] except: print("Key {0} does not exist in this graph".format(i)) raise axes.plot(timestamps, dataset, 'o:', label=axis_labels[counter], color=scalar_map.to_rgba(counter)) counter += 1 # Draw extra_labels if extra_labels: for extra in extra_labels: axes.annotate(extra[1], xy=(mdates.date2num(extra[0]), sar_parser.find_max(extra[0], datanames)), xycoords='data', xytext=(30, 30), textcoords='offset points', arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # If we have a sosreport draw the reboots if showreboots and sar_parser.sosreport is not None and \ sar_parser.sosreport.reboots is not None: reboots = sar_parser.sosreport.reboots for reboot in reboots.keys(): reboot_date = reboots[reboot]['date'] rboot_x = mdates.date2num(reboot_date) (xmin, xmax) = plt.xlim() (ymin, ymax) = plt.ylim() if rboot_x < xmin or rboot_x > xmax: continue axes.annotate('', xy=(mdates.date2num(reboot_date), ymin), xycoords='data', xytext=(-30, -30), textcoords='offset points', arrowprops=dict(arrowstyle="->", color='blue', connectionstyle="arc3,rad=-0.1")) # Show any data collection gaps in the graph gaps = sar_parser.find_data_gaps() if len(gaps) > 0: for i in gaps: (g1, g2) = i x1 = mdates.date2num(g1) x2 = mdates.date2num(g2) (ymin, ymax) = plt.ylim() axes.add_patch( Rectangle((x1, ymin), x2 - x1, ymax - ymin, facecolor="lightgrey")) # Add a grid to the graph to ease visualization axes.grid(True) lgd = None # Draw the legend only when needed if len(datanames) > 1 or \ (len(datanames) == 1 and len(datanames[0].split('#')) > 1): # We want the legends box roughly square shaped # and not take up too much room props = matplotlib.font_manager.FontProperties(size='xx-small') if len(datanames) < LEGEND_THRESHOLD: cols = int((len(datanames)**0.5)) lgd = axes.legend(loc=1, ncol=cols, shadow=True, prop=props) else: cols = int(len(datanames)**0.6) lgd = axes.legend(loc=9, ncol=cols, bbox_to_anchor=(0.5, -0.29), shadow=True, prop=props) if len(datanames) == 0: return None try: if lgd: plt.savefig(fname, bbox_extra_artists=(lgd, ), bbox_inches='tight') else: plt.savefig(fname, bbox_inches='tight') except: import traceback print(traceback.format_exc()) import sys sys.exit(-1) plt.cla() plt.clf() plt.close('all')
def plotSpectrum(self, option=3, xtick=2, blevel=0, endpts=[False, False], cmap=cm.jet, cbar=True, cbar_ori='vertical', fontsize=14): #plot the fig fig, ax = plt.subplots(figsize=(7, 7)) if option == 1: y, x = self.imagehdu.data.shape cax = ax.imshow(self.imagehdu.data, extent=[0, x, 0, y], aspect='auto', cmap=cmap, vmin=blevel) if cbar == True: ticks = list( np.linspace( blevel, self.datamax, 10).astype('int')) #calculate 10 ticks positins if cbar_ori == 'horizontal': cbar = fig.colorbar(cax, ticks=ticks, orientation='horizontal') else: cbar = fig.colorbar(cax, ticks=ticks) cbar.set_label('Intensity', rotation=90) plt.xlabel('Row Count') plt.ylabel('Column Count') if option == 2: xstart = int(self.imageheader['CRVAL1']) xstep = float(self.imageheader['CDELT1']) xlength = int(self.imageheader['NAXIS1']) xend = xstart + xstep * xlength freqs = self.bintablehdu.data['frequency'][ 0] # these are true frequencies cax = ax.imshow(self.imagehdu.data, extent=[xstart, xend, freqs[-1], freqs[0]], aspect='auto', cmap=cmap, vmin=blevel) if cbar == True: ticks = list( np.linspace( blevel, self.datamax, 10).astype('int')) #calculate 10 ticks positins if cbar_ori == 'horizontal': cbar = fig.colorbar(cax, ticks=ticks, orientation='horizontal') else: cbar = fig.colorbar(cax, ticks=ticks) cbar.set_label('Intensity', rotation=90) if endpts[1]: #set y minorticks for first and last frequency y_lims = [freqs[-1], freqs[0]] #print(y_lims) plt.yticks(list(plt.yticks()[0]) + y_lims) plt.xlabel('Time (sec of day)') plt.ylabel('Frequency [MHz]') if option == 3: # get the start time and end time of observation start_date = utils.toDate(self.imageheader['DATE-OBS']) starttime = utils.toTime(self.imageheader['TIME-OBS']) starttime = dt.datetime.combine( start_date, starttime) # make a datetime object endtime = utils.toTime(self.imageheader['TIME-END']) endtime = dt.datetime.combine(start_date, endtime) # get the frequencies freqs = self.bintablehdu.data['frequency'][ 0] # these are true frequencies # set the limits for plotting x_lims = [starttime, endtime] x_lims = mdates.date2num(x_lims) # dates to numeric values y_lims = [freqs[-1], freqs[0]] cax = ax.imshow( self.imagehdu.data, extent=[x_lims[0], x_lims[1], y_lims[0], y_lims[1]], aspect='auto', cmap=cmap, vmin=blevel) if cbar == True: ticks = list( np.linspace( blevel, self.datamax, 10).astype('int')) #calculate 10 ticks positins if cbar_ori == 'horizontal': cbar = fig.colorbar(cax, ticks=ticks, orientation='horizontal') else: cbar = fig.colorbar(cax, ticks=ticks) cbar.set_label('Intensity', rotation=90) ax.xaxis_date() # x axis has a date data ax.xaxis.set_major_locator( mdates.MinuteLocator(byminute=range(60), interval=xtick, tz=None)) ax.xaxis.set_major_formatter(DateFormatter('%H:%M:%S')) #set ytick labels to be intigers only, in case we have a small frequency range, pyplot tends to show fraction ax.get_yaxis().get_major_formatter().set_useOffset(False) if endpts[0]: #get the start time and end time ans set ticks at those position son x-axis using minor_locator total_sec = utils.tosec(endtime - starttime) ax.xaxis.set_minor_locator( mdates.SecondLocator(bysecond=None, interval=total_sec, tz=None)) ax.xaxis.set_minor_formatter(DateFormatter('%H:%M:%S')) fig.autofmt_xdate() if endpts[1]: #set y minorticks for first and last frequency plt.yticks(list(plt.yticks()[0]) + y_lims) #ax.xaxis.set_minor_formatter(DateFormatter('%H:%M:%S')) plt.xlabel('Universal Time') plt.ylabel('Frequency [MHz]') #title = fitsfile + "\n" + imageheader['DATE-OBS'] + "::" + imageheader['TIME-OBS'] title = self.imageheader['CONTENT'] plt.title(title) #plt.show() return plt
def plotAGC(dStf: dict, dfAgc: pd.DataFrame, logger=logging.Logger): """ plots the UTM coordinates and #SVs on 4 different plots as a function of time """ cFuncName = colored(os.path.basename(__file__), 'yellow') + ' - ' + colored(sys._getframe().f_code.co_name, 'green') logger.info('{func:s}: start plotting AGC values'.format(func=cFuncName)) amutils.logHeadTailDataFrame(df=dfAgc, dfName='dfAgc', callerName=cFuncName, logger=logger) # specify the style mpl.style.use('seaborn') colors = ['tab:green', 'tab:olive', 'tab:orange', 'tab:cyan', 'tab:blue', 'tab:red', 'tab:pink', 'tab:purple', 'tab:brown', 'tab:white'] # (re)set the color iterator # colorsIter = iter(list(mcolors.TABLEAU_COLORS)) colorsIter = iter(list(colors)) fig, ax = plt.subplots(nrows=1, ncols=1, sharex=True) fig.set_size_inches(14, 10) # for setting the time on time-scale dtFormat = plot_utils.determine_datetime_ticks(startDT=dfAgc['time'].iloc[0], endDT=dfAgc['time'].iloc[-1]) # x-axis properties ax.set_xlim([dfAgc['time'].iloc[0], dfAgc['time'].iloc[-1]]) if dtFormat['minutes']: ax.xaxis.set_major_locator(dates.MinuteLocator(byminute=[0, 15, 30, 45], interval=1)) else: ax.xaxis.set_major_locator(dates.HourLocator(interval=dtFormat['hourInterval'])) # every 4 hours ax.xaxis.set_major_formatter(dates.DateFormatter('%H:%M')) # hours and minutes ax.xaxis.set_minor_locator(dates.DayLocator(interval=1)) # every day ax.xaxis.set_minor_formatter(dates.DateFormatter('\n%d-%m-%Y')) ax.xaxis.set_tick_params(rotation=0) for tick in ax.xaxis.get_major_ticks(): # tick.tick1line.set_markersize(0) # tick.tick2line.set_markersize(0) tick.label1.set_horizontalalignment('center') # get the index for the different frontends dIdx = {} # dict with indices for i, fe in enumerate(dStf['frontend']): logger.info('{func:s}: ... plotting frontend[{nr:d}], SSNID = {ssnid:d}, name = {name:s}'.format(nr=i, ssnid=fe, name=dStf['frontend'][fe]['name'], func=cFuncName)) idx = dfAgc.index[dfAgc['FrontEnd'] == fe] logger.info('{func:s}: ... indices found {idx!s} (#{len:d})'.format(idx=idx, len=len(idx), func=cFuncName)) # plot the AGC for this frontend ax.plot(dfAgc['time'].loc[idx], dfAgc['AGCGain[dB]'].loc[idx], color=next(colorsIter), linestyle='', marker='.', label=dStf['frontend'][fe]['name'], markersize=3) # name y-axis ax.set_ylabel('AGC Gain [dB]', fontsize=14) # add a legend the plot showing 2D/3D positioning displayed ax.legend(loc='best', ncol=16, markerscale=6) # title of plot title = '{syst:s}: AGC Gain [dB]'.format(syst=dStf['gnss']) fig.suptitle(title, fontsize=16) # copyright this ax.annotate(r'$\copyright$ Alain Muls ([email protected])', xy=(1, 0), xycoords='axes fraction', xytext=(0, -45), textcoords='offset pixels', horizontalalignment='right', verticalalignment='bottom', weight='strong', fontsize='medium') # Save the file in dir png pltDir = os.path.join(dStf['dir'], 'png') os.makedirs(pltDir, exist_ok=True) pltName = '{syst:s}-AGC.png'.format(syst=dStf['gnss'].replace(' ', '-')) pltName = os.path.join(pltDir, pltName) fig.savefig(pltName, dpi=100) logger.info('{func:s}: plot saved as {name:s}'.format(name=pltName, func=cFuncName)) plt.show(block=True)
def graph_candlestick(self, symbol, chooser, start=None, end=None, minutes=1, dtFormat="%H:%M", save='trade'): ''' Currently this will retrieve the data using apiChooser. Set self.preferences to limit acceptible apis. To place tx markers, set (or clear) fp.entries and fp.exits prior to calling :params symbol: The stock ticker :params chooser: APIChooser object :params start: A datetime object or time string for the begining of the graph. The day must be within the last 7 days. This may change in the future. :params end: A datetime object or time string for the end of a graph. Defaults to whatever the call gets. :params dtFormat: a strftime formt to display the dates on the x axis of the chart :parmas st: The matplot lib style for style.use(st). If fp.randomStyle is set, it overrides. ''' register_matplotlib_converters() start = pd.Timestamp(start) end = pd.Timestamp(end) if self.style: style.use(self.style) # ############### Prepare data ############## # Get the data and prepare the DtaFrames from some stock api meta, df, maDict = chooser.get_intraday(symbol, start=start, end=end, minutes=minutes) if df.empty: if not isinstance(meta, int): self.apiset.setValue('errorCode', str(meta['code'])) self.apiset.setValue('errorMessage', meta['message']) return None df['date'] = df.index if len(df.index) > self.max_candles: print(f"Your graph would have {len(df.index)} candles. Please limit the dates or increse the candle size") return None df['date'] = df['date'].map(mdates.date2num) df_ohlc = df[['date', 'open', 'high', 'low', 'close']] df_volume = df[['date', 'volume']] # ############### End Prepare data ############## # ###### PLOT and Graph ####### colup = self.chartSet.value('colorup', 'g') coldown = self.chartSet.value('colordown', 'r') ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=5, colspan=1) ax1.set_axisbelow(True) if self.gridlines[1]: ax1.grid(b=self.gridlines[0], which='major', axis=self.gridlines[1]) ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) fig = plt.gcf() fig.subplots_adjust(hspace=0) # candle width is a percentage of a day width = (minutes * 35) / (3600 * 24) candlestick_ohlc(ax1, df_ohlc.values, width, colorup=colup, colordown=coldown, alpha=.99) for date, volume, dopen, close in zip(df_volume.date.values, df_volume.volume.values, df_ohlc.open.values, df_ohlc.close.values): color = colup if close > dopen else 'k' if close == dopen else coldown ax2.bar(date, volume, width, color=color) # ###### END PLOT and Graph ####### # ###### ENTRY MARKER STUFF ####### markersize = self.chartSet.value('markersize', 90) edgec = self.chartSet.value('markeredgecolor', '#000000') alpha = float(self.chartSet.value('markeralpha', 0.5)) tz = df_ohlc.index[0].tzinfo for entry in self.entries: e = entry[3] if isinstance(e, str): e = pd.Timestamp(start.strftime('%Y-%m-%d ') + e, tzinfo=tz) else: # Currently only finnhub usess tz aware dates, and that is only after retrieving the data if e.tzinfo: e = e.tz_convert(tz) else: e = e.tz_localize(tz) # TODO: indexing the candle does not work if there is missing data e.g. a halt candleIndex = int((e - df_ohlc.index[0]).total_seconds() / 60 // minutes) if candleIndex < 0 or candleIndex > (len(df_ohlc) - 1): continue x = df_ohlc.index[candleIndex] y = entry[0] if entry[2] == 'B': facec = self.chartSet.value('markercolorup', 'g') mark = '^' else: facec = self.chartSet.value('markercolordown', 'r') mark = 'v' sc = ax1.scatter(x, y, color=facec, marker=markers.MarkerStyle( marker=mark, fillstyle='full'), s=markersize, zorder=10) sc.set_edgecolor(edgec) sc.set_alpha(alpha) # ###### END MARKER STUFF ####### # #### TICKS-and ANNOTATIONS ##### ax1.yaxis.tick_right() ax2.yaxis.tick_right() # ax1.grid(True, axis='y') plt.setp(ax1.get_xticklabels(), visible=False) for label in ax2.xaxis.get_ticklabels(): label.set_rotation(-45) label.set_fontsize(8) ax2.xaxis.set_major_formatter(mdates.DateFormatter(dtFormat)) ax2.yaxis.set_major_formatter(FuncFormatter(self.volFormat)) plt.locator_params(axis='y', tight=True, nbins=2) numcand = ((end - start).total_seconds() / 60) // minutes ax2.xaxis.set_major_locator(mdates.MinuteLocator( byminute=self.setticks(minutes, numcand))) idx = int(len(df_ohlc.date) * .39) ax1.annotate(f'{symbol} {minutes} minute', (df_ohlc.date[idx], df_ohlc.low.max()), xytext=(0.4, 0.85), textcoords='axes fraction', alpha=0.35, size=16) # annotate the data source. ax2.annotate(f'Data is from {chooser.api}', xy=(0.99, 0), xytext=(0, 10), xycoords=('axes fraction', 'figure fraction'), textcoords='offset points', size=7, ha='right', va='bottom') # #### END TICKS-and ANNOTATIONS ##### # ###### ma, ema and vwap ####### # MA1 = 9 # MA2 = 20 # MA3 = 50 # MA4 = 200 # MA5 = 'vwap' if maDict: maSetDict = getMASettings() for ma in maSetDict[0]: if ma not in maDict.keys(): continue ax1.plot(df_ohlc.date, maDict[ma], lw=1, color=maSetDict[0][ma][1], label=f'{ma}MA') if 'vwap' in maDict.keys(): ax1.plot(df_ohlc.date, maDict['vwap'], lw=1, color=maSetDict[1][0][1], label='VWAP') if self.legend: leg = ax1.legend() leg.get_frame().set_alpha(0.35) # #### Adjust margins and frame top = df_ohlc.high.max() bottom = df_ohlc.low.min() margin = (top - bottom) * .08 ax1.set_ylim(bottom=bottom - margin, top=top + (margin * 2)) ad = self.adjust plt.subplots_adjust(left=ad['left'], bottom=ad['bottom'], right=ad['right'], top=ad['top'], wspace=0.2, hspace=0) if self.chartSet.value('interactive', False, bool): # plt.savefig('out/figure_1.png') plt.show() count = 1 saveorig = save while os.path.exists(save): s, ext = os.path.splitext(saveorig) save = '{}({}){}'.format(s, count, ext) count = count + 1 fig.savefig(save) return save
def plot_flare(i): new_ts = pd.to_datetime( vlf_flares["event_starttime"].iloc[i]) - datetime.timedelta(minutes=5) new_te = pd.to_datetime( vlf_flares["event_endtime"].iloc[i]) + datetime.timedelta(minutes=5) # SID data sid_file = glob.glob( vlf_flares.iloc[i]["event_starttime"].strftime(sid_file_dir))[0] sid_data = sid_to_series(sid_file).truncate(new_ts, new_te) sid_data_db = sid_to_series(sid_file, amp=True).truncate(new_ts, new_te) # smoothing window defined in terms of cadence window_sec = (sid_data.index[1] - sid_data.index[0]).total_seconds() window = int((3 * 60) / window_sec) if window % 2 == 0: window = window + 1 sid_resample = pd.Series(savgol_filter(sid_data, int(window), 3), index=sid_data.index) sid_resample_flare = sid_resample.truncate( vlf_flares["event_starttime"].iloc[i], vlf_flares["event_endtime"].iloc[i]) sid_resample_db = pd.Series(savgol_filter(sid_data_db, int(window), 3), index=sid_data_db.index) sid_resample_flare_db = sid_resample_db.truncate( vlf_flares["event_starttime"].iloc[i], vlf_flares["event_endtime"].iloc[i]) # GOES data goes_file = glob.glob( pd.to_datetime( vlf_flares["event_starttime"].iloc[i]).strftime(goes_file_dir))[0] goes = ts.TimeSeries(goes_file).truncate(new_ts, new_te) gl = goes.to_dataframe()["xrsb"] gs = goes.to_dataframe()["xrsa"] gl_flare = gl.truncate(vlf_flares["event_starttime"].iloc[i], vlf_flares["event_endtime"].iloc[i]) gs_flare = gs.truncate(vlf_flares["event_starttime"].iloc[i], vlf_flares["event_endtime"].iloc[i]) fig, ax = plt.subplots(2, figsize=(8, 6), sharex=True) ax[0].plot(gl, color="r", label="1-8$\mathrm{\AA}$") ax[0].plot(gs, color="b", label="0.5-4$\mathrm{\AA}$") ax[0].set_ylabel("Flux (Wm$^{-2}$)") ax[0].legend(loc="upper left") ax[0].set_yscale("log") ax[1].plot(sid_data_db - sid_data_db[0], label="VLF amp", color="grey") ax[1].plot(sid_resample_flare_db - sid_resample_flare_db[0], label="Smoothed VLF amp", color="k") ax[1].legend(loc="upper left") for a in ax: a.axvline(gl_flare.index[np.argmax(gl_flare)], color="r", lw=0.4) a.axvline(gs_flare.index[np.argmax(gs_flare)], color="b", lw=0.4) a.axvline(pd.to_datetime(vlf_flares["event_starttime"].iloc[i]), ls="dashed", color="grey") a.axvline(pd.to_datetime(vlf_flares["event_endtime"].iloc[i]), ls="dashed", color="grey") a.axvline(sid_resample_flare.index[np.argmax(sid_resample_flare)], color="k", lw=0.4) tstart_str = pd.to_datetime( vlf_flares["event_starttime"].iloc[i]).strftime("%Y-%m-%dT%H:%M") ax[1].set_xlabel("Time {:s}".format( pd.to_datetime( vlf_flares["event_starttime"].iloc[i]).strftime("%Y-%m-%d %H:%M"))) ax[1].xaxis.set_major_formatter(dates.DateFormatter("%H:%M")) ax[1].set_xlim(gl.index[0], gl.index[-1]) ax[1].tick_params(which="both", direction="in") ax[0].tick_params(which="both", direction="in") ax[1].set_ylabel("VLF amplitude excess (db)") plt.tight_layout() ax[1].xaxis.set_major_locator( dates.MinuteLocator(byminute=[35, 40, 45, 50])) ax[1].xaxis.set_minor_locator(dates.MinuteLocator(interval=1)) plt.subplots_adjust(hspace=0.01) plt.savefig("./paper_plots/example_flare_ana.png", dpi=300, facecolor="w", bbox_inches="tight") plt.close()
def plot_launches(filename, type): f = open(filename, 'r') dates = [] times = [] launches = [] distances = [] for line in f: data = line.rstrip("\n").split(" ") dates.append(data[0]) launches.append(float(data[1])) times.append(float(data[2])) distance = float(data[3]) - MARS_RADIUS if distance < 0: distance = 0 distances.append(distance) f.close() min_index = np.argmin(distances) print("Minimum distance to Mars achieved:") print("\tLaunch Day:", (INITIAL_DATE + datetime.timedelta(seconds=launches[min_index]) ).strftime('%Y-%m-%d %H:%M:%S'), "(" + str(launches[min_index]) + "[s])") print("\tArrival day:", (INITIAL_DATE + datetime.timedelta(seconds=times[min_index]) ).strftime('%Y-%m-%d %H:%M:%S') + "[s]") print("\tTime of Flight:", str(times[min_index]) + "[s]") print("\tDistance to Mars:", str(distances[min_index]) + "[km]") if type == TYPE_MINUTE or type == TYPE_SECOND or type == TYPE_HOUR: date_index = 0 x_values = [] for i in range(len(launches)): sub_date = INITIAL_DATE + datetime.timedelta(seconds=launches[i]) x_values.append(sub_date) y_values = distances elif type == TYPE_DAY: x_values = [ datetime.datetime.strptime(d, "%Y-%m-%d").date() for d in dates ] y_values = distances elif type == TYPE_WEEK: x_values = [ datetime.datetime.strptime(d, "%Y-%m-%d").date() for d in dates ] y_values = distances ax = plt.gca() formatter = mdates.DateFormatter("%d-%m-%Y") ax.xaxis.set_major_formatter(formatter) locator = mdates.DayLocator() ax.xaxis.set_major_locator(locator) plt.scatter(x_values, y_values, color="red") # Removes the scientific notation on top # https://stackoverflow.com/questions/28371674/prevent-scientific-notation-in-matplotlib-pyplot ax.ticklabel_format(style='plain', axis='y') # Format the date into months & days # Change the tick interval if type == TYPE_SECOND: interval = 15 plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) plt.gca().xaxis.set_major_locator( mdates.SecondLocator(interval=interval)) plt.gca().set_ylabel("Distancia a Superficie de Marte [km]") plt.gca().set_xlabel("Fecha de Despegue [" + dates[0] + "]") elif type == TYPE_MINUTE: interval = 10 plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) plt.gca().xaxis.set_major_locator( mdates.MinuteLocator(interval=interval)) plt.gca().set_ylabel("Distancia a Superficie de Marte [km]") plt.gca().set_xlabel("Fecha de Despegue [" + dates[0] + "]") elif type == TYPE_HOUR: interval = 4 plt.gca().xaxis.set_major_formatter( mdates.DateFormatter('%m-%d %H:%M')) plt.gca().xaxis.set_major_locator( mdates.HourLocator(interval=interval)) plt.gca().set_ylabel("Distancia a Superficie de Marte [km]") plt.gca().set_xlabel("Fecha de Despegue [Año " + dates[0].split("-")[0] + "]") elif type == TYPE_DAY: interval = 2 plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%m')) plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=interval)) plt.gca().set_ylabel("Distancia a Superficie de Marte [km]") plt.gca().set_xlabel("Fecha de Despegue [Año " + dates[0].split("-")[0] + "]") elif type == TYPE_WEEK: # https://stackoverflow.com/questions/46555819/months-as-axis-ticks interval = 2 plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%Y')) plt.gca().xaxis.set_major_locator( mdates.MonthLocator(interval=interval)) plt.gca().set_ylabel("Distancia a Superficie de Marte [km]") plt.gca().set_xlabel("Fecha de Despegue") # Puts x-axis labels on an angle plt.gca().xaxis.set_tick_params(rotation=30) plt.show()
for line in f: tweet = json.loads(line) all_dates.append(tweet.get('created_at')) ones = np.ones(len(all_dates)) idx = pd.DatetimeIndex(all_dates) # the actual series (at series of 1s for the moment) my_series = pd.Series(ones, index=idx) # Resampling / bucketing into 1-minute buckets per_minute = my_series.resample('1Min').sum().fillna(0) print(my_series.head()) print(per_minute.head()) fig, ax = plt.subplots() ax.grid(True) ax.set_title("Tweet Frequencies") hours = mdates.MinuteLocator(interval=20) date_formatter = mdates.DateFormatter('%H:%M') datemin = datetime(2019, 6, 10, 15, 0) datemax = datetime(2019, 6, 19, 18, 0) ax.xaxis.set_major_locator(hours) ax.xaxis.set_major_formatter(date_formatter) ax.set_xlim(datemin, datemax) max_freq = per_minute.max() ax.set_ylim(0, max_freq) ax.plot(per_minute.index, per_minute) plt.savefig('tweet_time_series.png')
'k-', linewidth=6) ax2.set_ylim([0, 7]) cax2 = fig.colorbar(im2, ax=ax2, fraction=0.05, shrink=caxShrnk, pad=0.008) cax2.set_label('Aerosol Backscatter Coefficient\n($m^{-1}sr^{-1}$)', fontsize=caxFsz * 0.9) cax2.ax.set_yticklabels(cax2.ax.get_yticklabels(), fontsize=ctkFsz) ax2.tick_params(axis='both', which='major', labelsize=tkFsz) ax2.set_ylabel('Altitude (km)', fontsize=axFsz) ax2.set_xlabel('Time (UTC)', fontsize=axFsz) ax2.xaxis.set_major_locator( mdates.MinuteLocator(byminute=[0, 10, 20, 30, 40, 50])) ax2.xaxis.set_major_formatter(xtick_formatter) ax2.grid() # Plot aerosol extinction coefficient # im3 = ax3.pcolormesh(hsrl_time2d[hsrl_tmpStIx:hsrl_tmpEndIx,:],hsrl_gateAlt[hsrl_tmpStIx:hsrl_tmpEndIx,:]/1000, # hsrl_aerosolExtnctCoef[hsrl_tmpStIx:hsrl_tmpEndIx,:], # norm=colors.LogNorm(vmin=1e-5,vmax=1e-2), # cmap=plt.cm.nipy_spectral) # ax3.plot(hsrl_time1d[hsrl_tmpStIx:hsrl_tmpEndIx],planeAlt[hsrl_tmpStIx:hsrl_tmpEndIx]/1000, # 'k-',linewidth=6) # ax3.set_ylim([0,7]) # cax3 = fig.colorbar(im3,ax=ax3,fraction=0.05,shrink=caxShrnk,pad=0.008) # cax3.ax.set_yticklabels(cax3.ax.get_yticklabels(), fontsize=ctkFsz) # cax3.set_label('Aerosol Extinction Coefficient ($m^{-1}$)',fontsize=caxFsz*.7) # ax3.tick_params(axis='both', which='major', labelsize=tkFsz)
freq='1s') T = pd.DataFrame(T, index=pandaTimeT, columns=zVecT) # time average #Tbin = T.resample('1s').mean() Tbin = T # Cut timeseries Tbin = Tbin.loc[(Tbin.index >= XLIM[0]) & (Tbin.index <= XLIM[1])] #### --------- plots ---------- #### days = dates.DayLocator() hours6 = dates.HourLocator(interval=6) dfmt = dates.DateFormatter('%H:%M') hours1 = dates.HourLocator(interval=1) min15 = dates.MinuteLocator(interval=15) fig = plt.figure() import matplotlib.dates as mdates # For zoomed rectangle start = mdates.date2num(pd.Timestamp('2010-03-02 03:45:00')) end = mdates.date2num(pd.Timestamp('2010-03-02 05:30:00')) rect_x = [start, end, end, start, start] rect_y = [82.9, 82.9, 53.1, 53.1, 82.9] rect = zip(rect_x, rect_y) levels = np.linspace(0, 10, 41) levels2 = np.linspace(0, 10, 11) ax = plt.subplot(1, 1, 1) c = plt.contourf(Tbin.index, Tbin.columns, Tbin.T, levels, cmap=plt.cm.RdBu_r) #ct = plt.contour(Tbin.index, Tbin.columns, Tbin.T, levels2, colors='k', linewidth=0.1)
def plotHistory(self, BalanceHistory, myTrades, tradesCondensation, plotVolume=False, plotTrades=False): fig, ax = plt.subplots(sharex=True, figsize=(16, 14), nrows=4, ncols=1) #plot price ax[0].plot_date(BalanceHistory.index, BalanceHistory['close'], 'orange', marker='o', markersize=1) ax[0].yaxis.grid(True) ax[0].xaxis.grid(True) ax[0].xaxis.set_major_locator( dates.HourLocator(interval=self.HoursInterval)) ax[0].xaxis.set_major_formatter(dates.DateFormatter('\n %d-%m %H')) if self.plotmin == True: ax[0].xaxis.set_minor_locator(dates.MinuteLocator(interval=5)) ax[0].xaxis.set_minor_formatter(dates.DateFormatter('%M')) ax[0].xaxis.grid(b=True, which='minor', color='grey', linestyle='--') ax[0].set_title('CLOSE') ax[0].legend(loc='best') #plot %CH short SMA Large SMA ax[1].plot_date(BalanceHistory.index, BalanceHistory['change'], 'ro-', markersize=1) ax[1].plot_date(BalanceHistory.index, BalanceHistory['cum_change'], 'b-') ax[1].plot_date(BalanceHistory.index, BalanceHistory['SMA03_cum_change'], 'go-', markersize=1, alpha=0.6) #ligthBlue ax[1].yaxis.grid(True) ax[1].xaxis.grid(True) ax[1].xaxis.set_major_locator( dates.HourLocator(interval=self.HoursInterval)) ax[1].xaxis.set_major_formatter(dates.DateFormatter('\n %d-%m %H')) if self.plotmin == True: ax[1].xaxis.set_minor_locator(dates.MinuteLocator(interval=5)) ax[1].xaxis.set_minor_formatter(dates.DateFormatter('%M')) ax[1].xaxis.grid(b=True, which='minor', color='grey', linestyle='--') ax[1].set_title('% CHANGE - CUMULATIVE CHANGE') ax[1].legend(loc='best') ax[1].axhline(0, color='g', ls='-') #plot MarquetBalance ax[2].plot_date(BalanceHistory.index, BalanceHistory['volbuy'], 'g--', alpha=0.5) ax[2].plot_date(BalanceHistory.index, BalanceHistory['volsell'], 'r--', alpha=0.5) #ax[2].plot_date(BalanceHistory.index, BalanceHistory['unbalance'],'bo-', markersize=3) ax[2].plot_date(BalanceHistory.index, BalanceHistory['EWM_unbalance'], 'bo-', markersize=1) ax[2].plot_date(BalanceHistory.index, BalanceHistory['EWM_unbalance_N'], 'ro-', markersize=1) ax[2].yaxis.grid(True) ax[2].xaxis.grid(True) ax[2].xaxis.set_major_locator( dates.HourLocator(interval=self.HoursInterval)) ax[2].xaxis.set_major_formatter(dates.DateFormatter('\n %d-%m %H')) if self.plotmin == True: ax[2].xaxis.set_minor_locator(dates.MinuteLocator(interval=5)) ax[2].xaxis.set_minor_formatter(dates.DateFormatter('%M')) ax[2].xaxis.grid(b=True, which='minor', color='grey', linestyle='--') ax[2].set_title('volbuy - volsell- unbalance') ax[2].legend(loc='best') #ax[2].axhline(0,color='g',ls='-') # plot volumen if plotVolume == True: ax[3].plot_date(tradesCondensation.index, tradesCondensation['volb'], 'g', marker='o', markersize=3) ax[3].plot_date(tradesCondensation.index, tradesCondensation['vols'], 'r', marker='o', markersize=3) ax[3].yaxis.grid(True) ax[3].xaxis.grid(True) ax[3].xaxis.set_major_locator( dates.HourLocator(interval=self.HoursInterval)) ax[3].xaxis.set_major_formatter(dates.DateFormatter('\n %d-%m %H')) if self.plotmin == True: ax[3].xaxis.set_minor_locator(dates.MinuteLocator(interval=5)) ax[3].xaxis.set_minor_formatter(dates.DateFormatter('%M')) ax[3].xaxis.grid(b=True, which='minor', color='grey', linestyle='--') ax[3].set_title('VOLUMEN POR PERIODO') ax[3].legend(loc='best') ax[3].axhline(0, color='g', ls='-') if plotTrades == True: cont = 1 for d in myTrades.openTime: ax[1].annotate(cont, xy=(d, 1)) ax[0].axvline(d, ymin=-1.2, ymax=1, c="#05652F", linewidth=2, zorder=0, clip_on=False) ax[1].axvline(d, ymin=-1.2, ymax=1, c="#05652F", linewidth=2, zorder=0, clip_on=False) ax[2].axvline(d, ymin=-1.2, ymax=1, c="#05652F", linewidth=2, zorder=0, clip_on=False) ax[3].axvline(d, ymin=0, ymax=1, c="#05652F", linewidth=2, zorder=0, clip_on=False) cont += 1 for d in myTrades.closeTime: ax[0].axvline(d, ymin=-1.2, ymax=1, c="#ffaa80", linewidth=2, zorder=0, clip_on=False) ax[1].axvline(d, ymin=-1.2, ymax=1, c="#ffaa80", linewidth=2, zorder=0, clip_on=False) ax[2].axvline(d, ymin=-1.2, ymax=1, c="#ffaa80", linewidth=2, zorder=0, clip_on=False) ax[3].axvline(d, ymin=0, ymax=1, c="#ffaa80", linewidth=2, zorder=0, clip_on=False)
fig.set_figheight(5) fig.set_figwidth(15) c = ax.pcolormesh(time, hgt, w.transpose(), vmin=-4, vmax=4, cmap='seismic') # Format the colorbar # c.cmap.set_bad('grey', 1.0) cb = plt.colorbar(c, ax=ax) cb.set_label('vertical velocity [m/s]') # Format the limits ax.set_ylabel('Height [m]') ax.set_xlabel('Time [UTC]') ax.set_xlim(XLIM) ax.set_ylim(HGT_LIM) ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=10)) ax.xaxis.set_minor_locator(mdates.MinuteLocator()) # ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d')) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H%M')) ax.set_title('Generated: {}'.format(now.isoformat())) plt.setp(ax.xaxis.get_majorticklabels(), rotation=45) plt.tight_layout() plt.savefig(outfile) plt.savefig('../plots/stare_latest.png')
ha='center', va='top', transform=ax.transAxes, size='small') ax.text(t_range[0] + 0.0001, 0.6, 'Mooring on seafloor', size='small', ha='left') ax.annotate('', (t_range[0] + 0.006, 0.3), (t_range[0], 0.3), arrowprops=dict(facecolor='black', shrink=0.0), ha='right') # Finalize the figure # Format the time axis: tkr = dt.MinuteLocator(interval=5) frmt = dt.DateFormatter('%H:%M') ax.xaxis.set_major_locator(tkr) ax.xaxis.set_minor_locator(dt.MinuteLocator(interval=1)) ax.xaxis.set_major_formatter(frmt) ax.set_ylim([-3, 3]) # Label the axes: ax.set_ylabel('$u\,\mathrm{[m/s]}$', size='large') ax.set_xlabel('Time [June 12, 2012]') ax.set_title('Data cropping and cleaning') ax.set_xlim([ dt.date2num(dt.datetime.datetime(2012, 6, 12, 12)), dt.date2num(dt.datetime.datetime(2012, 6, 12, 12, 30)) ])
def obs_seq_TimeHeightInnov(data_dict, plotlabel=None, ptype="Prior"): fig = plt.figure(figsize=(12, 12)) fig.text( 0.68, 0.75, "\n\nInnovation Stats\nBlack Line = Innov\nBlue Line = %s Spread\nGreen = No. of Obs" % ptype, size=16, va="baseline", ha="left", multialignment="left") if plotlabel != None: fig.text(0.68, 0.68, plotlabel, size=14, va="baseline", ha="left", multialignment="left") zmin = 0.0 zmax = 10. # Decouple data_dict spread = np.ma.masked_invalid(data_dict['spread']) anal_min = np.ma.masked_invalid(data_dict['mins']) z = np.ma.masked_invalid(data_dict['hgts']) data = np.ma.masked_invalid(data_dict['bin2d']) num_obs = np.ma.masked_invalid(data_dict['num_obs']) datebins = [] minutes_from = dtime.datetime.strptime("2017-05-16_18:00:00", time_format) for min in anal_min: datebins.append(minutes_from + dtime.timedelta(0, int(min) * 60)) # 2D plot axC = plt.axes(rectC) if auto_clevels: cmin, cmax, cint, clevels = nice_clevels(-30, 30, outside=False, cint=5.0) else: clevels = np.arange(_cmin, _cmax + _cinc, _cinc) cs1 = axC.contourf(datebins, z / 1000., data, clevels, cmap=cm.get_cmap('YlOrRd')) cs2 = axC.contour(datebins, z / 1000., data, cs1.levels, colors='k') start = datebins[0].strftime("%Y%m%d%H%M%S") end = datebins[-1].strftime("%Y%m%d%H%M%S") s = dtime.datetime.strptime(start, "%Y%m%d%H%M%S") e = dtime.datetime.strptime(end, "%Y%m%d%H%M%S") axC.set_xlim(s, e) axC.set_ylim(zmin, zmax) maj_loc = mdates.MinuteLocator(interval=30) axC.xaxis.set_major_locator(maj_loc) dateFmt = mdates.DateFormatter('%H:%M') axC.xaxis.set_major_formatter(dateFmt) min_loc = mdates.MinuteLocator(interval=15) axC.xaxis.set_minor_locator(min_loc) labels = axC.get_xticklabels() plt.setp(labels, rotation=40, fontsize=10) axC.clabel(cs2, inline=1, fontsize=10, fmt="%1.1f") axC.set_ylabel("Height (km)") axC.set_xlabel("Time") # 1D time series plot axX = plt.axes(rectX) time_data = data.mean(axis=0) time_spread = spread.mean(axis=0) start = datebins[0].strftime("%Y%m%d%H%M%S") end = datebins[-1].strftime("%Y%m%d%H%M%S") s = dtime.datetime.strptime(start, "%Y%m%d%H%M%S") e = dtime.datetime.strptime(end, "%Y%m%d%H%M%S") axX.plot(datebins, time_data, lw=2.0, color='k') axX.plot(datebins, time_spread, lw=1.0, color='b') # Twin the x-axis to create a double y axis for num_obs axX2 = axX.twinx() axX2.plot(datebins, num_obs.mean(axis=0), lw=1.0, color='g') axX2.set_ylabel('No. of Obs', color='g') axX2.tick_params('y', colors='g') axX.set_xlim(s, e) axX.set_ylim(_cmin, _cmax) axX.set_xticklabels([]) axX.set_ylabel("Innovation/Spread") min_loc = mdates.MinuteLocator(interval=15) axX.xaxis.set_minor_locator(min_loc) axX.grid(True) # 1D Height Plotting Plotting axY = plt.axes(rectY) height_data = data.mean(axis=1) height_spread = spread.mean(axis=1) axY.plot(height_data, z / 1000., lw=2.0, color='k') axY.plot(height_spread, z / 1000., lw=1.0, color='b') # Twin the y-axis to create a double x axis for num_obs axY2 = axY.twiny() axY2.plot(num_obs.mean(axis=1), z / 1000., lw=1.0, color='g') axY2.set_xlabel('No. of Obs', color='g') axY2.tick_params('x', colors='g') axY.set_ylim(0.0, z.max() / 1000.) axY.set_xlim(-5., 15) axY.set_yticklabels([]) axY.set_xlabel("Innovation/Spread") # major ticks every 20, minor ticks every 5 major_ticks = np.arange(0, 16, 4) minor_ticks = np.arange(0, 16, 2) axY.set_xticks(major_ticks) axY.set_xticks(minor_ticks, minor=True) axY.grid(True)
class PdfGenerator(): hours = mdates.HourLocator() ten_minutes = mdates.MinuteLocator(byminute=range(0, 60, 10)) hours_fmt = mdates.DateFormatter('%H:00') def __init__(self, filename): self.filename = filename def start(self): log.info("Creating {}...".format(self.filename)) self.pdf = matplotlib.backends.backend_pdf.PdfPages(self.filename) return self def attendances(self, x, y_rooms, y_all, rooms): log.info("Generating attendances...") fig, ax = plt.subplots() ax.stackplot(x, y_rooms, labels=rooms) ax.legend(loc='upper left', prop={'size': 4}) ax.xaxis.set_major_locator(PdfGenerator.hours) ax.xaxis.set_major_formatter(PdfGenerator.hours_fmt) ax.xaxis.set_minor_locator(PdfGenerator.ten_minutes) ax.set_xlabel('Time (PT)') ax.set_ylabel('Attendance (Stacked)') ax.grid(True) fig.autofmt_xdate() self.pdf.savefig(fig) fig, ax = plt.subplots() ax.plot(x, y_all) ax.xaxis.set_major_locator(PdfGenerator.hours) ax.xaxis.set_major_formatter(PdfGenerator.hours_fmt) ax.xaxis.set_minor_locator(PdfGenerator.ten_minutes) ax.set_xlabel('Time (PT)') ax.set_ylabel('Attendance (All)') ax.grid(True) fig.autofmt_xdate() self.pdf.savefig(fig) for i in range(len(rooms)): fig, ax = plt.subplots() ax.plot(x, y_rooms[i]) ax.xaxis.set_major_locator(PdfGenerator.hours) ax.xaxis.set_major_formatter(PdfGenerator.hours_fmt) ax.xaxis.set_minor_locator(PdfGenerator.ten_minutes) ax.set_xlabel('Time (PT)') ax.set_ylabel("Attendance ({0})".format(rooms[i])) ax.grid(True) fig.autofmt_xdate() self.pdf.savefig(fig) return self def stay_durations(self, user_stay_durations): log.info("Generating stay durations...") longest_stay = int(max(user_stay_durations)) fig, ax = plt.subplots() ax.hist(user_stay_durations, bins=int(longest_stay/5)+1) ax.set_xlabel("Duration (minutes)") plt.xlim(left=0) ax.set_ylabel("Quantity") plt.title("Stay Durations (First to Last Sighting)") self.pdf.savefig(fig) return self def rooms_visited(self, rooms_visited, rooms): log.info("Generating rooms visited...") number_of_rooms = len(rooms) fig, ax = plt.subplots() ax.hist(rooms_visited, bins=number_of_rooms) ax.set_xlabel("Rooms Visited During Stay") plt.xlim(left=1) ax.set_ylabel("Quantity of Users") plt.title("How Many Rooms Users Visited") self.pdf.savefig(fig) return self def visit_durations(self, all_visit_durations, visit_durations, rooms): log.info("Generating visit durations...") longest_visit = int(max(all_visit_durations)) for segment in Config.SEGMENTS: fig, ax = plt.subplots() for room in rooms: if segment in visit_durations and room in visit_durations[segment]: ax.hist(visit_durations[segment][room], label=room, histtype='step', bins=longest_visit) ax.legend(loc='upper right', prop={'size': 4}) ax.set_xlabel("Duration (minutes)") plt.xlim(left=0, right=120) ax.set_ylabel("Quantity") plt.title("Visit Durations ({0})".format(segment)) self.pdf.savefig(fig) for room in rooms: fig, ax = plt.subplots() for segment in Config.SEGMENTS: if segment in visit_durations and room in visit_durations[segment]: ax.hist(visit_durations[segment][room], label=segment, histtype='step', bins=longest_visit) ax.legend(loc='upper right', prop={'size': 4}) ax.set_xlabel("Duration (minutes)") plt.xlim(left=0, right=120) ax.set_ylabel("Quantity") plt.title("Visit Durations ({0})".format(room)) self.pdf.savefig(fig) return self def moves(self, moves_list): log.info("Generating moves...") df = pd.DataFrame(moves_list, columns=['from', 'to', 'value']) fig = hv.render(hv.Sankey(moves_list, ['from', 'to'], vdims='value').opts(cmap='Dark2', edge_color='to', node_color='index')) self.pdf.savefig(fig) return self def enters(self, x, ys, rooms): log.info("Generating entrances...") fig, ax = plt.subplots() ax.stackplot(x, ys, labels=rooms) ax.legend(loc='upper left', prop={'size': 4}) ax.xaxis.set_major_locator(PdfGenerator.hours) ax.xaxis.set_major_formatter(PdfGenerator.hours_fmt) ax.xaxis.set_minor_locator(PdfGenerator.ten_minutes) ax.set_xlabel('Time (PT)') ax.set_ylabel('Users Seen For First Time (Stacked, Cumulative)') ax.grid(True) fig.autofmt_xdate() self.pdf.savefig(fig) return self def exits(self, x, ys, rooms): log.info("Generating exits...") fig, ax = plt.subplots() ax.stackplot(x, ys, labels=rooms) ax.legend(loc='upper left', prop={'size': 4}) ax.xaxis.set_major_locator(PdfGenerator.hours) ax.xaxis.set_major_formatter(PdfGenerator.hours_fmt) ax.xaxis.set_minor_locator(PdfGenerator.ten_minutes) ax.set_xlabel('Time (PT)') ax.set_ylabel('Users Seen For Last Time (Stacked, Cumulative)') ax.grid(True) fig.autofmt_xdate() self.pdf.savefig(fig) return self def finish(self): log.info("Saving...") self.pdf.close()
def create_graph(self, fname, title, metrics): '''Take a title and a list of metrics and creates an image of the graph''' fig = plt.figure(figsize=(GRAPH_SIZE[0], GRAPH_SIZE[1])) axes = fig.add_subplot(111) # Set X Axis metadata axes.set_xlabel(X_AXIS[0]) axes.set_title('{0} time series'.format(title, fontsize=X_AXIS[1])) axes.xaxis.set_major_formatter(mdates.DateFormatter(X_AXIS[2])) axes.xaxis.set_minor_locator(mdates.MinuteLocator(interval=X_AXIS[3])) fig.autofmt_xdate() # Set Y Axis metadata axes.set_ylabel(title) y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) axes.yaxis.set_major_formatter(y_formatter) axes.yaxis.get_major_formatter().set_scientific(False) found = False indoms = 0 counter = 0 # First we calculate the maximum number of colors needed max_values_len = 0 for metric in metrics: values = self.all_data[metric] if len(values) > max_values_len: max_values_len = len(values) # We need at most number of max(indoms) * metrics colors vmax_color = max_values_len * len(metrics) color_norm = colors.Normalize(vmin=0, vmax=vmax_color) scalar_map = cm.ScalarMappable(norm=color_norm, cmap=plt.get_cmap('Set1')) # Then we walk the metrics and plot for metric in metrics: values = self.all_data[metric] for indom in sorted(values): (timestamps, dataset) = values[indom] # Currently if there is only one (timestamp,value) like with filesys.blocksize # we just do not graph the thing if len(timestamps) <= 1: continue if len(metrics) > 1: if indom == 0: lbl = metric else: lbl = "%s %s" % (metric, indom) else: if indom == 0: lbl = title else: lbl = indom found = True try: axes.plot(timestamps, dataset, 'o:', label=lbl, color=scalar_map.to_rgba(counter)) except: import traceback print("Metric: {0}".format(metric)) print(traceback.format_exc()) sys.exit(-1) indoms += 1 counter += 1 if not found: return False axes.grid(True) # Add legend only when there is more than one instance lgd = False if indoms > 1: fontproperties = matplotlib.font_manager.FontProperties( size='xx-small') if indoms > LEGEND_THRESHOLD: # Draw legend on the bottom only when instances are more than LEGEND_THRESHOLD lgd = axes.legend(loc=9, ncol=int(indoms**0.6), bbox_to_anchor=(0.5, -0.29), shadow=True, prop=fontproperties) else: # Draw legend on the right when instances are more than LEGEND_THRESHOLD lgd = axes.legend(loc=1, ncol=int(indoms**0.5), shadow=True, prop=fontproperties) if lgd: plt.savefig(fname, bbox_extra_artists=(lgd, ), bbox_inches='tight') else: plt.savefig(fname, bbox_inches='tight') plt.cla() plt.clf() plt.close('all') if USE_MELIAE: objgraph.show_growth() tmp = tempfile.mkstemp(prefix='pcp-test')[1] scanner.dump_all_objects(tmp) leakreporter = loader.load(tmp) summary = leakreporter.summarize() print(summary) return True
def plotRinexObservables(dPlot: dict, obsData: xarray.Dataset, logger=logging.Logger): """ plots the observales according to the selection made each plot combines separate plots for each signalType selected for all satellites """ cFuncName = colored(os.path.basename(__file__), 'yellow') + ' - ' + colored( sys._getframe().f_code.co_name, 'green') logger.info('{func:s}: start plotting\n{plt!s}'.format(plt=dPlot, func=cFuncName)) # deterimne layout of subplots according to number of signals we have to plot dSubPlotsLayout = { 1: [1, 1], 2: [2, 1], 3: [3, 1], 4: [2, 2], 5: [3, 2], 6: [3, 3], 7: [4, 3], 8: [4, 4] } # specify the style mpl.style.use('seaborn') # find the signalType to which each signal belongs sigTypes = [] for signal in dPlot['Signals']: sigType = list( set( rnxobs.findKeyOfSignal(signal, dict(rnxobs.dGAL, **rnxobs.dGPS)))) logger.info( '{func:s}: signal = {sign!s} signal type = {sigt!s}'.format( sign=signal, sigt=sigType, func=cFuncName)) sigTypes.append(sigType) # get rid of list of lists to get 1 list flatSigTypes = [item for sublist in sigTypes for item in sublist] # get the unique signal types out of this list uniqSigTypes = list(set(flatSigTypes)) logger.info('{func:s}: plot signal types (all) = {sigt!s}'.format( sigt=flatSigTypes, func=cFuncName)) logger.info('{func:s}: plot signal types (uniq) = {sigt!s}'.format( sigt=uniqSigTypes, func=cFuncName)) # the x-axis is a time axis, set its limits tLim = [dPlot['Time']['start'], dPlot['Time']['end']] logger.info('{func:s}: time limits = {tlim!s}'.format(tlim=tLim, func=cFuncName)) # create 1 plot for each uniq signalType with subplots for each signal of that sigType we have for i, sigType in enumerate(uniqSigTypes): logger.info('{func:s}: ----------------------'.format(func=cFuncName)) logger.info( '{func:s}: making plot for signal type {name!s} ({sigt:s})'.format( sigt=sigType, name=rnxobs.dSignalTypesNames[sigType]['name'], func=cFuncName)) # count the number of signals of this type to determine # of subplots nrSubPlotsSigType = len([v for v in flatSigTypes if v == sigType]) logger.info('{func:s}: sub plots created = {nrplt!s}'.format( nrplt=nrSubPlotsSigType, func=cFuncName)) # generate the subplots and its axes nrRows = dSubPlotsLayout[nrSubPlotsSigType][0] nrCols = dSubPlotsLayout[nrSubPlotsSigType][1] logger.info( '{func:s}: plot layout - rows={row:d} columns={col:d}'.format( row=nrRows, col=nrCols, func=cFuncName)) fig, axes = plt.subplots(nrows=nrRows, ncols=nrCols, sharex='col', sharey='row') fig.set_size_inches(18.5, 10.5) logger.debug('{func:s}: axes = {ax!s}'.format(ax=axes, func=cFuncName)) # axes_list = [item for sublist in axes for item in sublist] # find indices for signals of this signalType indexSigType = [ index for index, st in enumerate(flatSigTypes) if st == sigType ] logger.info('{func:s}: index for signal type = {ist!s}'.format( ist=indexSigType, func=cFuncName)) # determine the discrete colors for SVs colormap = plt.cm.nipy_spectral # I suggest to use nipy_spectral, Set1,Paired # colormap = plt.cm.Spectral #I suggest to use nipy_spectral, Set1,Paired colors = [colormap(i) for i in np.linspace(0, 1, dPlot['#SVs'])] logger.debug('{func:s}: colors = {colors!s}'.format(colors=colors, func=cFuncName)) # create the subplots for each signal of this sigType for indexAxes, indexSignal in enumerate(indexSigType): # get the axes to plot onto logger.info( '\n{func:s}: index axis = {iax:d} index signal = {isg:d}'. format(iax=indexAxes, isg=indexSignal, func=cFuncName)) axRow, axCol = divmod(indexAxes, nrCols) logger.info( '{func:s}: axis #row = {row:d} #column = {col:d}'.format( row=axRow, col=axCol, func=cFuncName)) try: ax = axes[axRow, axCol] except IndexError as e: logger.info('{func:s}: {err!s}'.format(err=colored(e, 'red'), func=cFuncName)) ax = axes[axRow] except TypeError as e: logger.info('{func:s}: {err!s}'.format(err=colored(e, 'red'), func=cFuncName)) ax = axes # add a UE RESTREINT if (axCol == 0 and axRow == 0) or (axCol == nrCols - 1 and axRow == nrRows - 1): ax.annotate( r'$\copyright$ Alain Muls - RESTREINT UE/EU RESTRICTED', xy=(1, 1), xycoords='axes fraction', xytext=(0, 0), textcoords='offset pixels', horizontalalignment='right', verticalalignment='bottom', fontsize='large', color='red') # get the name of the signal to plot on this axis signal = dPlot['Signals'][indexSignal] # get time interval timeInterval = [ datetime.datetime.strptime(dPlot['Time']['start'], "%Y-%m-%dT%H:%M:%S"), datetime.datetime.strptime(dPlot['Time']['end'], "%Y-%m-%dT%H:%M:%S") ] logger.info( '{func:s}: Plotting signal {!s} over interval {time!s}'.format( signal, time=timeInterval, func=cFuncName)) logger.info('{func:s}: for satellites {svs!s} (#{nr:d})'.format( svs=dPlot['SVs'], nr=len(dPlot['SVs']), func=cFuncName)) for iSV, sv in enumerate(dPlot['SVs']): obsData_time = obsData.sel( time=slice(timeInterval[0], timeInterval[1])) logger.info('{func:s} ... plotting satellite {sv:s}'.format( sv=sv, func=cFuncName)) # determine color for this SV by taking the color with th eindex of SV in AllSVs list colorSV = colors[dPlot['AllSVs'].index(sv)] ax.plot(obsData_time.time, obsData_time[signal].sel(sv=sv), label='{sv:s}'.format(sv=sv), color=colorSV, marker='.', markersize=3, linestyle='') # add a legend the plot showing the satellites displayed ax.legend(loc='best', ncol=16, markerscale=6) # find name of the signal in each constellation and use this for subplot title subTitle = 'Datafile {name:s}: '.format( name=os.path.basename(dPlot['name'])) if any([sv for sv in dPlot['SVs'] if sv.startswith('E')]): subTitle += subTitleGNSS(dGNSS=rnxobs.dGAL, signal=signal, logger=logger) if any([sv for sv in dPlot['SVs'] if sv.startswith('G')]): subTitle += subTitleGNSS(dGNSS=rnxobs.dGPS, signal=signal, logger=logger) logger.info('{func:s}: plot subtitle {sub:s}'.format( sub=subTitle, func=cFuncName)) # adjust the titles for the subplots ax.set_title(subTitle, fontsize=11) # ax.set_xlabel('Time') if axCol == 0: ax.set_ylabel('{name:s} {unit:s}'.format( name=rnxobs.dSignalTypesNames[sigType]['name'], unit=rnxobs.dSignalTypesNames[sigType]['unit']), fontsize=11) if signal.startswith('S'): ax.set_ylim([20, 60]) # create the ticks for the time axis dtFormat = plot_utils.determine_datetime_ticks( startDT=timeInterval[0], endDT=timeInterval[1]) if dtFormat['minutes']: ax.xaxis.set_major_locator( dates.MinuteLocator(byminute=[0, 15, 30, 45], interval=1)) else: ax.xaxis.set_major_locator( dates.HourLocator( interval=dtFormat['hourInterval'])) # every 4 hours ax.xaxis.set_major_formatter( dates.DateFormatter('%H:%M')) # hours and minutes ax.xaxis.set_minor_locator( dates.DayLocator(interval=1)) # every day ax.xaxis.set_minor_formatter(dates.DateFormatter('\n%d-%m-%Y')) ax.xaxis.set_tick_params(rotation=0) for tick in ax.xaxis.get_major_ticks(): # tick.tick1line.set_markersize(0) # tick.tick2line.set_markersize(0) tick.label1.set_horizontalalignment('center') # set title fig.suptitle(rnxobs.dSignalTypesNames[sigType]['name'], fontsize=16) # fig.tight_layout() fig.subplots_adjust(top=0.925) # save the figure (add satellite number is total satellites in plot is < 3) baseName = os.path.basename(dPlot['name']) dirName = os.path.dirname(dPlot['name']) os.makedirs(os.path.join(dirName, 'png'), exist_ok=True) if len(dPlot['SVs']) < 4: listSVs = '-'.join(dPlot['SVs']) figName = os.path.join( dirName, 'png', '{base:s}-{name:s}-{list:s}'.format( base=baseName, name=rnxobs.dSignalTypesNames[sigType]['name'], list=listSVs)) elif dPlot['#SVs'] == len(dPlot['SVs']): listSVs = 'ALL' figName = os.path.join( dirName, 'png', '{base:s}-{name:s}-{list:s}'.format( base=baseName, name=rnxobs.dSignalTypesNames[sigType]['name'], list=listSVs)) else: figName = os.path.join( dirName, 'png', '{base:s}-{name:s}'.format( base=baseName, name=rnxobs.dSignalTypesNames[sigType]['name'])) # figName += '{start:s}'.format(start=datetime.datetime.strptime(dPlot['Time']['start'], "%Y-%m-%dT%H:%M:%S")) # figName += '{end:s}'.format(end=datetime.datetime.strptime(dPlot['Time']['end'], "%Y-%m-%dT%H:%M:%S")) tmpName = figName.replace(' ', '-') tmp2Name = tmpName.replace('.', '-') tmpName = tmp2Name.replace('_', '') figName = tmpName + '.png' fig.savefig(figName, dpi=100) logger.info('{func:s}: plot saved as {name:s}'.format(name=figName, func=cFuncName)) plt.show()
def compareEquity(sst, title, filename): #check if there's time in the index if not sst.index.to_datetime()[0].time() and not sst.index.to_datetime( )[1].time(): barSize = '1 day' else: barSize = '1 min' nrows = sst.gainAhead.shape[0] #signalCounts = sst.signals.shape[0] print '\nThere are %0.f signal counts' % nrows if 1 in sst.signals.value_counts(): print sst.signals.value_counts()[1], 'beLong Signals', if -1 in sst.signals.value_counts(): print sst.signals.value_counts()[-1], 'beShort Signals', if 0 in sst.signals.value_counts(): print sst.signals.value_counts()[0], 'beFlat Signals', # Compute cumulative equity for all days equityAllSignals = np.zeros(nrows) equityAllSignals[0] = 1 for i in range(1, nrows): equityAllSignals[i] = ( 1 + sst.gainAhead.iloc[i - 1]) * equityAllSignals[i - 1] # Compute cumulative equity for days with beLong signals equityBeLongSignals = np.zeros(nrows) equityBeLongSignals[0] = 1 for i in range(1, nrows): if (sst.signals.iloc[i - 1] > 0): equityBeLongSignals[i] = ( 1 + sst.gainAhead.iloc[i - 1]) * equityBeLongSignals[i - 1] else: equityBeLongSignals[i] = equityBeLongSignals[i - 1] # Compute cumulative equity for days with beShort signals equityBeLongAndShortSignals = np.zeros(nrows) equityBeLongAndShortSignals[0] = 1 for i in range(1, nrows): if (sst.signals.iloc[i - 1] < 0): equityBeLongAndShortSignals[i] = ( 1 + -sst.gainAhead.iloc[i - 1] ) * equityBeLongAndShortSignals[i - 1] elif (sst.signals.iloc[i - 1] > 0): equityBeLongAndShortSignals[i] = ( 1 + sst.gainAhead.iloc[i - 1]) * equityBeLongAndShortSignals[i - 1] else: equityBeLongAndShortSignals[i] = equityBeLongAndShortSignals[i - 1] # Compute cumulative equity for days with beShort signals equityBeShortSignals = np.zeros(nrows) equityBeShortSignals[0] = 1 for i in range(1, nrows): if (sst.signals.iloc[i - 1] < 0): equityBeShortSignals[i] = ( 1 + -sst.gainAhead.iloc[i - 1]) * equityBeShortSignals[i - 1] else: equityBeShortSignals[i] = equityBeShortSignals[i - 1] #plt.close('all') fig, ax = plt.subplots(1, figsize=(8, 7)) ax.plot(sst.index.to_datetime(), equityBeLongSignals, label="Long 1 Signals", color='b') ax.plot(sst.index.to_datetime(), equityBeShortSignals, label="Short -1 Signals", color='r') ax.plot(sst.index.to_datetime(), equityBeLongAndShortSignals, label="Long & Short", color='g') ax.plot(sst.index.to_datetime(), equityAllSignals, label="BuyHold", ls='--', color='c') # rotate and align the tick labels so they look better years = mdates.YearLocator() # every year months = mdates.MonthLocator() # every month days = mdates.DayLocator() # format the ticks ax.xaxis.set_major_locator(years) ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax.xaxis.set_minor_locator(months) y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) ax.yaxis.set_major_formatter(y_formatter) if barSize != '1 day' and nrows <= 1440: hours = mdates.HourLocator() minutes = mdates.MinuteLocator() # format the ticks ax.xaxis.set_major_locator(hours) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d %H")) ax.xaxis.set_minor_locator(minutes) else: hours = mdates.HourLocator() minutes = mdates.MinuteLocator() # format the ticks ax.xaxis.set_major_locator(days) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d")) ax.xaxis.set_minor_locator(hours) #ax.fmt_xdata = mdates.DateFormatter("%Y-%m-%d %H:%M") plt.title(title) plt.ylabel("TWR") plt.legend(loc="best") fig.autofmt_xdate() plt.savefig(filename) #plt.show() shortTrades, longTrades = numberZeros(sst.signals.values) allTrades = shortTrades + longTrades print '\nValidation Period from', sst.index[0], 'to', sst.index[-1] print 'TWR for Buy & Hold is %0.3f, %i days' % (equityAllSignals[nrows - 1], nrows) print 'TWR for %i beLong trades is %0.3f' % ( longTrades, equityBeLongSignals[nrows - 1]) print 'TWR for %i beShort trades is %0.3f' % ( shortTrades, equityBeShortSignals[nrows - 1]) print 'TWR for %i beLong and beShort trades is %0.3f' % ( allTrades, equityBeLongAndShortSignals[nrows - 1])
def create_plot( *, title: str, x_attr: str, y_attr: str, stats: list, additional_plots: typing.Optional[typing.Sequence[dict]] = None, legend: typing.Optional[typing.Sequence[str]] = None) -> io.BytesIO: # init_settings_for_plt() is called before if len(stats) <= 2: marker = 'o' else: marker = None x = tuple(getattr(item, x_attr) for item in stats) y = tuple(round(getattr(item, y_attr), 1) for item in stats) fig, ax = plt.subplots(figsize=( 12, 8, )) ax.plot(x, y, marker=marker) if additional_plots is not None: for additional_plot in additional_plots: x_ = tuple( getattr(item, additional_plot['x_attr']) for item in additional_plot['stats']) y_ = tuple( round(getattr(item, additional_plot['y_attr']), 1) for item in additional_plot['stats']) ax.plot(x_, y_, marker=marker) if legend is not None: ax.legend(legend) if isinstance(x[0], ( datetime.date, datetime.datetime, )): if len(x) > 1: diff = abs(x[0] - x[-1]) postfix = f'({x[0].strftime("%H:%M:%S %d.%m.%y")} - {x[-1].strftime("%H:%M:%S %d.%m.%y")})' else: diff = datetime.timedelta(seconds=1) postfix = '' if diff < datetime.timedelta(seconds=10): ax.xaxis.set_major_formatter(DateFormatter('%H:%M:%S')) ax.xaxis.set_major_locator(mdates.SecondLocator(interval=1)) plt.xlabel(f'Time {postfix}') elif diff < datetime.timedelta(minutes=20): ax.xaxis.set_major_formatter(DateFormatter('%H:%M')) ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=1)) plt.xlabel(f'Time {postfix}') elif diff <= datetime.timedelta(hours=24): ax.xaxis.set_major_formatter(DateFormatter('%H')) ax.xaxis.set_major_locator(mdates.HourLocator(interval=1)) plt.xlabel(f'Hours {postfix}') elif diff < datetime.timedelta(days=30): ax.xaxis.set_major_formatter(DateFormatter('%d')) ax.xaxis.set_major_locator(mdates.DayLocator(interval=1)) plt.xlabel(f'Days {postfix}') elif diff < datetime.timedelta(days=30 * 15): ax.xaxis.set_major_formatter(DateFormatter('%m')) ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1)) plt.xlabel(f'Months {postfix}') else: ax.xaxis.set_major_formatter(DateFormatter('%y')) ax.xaxis.set_major_locator(mdates.YearLocator()) plt.xlabel(f'Years {postfix}') else: ax.xaxis.set_major_locator(AutoLocator()) if all( isinstance(i, int) or isinstance(i, float) and i.is_integer() for i in y): ax.yaxis.set_major_locator(MaxNLocator(integer=True)) ax.set_title(title) with tempfile.TemporaryDirectory() as temp_dir_name: image_name = os.path.join(temp_dir_name, f'{title}.png') fig.savefig(image_name) fig.clear() plt.close(fig) with open(image_name, 'rb') as image: return io.BytesIO(image.read())