def plot_superposed_symh(ax, df_turn=None, stable_interval=30, IMF_turning="northward"): """ Superimposes SymH for IMF turnings Parameters ---------- stable_interval : minutes The interval length before or after the turning """ if df_turn is None: df_turn = build_event_database(IMF_turning=IMF_turning, event_status="good") #df_turn = df_turn.tail() dbdir = "../data/sqlite3/" table_name = "symh" db_name = "gmi_imf.sqlite" # make a connection conn = sqlite3.connect(dbdir + db_name, detect_types=sqlite3.PARSE_DECLTYPES) cur = conn.cursor() dtms = pd.to_datetime(df_turn.datetime.unique()) for dtm in dtms: # Add the lag time tmp_var = df_turn.loc[df_turn.datetime == dtm, :] lag_time = tmp_var.lag_time.iloc[0] dtm = dtm + dt.timedelta(seconds=60. * lag_time) # load data to a dataframe stm = dtm - dt.timedelta(seconds=60. * stable_interval) etm = dtm + dt.timedelta(seconds=60. * stable_interval) command = "SELECT symh, datetime FROM {tb} " + \ "WHERE datetime BETWEEN '{stm}' AND '{etm}' " command = command.format(tb=table_name, stm=stm, etm=etm) df = pd.read_sql(command, conn) dtms_tmp = pd.to_datetime(df.datetime) df.loc[:, "relative_time"] = [(x - dtm).total_seconds() / 60. for x in dtms_tmp] ax.plot(df.relative_time, df.loc[:, "symh"]) ax.axvline(x=0, color="r", linestyle="--", linewidth=1.) #ax.legend() return
def build_superposed_master_table(output_table, df_events=None, half_interval_length=75, imf_lagtime=15, ftype="fitacf", coords="mlt", dbdir="../data/sqlite3/", input_dbname=None, output_dbname=None): """ combines all the gridded data (NOT median filtered) into one master table to do superposed epoch analysis. The results are stored in a different db file. Parameters ---------- output_table : str A table name from output_dbname ftype : str SuperDARN file type coords : str Coordinates in which the binning process took place. Default to "mlt, can be "geo" as well. input_dbname : str, default to None Name of the sqlite db where xxx-min median data are stored. output_dbname : str, default to None Name of the master db Returns ------- Nothing """ # create db name if input_dbname is None: input_dbname = "sd_gridded_los_data_" + ftype + ".sqlite" if output_dbname is None: output_dbname = "sd_master_" + coords + "_" + ftype + ".sqlite" if df_events is None: df_events = build_event_database(IMF_turning="all", event_status="all") # make a db connection try: conn_in = sqlite3.connect(dbdir + input_dbname, detect_types=sqlite3.PARSE_DECLTYPES) cur_in = conn_in.cursor() except Exception, e: logging.error(e, exc_info=True)
ax.axvline(x=0, color="r", linestyle="--", linewidth=1.) #ax.legend() return if __name__ == "__main__": fig, ax = plt.subplots() imf_comp = "By" IMF_turning = "southward" #IMF_turning = "northward" event_status = "good" stable_interval = 30 df_events = build_event_database(IMF_turning=IMF_turning, event_status=event_status) nevents = len(df_events.datetime.unique()) plot_superposed_imf(ax, imf_comp=imf_comp, df_turn=df_events, stable_interval=stable_interval, IMF_turning=IMF_turning) ax.set_ylim([-12, 12]) ax.set_xlabel("Time [min]") ax.set_ylabel("IMF " + imf_comp + " [nT]") ax.set_title( str(nevents) + " " + IMF_turning.capitalize() + " IMF Turnings") fig_dir = "/home/muhammad/Dropbox/tmp/tmp/" #fig_dir = "../plots/superposed_imf/"
params = ["Bz", "au", "al", "ae", "symh"] ylim_imf=[-12, 12] ylim_au=[-50, 500]; ylim_al=[-500, 50] ylim_ae = [-50, 800]; ylim_symh = [-80, 30] ylims = [ylim_imf, ylim_au, ylim_al, ylim_ae, ylim_symh] IMF_turning = "southward" #IMF_turning = "northward" event_status = "good" #rads = "all" rads = ["wal", "bks", "fhe", "fhw", "cve", "cvw"] geomag_condition="quiet" stable_interval=30 df_events = build_event_database(IMF_turning=IMF_turning, event_status=event_status, geomag_condition=geomag_condition, rads=rads) nevents = len(df_events.datetime.unique()) fig, axes = plt.subplots(nrows=len(params), ncols=1, sharex=True, figsize=(5,10)) fig.subplots_adjust(hspace=0.1) if len(params) == 1: axes = [axes] for i, param in enumerate(params): ax = axes[i] if param == "Bz": plot_superposed_imf(ax, imf_comp=param, df_turn=df_events, stable_interval=stable_interval, IMF_turning=IMF_turning, color="r") elif param == "symh": plot_superposed_symh(ax, df_turn=df_events, stable_interval=stable_interval, IMF_turning=IMF_turning, color="orange") else:
def main(master_table=True, superposed_master_table=False, master_summary_table=True): # input parameters ftype = "fitacf" coords = "mlt" filtered_interval = 2. dbdir = "../data/sqlite3/" input_dbname = "sd_" + str(int(filtered_interval)) + "_min_median_" +\ coords + "_" + ftype + ".sqlite" output_dbname = "sd_master_" + coords + "_" + ftype + ".sqlite" input_table_1 = "all_radars" output_table_1 = "master_all_radars" input_table_2 = "master_all_radars" output_table_2 = "master_summary_all_radars" IMF_turning = "northward" #IMF_turning = "southward" event_status = "good" output_table = "master_superposed_epoch_" + IMF_turning imf_lagtime = 15 half_interval_length = 60 # create a log file to which any error occured will be written. logging.basicConfig(filename="./log_files/superposed_master_table" + ".log", level=logging.INFO) if master_table: # build a master table print "building a master table" build_master_table(input_table_1, output_table_1, ftype=ftype, coords=coords, dbdir=dbdir, input_dbname=input_dbname, output_dbname=output_dbname) print "A master table has been built" if superposed_master_table: df_events = build_event_database(IMF_turning=IMF_turning, event_status=event_status) build_superposed_master_table( output_table, df_events=df_events, half_interval_length=half_interval_length, imf_lagtime=imf_lagtime, ftype=ftype, coords=coords, dbdir=dbdir, input_dbname=None, output_dbname=None) if master_summary_table: # build a summary table print "building a master_summary table" master_summary(input_table_2, output_table_2, coords=coords, dbdir=dbdir, db_name=output_dbname) print "A master_summary has been built" return
def superpose_poes_aur_bnd(axes, df_turn=None, IMF_turning="northward", plot_type="mlat_vs_mlt", raw_fdir="../data/poes/raw/", bnd_fdir="../data/poes/raw/", coords="mlt", read_bnd_from_file=True, file_source="bharat"): """Superposes POES determined auroral boundary""" from poes import get_aur_bnd if df_turn is None: df_turn = build_event_database(IMF_turning=IMF_turning, event_status="good") imf_dtms = pd.to_datetime(df_turn.datetime.unique()) del_time = 30 # approximate relative time from the flow response time. Used to get the real relative time turning_txt = ["Before Turning", "After Turning"] for imf_dtm in imf_dtms: print(imf_dtm) # Get the lag time in flow response tmp_var = df_turn.loc[df_turn.datetime == imf_dtm, :] lag_time = tmp_var.lag_time.iloc[0] for i, reltime_sign in enumerate([-1, 1]): ax = axes[i] # Find an appropriate datetime for POES sd_dtm = imf_dtm + dt.timedelta(seconds=60. * lag_time) if reltime_sign == -1: if (sd_dtm.minute % del_time) == 0: reltime = (-1) * del_time else: reltime = (-1) * (sd_dtm.minute % del_time) elif reltime_sign == 1: reltime = del_time - (sd_dtm.minute % del_time) poes_dtm = sd_dtm + dt.timedelta(seconds=60. * reltime) selTime = poes_dtm # two ways to overlay estimated boundary! # Fast way if read_bnd_from_file: if file_source == "bharat": inpFileName = bnd_fdir + "poes-fit-" + selTime.strftime( "%Y%m%d") + ".txt" try: print "reading boundary data from-->", inpFileName colTypeDict = { "MLAT" : np.float64, "MLON" : np.float64,\ "date":np.str, "time":np.str } estBndDF = pd.read_csv(inpFileName, delim_whitespace=True,\ dtype=colTypeDict) # get the selected time estBndDF = estBndDF[ ( estBndDF["date"] == selTime.strftime("%Y%m%d") ) &\ ( estBndDF["time"] == selTime.strftime("%H%M") )\ ].reset_index(drop=True) except IOError: print(inpFileName + " does not exist.") pass # Slow way else: poesRdObj = get_aur_bnd.PoesAur() ( poesAllEleDataDF, poesAllProDataDF ) = poesRdObj.read_poes_data_files(\ poesRawDate=selTime,\ poesRawDir=raw_fdir ) aurPassDF = poesRdObj.get_closest_sat_passes( poesAllEleDataDF,\ poesAllProDataDF, [selTime, selTime] ) # determine auroral boundaries from all the POES satellites # at a given time. eqBndLocsDF = poesRdObj.get_nth_ele_eq_bnd_locs( aurPassDF,\ poesAllEleDataDF ) estBndDF = poesRdObj.fit_circle_aurbnd(eqBndLocsDF, save_to_file=False) # convert to MLT coords if needed if not estBndDF.empty: if coords == "mlt": estBndDF["selTime"] = selTime estBndDF["MLT"] = estBndDF.apply(get_mlt, axis=1) else: pass # Plot fitted Aur. Bnd. if plot_type == "mlat_vs_mlt": xs = [ x if x < 12 else x - 24 for x in estBndDF.MLT.tolist() ] ys = estBndDF.MLAT xs = xs[:-1] ys = ys[:-1] ax.plot(xs, ys, marker="o", markersize=2, linewidth=1.5) if plot_type == "fitted_circle": phi = np.deg2rad(estBndDF.MLT.as_matrix() * 15. - 90) rd = 90. - np.abs(estBndDF.MLAT.as_matrix()) xs, ys = pol2cart(phi, rd) ax.plot(xs, ys, marker="o", markersize=2, linewidth=1.) else: print("No Data") if plot_type == "mlat_vs_mlt": for j, ax in enumerate(axes): # Set x-lim ax.set_xlim([-6, 6]) ax.set_ylim([50, 75]) ax.axhline(y=58, color="k", linestyle="--", linewidth=1.0) # Set titles, labels ax.set_title(turning_txt[j]) ax.set_xlabel("MLT") axes[0].set_ylabel("MLAT") # Make it like a polar plot if plot_type == "fitted_circle": lat_min = 50. for j, ax in enumerate(axes): rmax = 90. - lat_min ax.set_xlim([-rmax, rmax]) ax.set_ylim([-rmax, rmax]) ax.set_aspect("equal") # remove tikcs ax.tick_params(axis='both', which='both', bottom='off', top='off', left="off", right="off", labelbottom='off', labelleft='off') # plot the latitudinal circles for r in [10, 30, 50]: c = plt.Circle((0, 0), radius=r, fill=False, linewidth=0.5) ax.add_patch(c) # plot the longitudinal lines #for l in np.deg2rad(np.array([210, 240, 270, 300, 330])): for l in np.deg2rad(np.arange(0, 360, 30)): x1, y1 = pol2cart(l, 10) x2, y2 = pol2cart(l, 50) ax.plot([x1, x2], [y1, y2], 'k', linewidth=0.5) fnts = "large" ax.annotate("80", xy=(0, 10), ha="left", va="bottom", fontsize=fnts) ax.annotate("70", xy=(0, 20), ha="left", va="bottom", fontsize=fnts) ax.annotate("60", xy=(0, 30), ha="left", va="bottom", fontsize=fnts) # add mlt labels ax.annotate("0", xy=(0, -rmax), xytext=(0, -rmax - 1), ha="center", va="top", fontsize=fnts) ax.annotate("6", xy=(rmax, 0), xytext=(rmax + 5, 0), ha="left", va="center", fontsize=fnts) ax.annotate("12", xy=(rmax, rmax), xytext=(0, rmax + 4), ha="center", va="top", fontsize=fnts) ax.annotate("18", xy=(-rmax, 0), xytext=(-rmax - 5, 0), ha="right", va="center", fontsize=fnts) # Set title ax.set_title(turning_txt[j], fontsize="x-large") ttl = ax.title ttl.set_position([0.5, 1.07]) return
y = rho * np.sin(phi) return (x, y) if __name__ == "__main__": raw_fdir = "../data/poes/raw/" bnd_fdir = "../data/poes/bnd/" IMF_turning = "northward" #IMF_turning="southward" read_bnd_from_file = True coords = "mlt" #plot_type="mlat_vs_mlt" plot_type = "fitted_circle" df_turn = build_event_database(IMF_turning=IMF_turning, event_status="good") #df_turn = df_turn.head(30) nevents = len(df_turn.datetime.unique()) # Superpose Auroral Boundaries in MLAT vs MLT format if plot_type == "mlat_vs_mlt": figsize = (12, 5) fig, axes = plt.subplots(nrows=1, ncols=2, figsize=figsize, sharey=True) if plot_type == "fitted_circle": figsize = (12, 5) fig, axes = plt.subplots(nrows=1, ncols=2, figsize=figsize,
def plot_superposed_aualae(ax, param="au", df_turn=None, stable_interval=30, ylim_au=[0, 500], ylim_al=[-500, 0], IMF_turning="northward"): """ Superimposes AU, AL, AE for IMF turnings Parameters ---------- stable_interval : minutes The interval length before or after the turning """ if df_turn is None: df_turn = build_event_database(IMF_turning=IMF_turning, event_status="good") #df_turn = df_turn.tail() dbdir = "../data/sqlite3/" table_name = "aualae" db_name = "gmi_imf.sqlite" # make a connection conn = sqlite3.connect(dbdir + db_name, detect_types=sqlite3.PARSE_DECLTYPES) cur = conn.cursor() color_dict = {"AU": "k", "AL": "g", "AE": "r"} dtms = pd.to_datetime(df_turn.datetime.unique()) for dtm in dtms: # Add the lag time tmp_var = df_turn.loc[df_turn.datetime == dtm, :] lag_time = tmp_var.lag_time.iloc[0] dtm = dtm + dt.timedelta(seconds=60. * lag_time) # load data to a dataframe stm = dtm - dt.timedelta(seconds=60. * stable_interval) etm = dtm + dt.timedelta(seconds=60. * stable_interval) command = "SELECT au, al, ae, datetime FROM {tb} " + \ "WHERE datetime BETWEEN '{stm}' AND '{etm}' " command = command.format(tb=table_name, stm=stm, etm=etm) df = pd.read_sql(command, conn) dtms_tmp = pd.to_datetime(df.datetime) df.loc[:, "relative_time"] = [(x - dtm).total_seconds() / 60. for x in dtms_tmp] ax.plot(df.relative_time, df.loc[:, param], color=color_dict[param.upper()]) ax.axvline(x=0, color="r", linestyle="--", linewidth=1.) ax.set_ylim([ylim_al[0], ylim_au[1]]) ax.locator_params(axis='y', nbins=6) # Add label # ax.annotate(param.upper(), xytext=(0.9, 0.9), # color=color_dict[param.upper()], textcoords="axes fraction") xy_dict = {"AU": (0.85, 0.7), "AL": (0.85, 0.25), "AE": (0.85, 0.8)} ax.annotate(param.upper(), xy=xy_dict[param.upper()], color=color_dict[param.upper()], xycoords="axes fraction", fontsize=15) return
def plot_rti(ax, event_dtm, rad, bmnum=7, lag_time=None, mag_bmazm=None, stable_interval=30, ftype="fitacf", mag_latc_range=[53, 65], vel_maxlim=500, cmap="jet", norm=None, scatter_plot=True, IMF_turning="southward", db_name=None, dbdir="../data/sqlite3/"): """ Makes an range-time plot of a radar beam for certain IMF turning period Parameters ---------- stable_interval : minutes The interval length before or after the IMF turning """ if lag_time is None: # Create event list df_turn_tmp = build_event_database(IMF_turning=IMF_turning) df_turn_tmp = df_turn_tmp.loc[df_turn_tmp.datetime == event_dtm, :] # Find the convection respond time lag_time = df_turn_tmp.lag_time.iloc[0] event_dtm = event_dtm + dt.timedelta(seconds=60. * lag_time) # Construct stm and etm stm = event_dtm - dt.timedelta(seconds=60. * stable_interval) etm = event_dtm + dt.timedelta(seconds=60. * stable_interval) if db_name is None: db_name = "sd_gridded_los_data" + "_" + ftype + ".sqlite" # make a connection conn = sqlite3.connect(dbdir + db_name, detect_types=sqlite3.PARSE_DECLTYPES) if bmnum is None: if mag_bmazm is None: mag_bmazm = 30 # Find bmnum that corresponds to mag_bmazm bmnum = find_bmnum(rad, stm, etm, mag_bmazm=mag_bmazm, bmazm_diff=3., db_name=db_name, dbdir=dbdir) ccoll = None if bmnum is not None: # load data to a dataframe command = "SELECT vel, mag_latc, rad_mlt, bmnum, frang, nrang, rsep, slist, datetime " +\ "FROM {tb} " + \ "WHERE datetime BETWEEN '{stm}' AND '{etm}' "+\ "AND bmnum={bmnum} ORDER BY datetime" command = command.format(tb=rad, stm=stm, etm=etm, bmnum=bmnum) df = pd.read_sql(command, conn) if not df.empty: if scatter_plot: xs = [] ys = [] cs = [] else: xs = np.zeros(2 * len(df.datetime)) # For geo or mag coords, get radar FOV lats/lons. rmax = df.nrang.max() fov_dtm = pd.to_datetime(df.datetime.tolist()[0]) rsep = df.rsep.unique().tolist()[0] frang = df.frang.unique().tolist()[0] site = pydarn.radar.network().getRadarByCode(rad) \ .getSiteByDate(fov_dtm) myFov = pydarn.radar.radFov.fov(site=site, ngates=rmax, nbeams=site.maxbeam, rsep=rsep, frang=frang, coords="mag", coord_alt=300., date_time=fov_dtm) ys = myFov.latFull[bmnum] cs = np.ones((len(xs), len(ys))) * np.nan # fov_dtm = df.datetime.unique().tolist() # rsep = df.rsep.unique().tolist() # # check whether site parameters has changed within the interval of interest # if len(fov_dtm) <= 1: # fov_dtm = fov_dtm[0] # rsep = rsep[0] # site = pydarn.radar.network().getRadarByCode(rad) \ # .getSiteByDate(fov_dtm) # myFov = pydarn.radar.radFov.fov(site=site, ngates=rmax, # nbeams=site.maxbeam, # rsep=rsep, coords="mag", # date_time=fov_dtm) # ys = myFov.latFull[bmnum] # cs = np.ones((len(xs), len(ys))) * np.nan # # else: # print("WARNING: more than one site/fov exist") # print("Setting scatter_plot to True") # scatter_plot = True # xs = [] # ys = [] # cs = [] tcnt = 0 for i, rw in df.iterrows(): vl = json.loads(rw.vel) lat = json.loads(rw.mag_latc) slst = json.loads(rw.slist) dtm_tmp = pd.to_datetime(rw.datetime) relative_time = (dtm_tmp - event_dtm).total_seconds() / 60. if scatter_plot: # Select data between the mag_latc_range vels_tmp = np.array([vl[i] for i in range(len(vl))\ if (lat[i] >= mag_latc_range[0] and lat[i] <= mag_latc_range[1])]) lats_tmp = np.array([lat[i] for i in range(len(lat))\ if (lat[i] >= mag_latc_range[0] and lat[i] <= mag_latc_range[1])]) xs.extend([relative_time] * len(lats_tmp)) ys.extend(lats_tmp) cs.extend(vels_tmp) else: # Build a list of datetimes to plot each data point at. xs[tcnt] = relative_time # if(i < len(df) - 1): # dtm_tmp_next = pd.to_datetime(df.iloc[i+1, :].datetime) # relative_time_next = (dtm_tmp_next-event_dtm).total_seconds()/60. # if(relative_time_next - xs[tcnt] > 4.): # tcnt += 1 # # hardcoded 1 minute step per data point # # but only if time between data points is > 4 minutes # xs[tcnt] = xs[tcnt - 1] + 1. # for j in range(len(slst)): # cs[tcnt][slst[j]] = vl[j] # tcnt += 1 for j in range(len(slst)): cs[tcnt][slst[j]] = vl[j] if (i < len(df) - 1): dtm_tmp_next = pd.to_datetime(df.iloc[i + 1, :].datetime) relative_time_next = (dtm_tmp_next - event_dtm).total_seconds() / 60. if (relative_time_next - xs[tcnt] > 4.): tcnt += 1 # hardcoded 1 minute step per data point # but only if time between data points is > 4 minutes xs[tcnt] = xs[tcnt - 1] + 1. tcnt += 1 # Plot the data if scatter_plot: ccoll = ax.scatter(xs, ys, s=4.0, zorder=1, marker="s", c=cs, linewidths=.5, edgecolors='face', cmap=cmap, norm=norm) else: # Remove np.nan in ys if np.sum(np.isnan(ys)) > 0: idx = np.where(np.isnan(ys))[0][0] X, Y = np.meshgrid(xs[:tcnt], ys[:idx]) Z = np.ma.masked_where(np.isnan(cs[:tcnt, :idx].T), cs[:tcnt, :idx].T) else: X, Y = np.meshgrid(xs[:tcnt], ys) Z = np.ma.masked_where(np.isnan(cs[:tcnt, :].T), cs[:tcnt, :].T) ccoll = ax.pcolormesh(X, Y, Z, edgecolor=None, cmap=cmap, norm=norm) # Annotate the starting MLT location of the radar rad_mlt_loc = round( df.rad_mlt.as_matrix()[0] / 15. + stable_interval / 60., 1) % 24 #lbl = rad + ",b" + str(bmnum) + "\nMLT=" + str(rad_mlt_loc) + "\nlag=" + str(lag_time) + "min" lbl = "Beam " + str(bmnum) ax.annotate(lbl, xy=(0.85, 0.82), xycoords="axes fraction", fontsize=8) ax.set_ylabel("MLAT", fontsize=9) ax.set_ylim([mag_latc_range[0], mag_latc_range[1]]) ax.axvline(x=0, color="r", linestyle="--", linewidth=1.) # Close conn conn.close() return ccoll
def main(): import datetime as dt import matplotlib.pyplot as plt import matplotlib as mpl # input parameters nvel_min = 20 lat_range = [54, 60] lat_min = 50 reltime_resolution = 2 mlt_width = 2. mlt_range = [-6, 6] gazmc_span_minlim = 30 vel_mag_err_maxlim = 0.2 vel_mag_maxlim = 200. fit_by_bmazm = False # Not implemented yet fit_by_losvel_azm = True ftype = "fitacf" coords = "mlt" #weighting = None weighting = "std" dbdir = "../data/sqlite3/" #IMF_turning = "southward" IMF_turning = "northward" input_table = "master_cosfit_superposed_" + IMF_turning + "_mltwidth_" + str(int(mlt_width)) +\ "_res_" + str(reltime_resolution) + "min" # cmap and bounds for color bar color_list = ['purple', 'b', 'c', 'g', 'y', 'r'] cmap = mpl.colors.ListedColormap(color_list) bounds = range(0, 180, 30) bounds.append(10000) # build a custom color map norm = mpl.colors.BoundaryNorm(bounds, cmap.N) #relative_times = [-30, -20, -10, -6, 0, 6, 10, 20, 30] relative_times = [-20, -10, -6, 0, 10, 20] #fig_dir = "../plots/convection/" fig_dir = "/home/muhammad/Dropbox/tmp/convection/" fig_name = "3_by_2_superposed_convection_" + IMF_turning + "_lat" + str(lat_range[0]) +\ "_to_lat" + str(lat_range[1]) +\ "_mltwidth_" + str(int(mlt_width)) +\ "_res_" + str(reltime_resolution) + "min" + \ "_nvel_min_" + str(nvel_min) + "velmag_err_" + str(vel_mag_err_maxlim) # create subplots #fig, axes = plt.subplots(nrows=len(relative_times)/3, ncols=3, figsize=(8,6)) fig, axes = plt.subplots(nrows=len(relative_times) / 3, ncols=3, figsize=(8, 4)) fig.subplots_adjust(hspace=-0.2) #fig.subplots_adjust(hspace=0.3) if len(relative_times) == 1: axes = [axes] else: axes = axes.flatten().tolist() for i, relative_time in enumerate(relative_times): # fetches the data from db data_dict = fetch_data(input_table, lat_range=lat_range, nvel_min=nvel_min, relative_time=relative_time, reltime_resolution=reltime_resolution, mlt_width=mlt_width, mlt_range=mlt_range, gazmc_span_minlim=gazmc_span_minlim, fit_by_bmazm=fit_by_bmazm, fit_by_losvel_azm=fit_by_losvel_azm, vel_mag_maxlim=vel_mag_maxlim, vel_mag_err_maxlim=vel_mag_err_maxlim, ftype=ftype, coords=coords, dbdir=dbdir, db_name=None, weighting=weighting) # plot the flow vectors title = "Time = " + str(relative_time) coll = vector_plot(axes[i], data_dict, cmap=cmap, norm=norm, velscl=10, lat_min=lat_min, title=title) # add colorbar fig.subplots_adjust(right=0.85) cbar_ax = fig.add_axes([0.90, 0.25, 0.02, 0.5]) add_cbar(fig, coll, bounds, cax=cbar_ax, label="Speed [m/s]") # Set a figure title df_turn = build_event_database(IMF_turning=IMF_turning, event_status="good") nevents = len(df_turn.datetime.unique()) fig_title = str( nevents) + " IMF " + IMF_turning.capitalize() + " Turning Events" fig.suptitle(fig_title, y=0.90, fontsize=15) # save the fig fig.savefig(fig_dir + fig_name + ".png", dpi=300, bbox_inches="tight") plt.close(fig) #plt.show() return