def sine_example(): if not os.path.exists(os.path.join('..', 'Output/')): os.mkdir(os.path.join('..', 'Output/')) # Make signals nSamples = 44100 # 1 second per each frequency sin1 = np.sin(np.linspace(0, 100 * 2 * np.pi, nSamples)) # Freq = 100 Hz sin2 = np.sin(np.linspace(0, 200 * 2 * np.pi, nSamples)) # Freq = 200 Hz sin3 = np.sin(np.linspace(0, 300 * 2 * np.pi, nSamples)) # Freq = 300 Hz sines = np.concatenate((sin1, sin2, sin3)) # load into AudioSignal object and get stft signal = nussl.AudioSignal(audio_data_array=sines) signal.stft() stft = signal.get_stft_channel(1) # Start NMF and time it start = time.time() nmf = nussl.NMF(3) activation, dictionary = nmf.run() print '{0:.3f}'.format(time.time() - start), 'sec' # plot results plt.imshow(activation, interpolation='none', aspect='auto') ax = plt.axes() ya = ax.get_yaxis() ya.set_major_locator(plt.MaxNLocator(integer=True)) xa = ax.get_xaxis() xa.set_major_locator(plt.MaxNLocator(integer=True)) plt.title('Activation Matrix (H)') plt.savefig('../Output/A.png') plt.close() plt.imshow(dictionary, interpolation='none', aspect='auto') ax = plt.axes() ya = ax.get_yaxis() ya.set_major_locator(plt.MaxNLocator(integer=True)) xa = ax.get_xaxis() xa.set_major_locator(plt.MaxNLocator(integer=True)) plt.ylim([0, 20]) plt.title('Template dictionary (W)') plt.savefig('../Output/B.png')
def plot_jobs(normalized_times_df, point_size=4, plot_step=100, ax=None): """ Plot basic history of job runtimes """ palette = sns.color_palette("hls", len(util.DEFAULT_FIELDS)) create_fig = ax is None if create_fig: fig = pylab.figure(figsize=(10, 10)) ax = fig.add_subplot(1, 1, 1) total_jobs = len(normalized_times_df) y = np.arange(len(normalized_times_df)) point_size = 8 patches = [] for f_i, field_name in enumerate(util.DEFAULT_FIELDS): ax.scatter( normalized_times_df[field_name], y, c=palette[f_i], edgecolor="none", s=point_size, alpha=0.8, ) patches.append(mpatches.Patch(color=palette[f_i], label=field_name)) ax.set_xlabel("wallclock time (sec)") ax.set_ylabel("job") legend = pylab.legend(handles=patches, loc="upper right", frameon=True) legend.get_frame().set_facecolor("#FFFFFF") ax.xaxis.set_major_locator(pylab.MaxNLocator(min_n_ticks=10)) plot_step = 100 # int(np.min([128, total_jobs/32])) y_ticks = np.arange(total_jobs // plot_step + 2) * plot_step ax.set_yticks(y_ticks) ax.set_ylim(-0.02 * total_jobs, total_jobs * 1.05) ax.set_xlim(-5, np.max(normalized_times_df["results returned"]) * 1.05) for y in y_ticks: ax.axhline(y, c="k", alpha=0.1, linewidth=1) ax.grid(False) if create_fig: fig.tight_layout() return ax
def line_box(ax, group, param, color, t=False): pivot = multi_index.loc[:, param].unstack(group) if t: pivot = pivot.T lower = pivot.quantile(0.25) upper = pivot.quantile(0.75) for i, (l,u) in enumerate(zip(lower, upper)): ax.plot([i+1, i+1], [l, u], color=lighten_color(color, 0.75), zorder=0) ax.plot(np.arange(pivot.shape[1]) + 1, pivot.median().values, '.', color=color, zorder=1) ax.yaxis.set_major_locator(plt.MaxNLocator(3)) ax.set_ylabel(param)
def plot_differenciated_stats(self, ax = None): """ Parameters ---------- ax: list of axes Returns ------- """ if isinstance(ax, type(None)): f, aa = _plt.subplots(4, sharex=True, gridspec_kw={'hspace': 0}) f.set_figheight(f.get_figheight() * 1.2) else: aa = ax a_r = aa[0] a_m = aa[1] a_c = aa[2] a_var = aa[3] # r self.pearson_r.pearson_r.plot(ax=a_r) a_r.set_ylabel('r') # m self.orthogonla_distance_regression.m.plot(ax=a_m) a_m.set_ylabel('m') # c self.orthogonla_distance_regression.c.plot(ax=a_c) a_c.set_ylabel('c') # var self.orthogonla_distance_regression['var'].plot(ax=a_var) a_var.set_ylabel('var') ##### for at in aa: at.yaxis.set_major_locator(_plt.MaxNLocator(5, prune='both')) return aa
def plot_members_degree( g, filename, limit=None, title=None, show=0): plt.clf() ax = plt.figure().gca() ambassadors_any_time_indexes = set( [ambassador.index for ambassador in g.vs.select(ambassador=True)] + [former_ambassador.index for former_ambassador in g.vs.select(former_ambassador=True)]) ambassadors_any_time_indexes = list( np.sort(np.array(list(ambassadors_any_time_indexes)))) other_members = np.delete(range(len(g.vs)), ambassadors_any_time_indexes) if limit == 'ambassadors_all_times': degrees = np.take(g.vs.degree(), ambassadors_any_time_indexes) elif limit == 'non_ambassadors': degrees = np.take(g.vs.degree(), other_members) else: degrees = g.vs.degree() plt.hist( degrees, bins=50, range=[0, max(g.vs.degree())] ) plt.xlabel('Number of connections') plt.ylabel('Member count') if title: plt.title(title) ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True)) if show: plt.show() else: plt.savefig(filename)
def box(ax, param, color): pivot = annotated_fits.pivot(index='well', columns='plate', values=param) if self.num_plates < 40: bp = ax.boxplot(pivot.values, notch=False, sym='', widths=0.65, whis=[2.5, 97.5]) plt.setp(bp['medians'], color=color, linewidth=0.75, solid_capstyle='butt') plt.setp(bp['boxes'], color=color, linewidth=0.5) plt.setp(bp['whiskers'], color=color, linewidth=0.5) plt.setp(bp['caps'], color=color, linewidth=0.5) plt.setp(bp['fliers'], color=color) else: # Just draw a line from .25 to 0.75 quartile, with dot # for median pass lower = pivot.quantile(0.25) upper = pivot.quantile(0.75) for i, (l, u) in enumerate(zip(lower, upper)): ax.plot([i + 1, i + 1], [l, u], color=lighten_color(color, 0.75), zorder=0) ax.plot(np.arange(self.num_plates) + 1, pivot.median().values, '.', color=color, zorder=1) ax.yaxis.set_major_locator(plt.MaxNLocator(3)) ax.set_ylabel(param)
def xticknum(ax, n): import matplotlib.pylab as plt ax.xaxis.set_major_locator(plt.MaxNLocator(n)) return
def make_figure(df, pa): """Generates figure. Args: df (pandas.core.frame.DataFrame): Pandas DataFrame containing the input data. pa (dict): A dictionary of the style { "argument":"value"} as outputted by `figure_defaults`. Returns: A Plotly figure """ tmp = df.copy() tmp = tmp[pa["vals"]] fig, axes = plt.subplots(1, 1, figsize=(float(pa["fig_width"]), float(pa["fig_height"]))) #Read histogram arguments and plot one histogram per column selected by user for h in pa["groups_settings"].values(): pa_ = {} if h["color_rgb"] == "" or h["color_rgb"] == "None": if h["color_value"] == "None": pa_["color_value"] = None else: pa_["color_value"] = h["color_value"] else: pa_["color_value"] = GET_COLOR(h["color_rgb"]) if h["line_rgb"] == "" or h["line_rgb"] == None: pa_["line_color"] = str(h["line_color"]) else: pa_["line_color"] = GET_COLOR(h["line_rgb"]) if (h["bins_number"] == "") or (h["bins_number"] == None): pa_["bins_number"] = h["bins_value"] else: pa_["bins_number"] = int(h["bins_number"]) if h["fill_alpha"] != pa["fill_alpha"]: pa_["fill_alpha"] = float(h["fill_alpha"]) else: pa_["fill_alpha"] = float(pa["fill_alpha"]) if h["linewidth"] != pa["linewidth"]: pa_["linewidth"] = float(h["linewidth"]) else: pa_["linewidth"] = float(pa["linewidth"]) if pa["log_scale"] == "on": pa_["log_scale"] = True else: pa_["log_scale"] = False if h["density"] == "on": pa_["density"] = True else: pa_["density"] = False if h["cumulative"] == "on": pa_["cumulative"] = True else: pa_["cumulative"] = False if pa_["line_color"] == "None": plt.hist(x=df[h["name"]].tolist(),bins=pa_["bins_number"],histtype=h["histtype_value"],orientation=h["orientation_value"],\ color=pa_["color_value"], alpha=pa_["fill_alpha"],lw=pa_["linewidth"],log=pa_["log_scale"],linestyle=h["linestyle_value"],\ cumulative=pa_["cumulative"],density=pa_["density"]) else: plt.hist(x=df[h["name"]].tolist(),bins=pa_["bins_number"],histtype=h["histtype_value"],orientation=h["orientation_value"],\ color=pa_["color_value"], alpha=pa_["fill_alpha"],lw=pa_["linewidth"],edgecolor=pa_["line_color"],log=pa_["log_scale"],\ linestyle=h["linestyle_value"],cumulative=pa_["cumulative"],density=pa_["density"]) for axis in ['top', 'bottom', 'left', 'right']: axes.spines[axis].set_linewidth(float(pa["axis_line_width"])) for axis, argv in zip(['top', 'bottom', 'left', 'right'], [ pa["upper_axis"], pa["lower_axis"], pa["left_axis"], pa["right_axis"] ]): if (argv == "on") | (argv == ".on"): axes.spines[axis].set_visible(True) else: axes.spines[axis].set_visible(False) ticks = {} for axis,argv in zip(['top','bottom','left','right'], \ [pa["tick_upper_axis"],pa["tick_lower_axis"],pa["tick_left_axis"],pa["tick_right_axis"]]): if (argv == "on") | (argv == ".on"): show = True else: show = False ticks[axis] = show axes.tick_params(right= ticks["right"],top=ticks["top"],\ left=ticks["left"], bottom=ticks["bottom"]) axes.tick_params(direction=pa["ticks_direction_value"], width=float(pa["axis_line_width"]), length=float(pa["ticks_length"])) if (pa["x_lower_limit"] != "") or (pa["x_upper_limit"] != ""): xmin, xmax = axes.get_xlim() if pa["x_lower_limit"] != "": xmin = float(pa["x_lower_limit"]) if pa["x_upper_limit"] != "": xmax = float(pa["x_upper_limit"]) plt.xlim(xmin, xmax) if (pa["y_lower_limit"] != "") or (pa["y_upper_limit"] != ""): ymin, ymax = axes.get_ylim() if pa["y_lower_limit"] != "": ymin = float(pa["y_lower_limit"]) if pa["y_upper_limit"] != "": ymax = float(pa["y_upper_limit"]) plt.ylim(xmin, ymax) if pa["maxxticks"] != "": axes.xaxis.set_major_locator(plt.MaxNLocator(int(pa["maxxticks"]))) if pa["maxyticks"] != "": axes.yaxis.set_major_locator(plt.MaxNLocator(int(pa["maxyticks"]))) plt.xlabel(pa["xlabel"], fontsize=int(pa["xlabels"])) plt.ylabel(pa["ylabel"], fontsize=int(pa["ylabels"])) plt.xticks(fontsize=float(pa["xticks_fontsize"]), rotation=float(pa["xticks_rotation"])) plt.yticks(fontsize=float(pa["yticks_fontsize"]), rotation=float(pa["yticks_rotation"])) if pa["grid_value"] != "None": if pa["grid_color_text"] != "": grid_color = GET_COLOR(pa["grid_color_text"]) else: grid_color = GET_COLOR(pa["grid_color_value"]) axes.grid(axis=pa["grid_value"], color=grid_color, linestyle=pa["grid_linestyle_value"], linewidth=float(pa["grid_linewidth"]), alpha=float(pa["grid_alpha"])) if pa["show_legend"] != "off": labels = [x["label"] for x in pa["groups_settings"].values()] facecolor = pa["facecolor"] edgecolor = pa["edgecolor"] loc = pa["legend_loc"] ncol = int(pa["legend_ncol"]) mode = pa["mode"] legend_title = pa["legend_title"] if pa["markerfirst"] == "on": markerfirst = True else: markerfirst = False if pa["fancybox"] == "on": fancybox = True else: fancybox = False if pa["shadow"] == "on": shadow = True else: shadow = False if pa["framealpha"] == "": framealpha = None else: framealpha = float(pa["framealpha"]) if pa["labelspacing"] == "": labelspacing = None else: labelspacing = float(pa["labelspacing"]) if pa["columnspacing"] == "": columnspacing = None else: columnspacing = float(pa["columnspacing"]) if pa["handletextpad"] == "": handletextpad = None else: handletextpad = float(pa["handletextpad"]) if pa["handlelength"] == "": handlelength = None else: handlelength = float(pa["handlelength"]) if pa["borderaxespad"] == "": borderaxespad = None else: borderaxespad = float(pa["borderaxespad"]) if pa["borderpad"] == "": borderpad = None else: borderpad = float(pa["borderpad"]) if pa["legend_title_fontsize_value"] != "": legend_title_fontsize = pa["legend_title_fontsize_value"] else: legend_title_fontsize = pa["legend_title_fontsize"] if pa["legend_body_fontsize_value"] != "": legend_body_fontsize = float(pa["legend_body_fontsize_value"]) else: legend_body_fontsize = pa["legend_body_fontsize"] plt.legend(labels=labels,loc=loc,ncol=ncol,fontsize=legend_body_fontsize,\ markerfirst=markerfirst,fancybox=fancybox,shadow=shadow,framealpha=framealpha, \ facecolor=facecolor, edgecolor=edgecolor,mode=mode,title=legend_title,\ title_fontsize=legend_title_fontsize,borderpad=borderpad,labelspacing=labelspacing,\ handlelength=handlelength,handletextpad=handletextpad,\ borderaxespad=borderaxespad,columnspacing=columnspacing) plt.title(pa["title"], fontsize=float(pa["title_size_value"])) plt.tight_layout() return fig
def main(): if(a00acc() != 1): print("Cannot find a valid NAG license") sys.exit(1) try: if(len(sys.argv)>1): QuoteData = sys.argv[1] else: QuoteData = 'QuoteData.dat' qd = open(QuoteData, 'r') qd_head = [] qd_head.append(qd.readline()) qd_head.append(qd.readline()) qd.close() except: sys.stderr.write("Usage: implied_volatility.py QuoteData.dat\n") sys.stderr.write("Couldn't read QuoteData") sys.exit(1) print("Implied Volatility for %s %s" % (qd_head[0].strip(), qd_head[1])) # Parse the header information in QuotaData first = qd_head[0].split(',') second = qd_head[1].split() qd_date = qd_head[1].split(',')[0] company = first[0] underlyingprice = float(first[1]) month, day = second[:2] today = cumulative_month[month] + int(day) - 30 current_year = int(second[2]) def getExpiration(x): monthday = x.split() adate = monthday[0] + ' ' + monthday[1] if adate not in dates: dates.append(adate) return (int(monthday[0]) - (current_year % 2000)) * 365 + cumulative_month[monthday[1]] def getStrike(x): monthday = x.split() return float(monthday[2]) data = pandas.io.parsers.read_csv(QuoteData, sep=',', header=2, na_values=' ') # Need to fill the NA values in dataframe data = data.fillna(0.0) # Let's look at data where there was a recent sale # data = data[data.Calls > 0] data = data[(data['Last Sale'] > 0) | (data['Last Sale.1'] > 0)] # Get the Options Expiration Date exp = data.Calls.apply(getExpiration) exp.name = 'Expiration' # Get the Strike Prices strike = data.Calls.apply(getStrike) strike.name = 'Strike' data = data.join(exp).join(strike) print('Calculating Implied Vol of Calls...') impvolcall = pandas.Series(pandas.np.zeros(len(data.index)), index=data.index, name='impvolCall') np.save(i for i in data.index: impvolcall[i] = (calcvol(data.Expiration[i], data.Strike[i], today, underlyingprice, (data.Bid[i] + data.Ask[i]) / 2, Nag_Call)) print('Calculated Implied Vol for %d Calls' % len(data.index)) data = data.join(impvolcall) print('Calculating Implied Vol of Puts...') impvolput = pandas.Series(numpy.zeros(len(data.index)), index=data.index, name='impvolPut') for i in data.index: impvolput[i] = (calcvol(data.Expiration[i], data.Strike[i], today, underlyingprice, (data['Bid.1'][i] + data['Ask.1'][i]) / 2.0, Nag_Put)) print('Calculated Implied Vol for %i Puts' % len(data.index)) data = data.join(impvolput) fig = plt.figure(1) fig.subplots_adjust(hspace=.4, wspace=.3) # Plot the Volatility Curves # Encode graph layout: 3 rows, 3 columns, 1 is first graph. num = 331 max_xticks = 4 for date in dates: # add each subplot to the figure plot_year, plot_month = date.split() plot_date = (int(plot_year) - (current_year % 2000)) * 365 + cumulative_month[plot_month] plot_call = data[(data.impvolCall > .01) & (data.impvolCall < 1) & (data.Expiration == plot_date) & (data['Last Sale'] > 0)] plot_put = data[(data.impvolPut > .01) & (data.impvolPut < 1) & (data.Expiration == plot_date) & (data['Last Sale.1'] > 0)] myfig = fig.add_subplot(num) xloc = plt.MaxNLocator(max_xticks) myfig.xaxis.set_major_locator(xloc) myfig.set_title('Expiry: %s 20%s' % (plot_month, plot_year)) myfig.plot(plot_call.Strike, plot_call.impvolCall, 'pr', label='call') myfig.plot(plot_put.Strike, plot_put.impvolPut, 'p', label='put') myfig.legend(loc=1, numpoints=1, prop={'size': 10}) myfig.set_ylim([0,1]) myfig.set_xlabel('Strike Price') myfig.set_ylabel('Implied Volatility') num += 1 plt.suptitle('Implied Volatility for %s Current Price: %s Date: %s' % (company, underlyingprice, qd_date))
def plot_rh(self, df_nsa_aotd, a): outs = [] returns = {} i = 0 for e, meas in enumerate(df_nsa_aotd.data): # test and skip bad quality values if meas.based_on_file_pops in self.inst_perform_pops.fname.values: qualtest = self.inst_perform_pops[self.inst_perform_pops.fname == meas.based_on_file_pops] if qualtest.quality.loc[0] == 'bad': print('bad quality measurement skiped ({})'.format( meas.based_on_file_pops)) continue # resample # if resample: # meas = meas.resample(datetime=resample).mean() colorbar = False values = meas.relative_humidity.to_pandas() values[values < 0] = np.nan values[values > 110] = np.nan a, lc, cm = plt_tools.plot.plot_gradiant_color( meas.time.values + np.timedelta64(self.timezone, 'h'), meas.altitude.values, values, ax=a, colorbar=colorbar) out = dict(lc=lc, cm=cm) out['mean'] = float(meas.relative_humidity.median().values) out['std'] = float(meas.relative_humidity.std().values) out['cmax'] = meas.relative_humidity.max() out['cmin'] = meas.relative_humidity.min( ) # out['mean'] - (2 * out['std']) # print(out['cmin']) out['alt_max'] = meas.altitude.max() outs.append(out) i += 1 cmax = max([out['cmax'] for out in outs]) cmin = min([out['cmin'] for out in outs]) returns['clim'] = (cmin, cmax) lcs = [out['lc'] for out in outs] # returns['zobjects'] = lcs a.zobjects = lcs for lc in lcs: lc.set_clim(cmin, cmax) lc.set_cmap(self.cm_meins) lc.set_linewidth(self.lw_pgc) a.set_ylim(-10, max([out['alt_max'] for out in outs]) * 1.2) a.xaxis.set_major_formatter(plt.DateFormatter("%H:%M:%S")) # a.set_xlabel('') f = a.get_figure() f.autofmt_xdate() a.set_ylabel('Altitude (m)') # colorbar cb, cax = plt_tools.colorbar.colorbar_axis_split_off(lc, a) cax.set_ylabel('RH (%)', labelpad=0.5) cb.locator = plt.MaxNLocator(5, prune='both') cb.update_ticks() a.cax = cax returns['a'] = a # returns['a'].cax.set_label('buba') return returns
def create_plot(self): x, y, _ = zip(*detector.doms.values()) fig, ax = plt.subplots(figsize=(10, 6)) cmap = plt.get_cmap('RdYlGn_r').copy() cmap.set_over('deeppink', 1.0) cmap.set_under('deepskyblue', 1.0) vmax = 15 * 60 scatter_args = { 'edgecolors': 'None', 's': 100, 'vmin': 0.0, 'vmax': vmax, } sc_inactive = ax.scatter( x, y, c='lightgray', label='inactive', **scatter_args ) now = tai_timestamp() try: xa, ya = map(np.array, zip(*self.rates.keys())) ts = np.array([now - max(zip(*d)[0]) for d in self.rates.values()]) except ValueError: print("Not enough data.") pass else: active_idx = ts < vmax sc_active = ax.scatter( xa[active_idx], ya[active_idx], c=ts[active_idx], cmap=cmap, **scatter_args ) ax.scatter( xa[~active_idx], ya[~active_idx], c='deeppink', label='> {0} s'.format(vmax), **scatter_args ) cb = plt.colorbar(sc_active) cb.set_label("last activity [s]") ax.set_title( "DOM Activity - via Summary Slices\n{0}".format( time.strftime("%c") ) ) ax.set_xlabel("DU") ax.set_ylabel("DOM") ax.set_ylim(-2) ax.set_yticks(range(1, N_DOMS + 1)) major_locator = pylab.MaxNLocator(integer=True) sc_inactive.axes.xaxis.set_major_locator(major_locator) ax.legend( bbox_to_anchor=(0., -.16, 1., .102), loc=1, ncol=2, mode="expand", borderaxespad=0. ) fig.tight_layout() filename = os.path.join(PLOTS_PATH, 'dom_activity.png') filename_tmp = os.path.join(PLOTS_PATH, 'dom_activity_tmp.png') plt.savefig(filename_tmp, dpi=120, bbox_inches="tight") plt.close('all') shutil.move(filename_tmp, filename)
def batch_current_future_time_analysis(batch_df): """ HIGHLY APPLICATION-SPECIFIC Takes a batches_produced dataframe, and builds a matplotlib chart, which shows a current state time analysis, a future state time analysis, and a bar chart showing batches produced per day. Exclusive to the 'main 5' comps: '3077', '3001', '3004', '1968', '1651' :param batch_df: (dataframe) A dataframe with the number of batches produced by day. Must include the 'main 5' comps. :return: No return. Displays a graph. """ # Create data points for current state time_3077_major, time_3077_minor = prod_time(batch_df['3077'], '3077') time_3001_major, time_3001_minor = prod_time(batch_df['3001'], '3001') time_3004_major, time_3004_minor = prod_time(batch_df['3004'], '3004') time_1968_major, time_1968_minor = prod_time(batch_df['1968'], '1968') time_1651_major, time_1651_minor = prod_time(batch_df['1651'], '1651') total_minor = (time_3077_minor + time_3001_minor + time_3004_minor + time_1968_minor + time_1651_minor) total_major = (time_3077_major + time_3001_major + time_3004_major + time_1968_major + time_1651_major) total_all = total_minor + total_major # Create data points for future state time_3077_major, time_3077_minor = prod_time(batch_df['3077'], '3077', find_lot=0, pull_mat=0.5, return_mat=0.5) time_3001_major, time_3001_minor = prod_time(batch_df['3001'], '3001', find_lot=0, pull_mat=0.5, return_mat=0.5) time_3004_major, time_3004_minor = prod_time(batch_df['3004'], '3004', find_lot=0, pull_mat=0.5, return_mat=0.5) time_1968_major, time_1968_minor = prod_time(batch_df['1968'], '1968', find_lot=0, pull_mat=0.5, return_mat=0.5) time_1651_major, time_1651_minor = prod_time(batch_df['1651'], '1651', find_lot=0, pull_mat=0.5, return_mat=0.5) future_total_minor = (time_3077_minor + time_3001_minor + time_3004_minor + time_1968_minor + time_1651_minor) future_total_major = (time_3077_major + time_3001_major + time_3004_major + time_1968_major + time_1651_major) future_total_all = future_total_minor + future_total_major ax1 = plt.subplot2grid((7, 1), (0, 0), rowspan=2, colspan=1) ax2 = plt.subplot2grid((7, 1), (2, 0), rowspan=3, colspan=1) ax3 = plt.subplot2grid((7, 1), (5, 0), rowspan=2, colspan=1) total_all.plot.line(ax=ax1, label='Total', ylim=(0, 12)) total_major.plot.line(ax=ax1, label='Majors', ylim=(0, 12)) total_minor.plot.line(ax=ax1, label='Minors', ylim=(0, 12)) # First subplot build (current state time analysis) ax1.fill_between(total_all.index, 6, total_all, where=(total_all > 6), facecolor='r', alpha=0.3) ax1.fill_between(total_all.index, 6, total_all, where=(total_all < 6), facecolor='g', alpha=0.3) ax1.axhline(y=6, linewidth=2, color='k') ax1.legend() ax1.xaxis.set_visible(False) ax1.set_title('Hours to Complete - Current State') ax1.set_ylabel('Time (Hours)') # Second subplot build (Batches produced Column chart) batch_df.plot.bar(ax=ax2) ax2.get_yaxis().set_major_locator(pylab.MaxNLocator(integer=True)) ax2.xaxis.set_visible(False) ax2.set_title('Batches Produced by Shift') ax2.set_ylabel('Batches') # Third subplot build (future state time analysis) future_total_all.plot.line(ax=ax3, label='Total', ylim=(0, 12)) future_total_major.plot.line(ax=ax3, label='Majors', ylim=(0, 12)) future_total_minor.plot.line(ax=ax3, label='Minors', ylim=(0, 12)) ax3.fill_between(future_total_all.index, 6, future_total_all, where=(future_total_all > 6), facecolor='r', alpha=0.3) ax3.fill_between(future_total_all.index, 6, future_total_all, where=(future_total_all < 6), facecolor='g', alpha=0.3) ax3.axhline(y=6, linewidth=2, color='k') ax3.set_title('Hours to Complete - Future State') ax3.set_ylabel('Time (Hours)') ax3.legend() # Build main plot, and show. plt.legend() plt.subplots_adjust(left=0.08, bottom=0.07, right=0.92, top=0.95, hspace=0.25) plt.show()
def plot(cls, options, matplotlib_style, historic_volatility=False, output_image=None): print('Calculating Implied Volatility for Calls...') call_iv = pd.Series(pd.np.zeros(len(options.data.index)), index=options.data.index, name='_CallImpliedVolatility') for i in options.data.index: t = options.data.Expiration[i] / 365.0 price = (options.data.CallBid[i] + options.data.CallAsk[i]) / 2.0 call_iv[i] = cls.calculate(options.underlying_price, options.data.Strike[i], t, price, flag='c') print('Calculated Implied Volatility for %d Calls' % len(options.data.index)) data = options.data.join(call_iv) print('Calculating Implied Volatility for Puts...') put_iv = pd.Series(np.zeros(len(options.data.index)), index=options.data.index, name='_PutImpliedVolatility') for i in options.data.index: t = options.data.Expiration[i] / 365.0 price = (options.data.PutBid[i] + options.data.PutAsk[i]) / 2.0 put_iv[i] = cls.calculate(options.underlying_price, options.data.Strike[i], t, price, flag='p') print('Calculated Implied Volatility for %i Puts' % len(options.data.index)) data = data.join(put_iv) mpl.style.use(matplotlib_style) fig = plt.figure(1, figsize=(16, 12)) # fig.subplots_adjust(hspace=.6, wspace=.2) # Plot the Implied Volatility curves index = 0 nrows = ncols = math.ceil(np.sqrt(len(options.plot_dates_dict))) # Add 2 extra rows for the historic volatility and price graphs if historic_volatility: nrows += 2 # Make sure we have at least 4 columns ncols = ncols if ncols >= 4 else 4 max_xticks = 5 def _enforce_fontsize(ax, fontsize=9): # Set font size for all IV chart elements for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(9) def _emphasise_text(text, style='bf'): """ Supported styles are bf for Bold and it for Italics See https://matplotlib.org/users/mathtext.html for more info """ return ' '.join( ['$\\' + style + '{' + word + '}$' for word in text.split()]) for key, value in options.plot_dates_dict.items(): index += 1 expiration = (value - options.current_time).days plot_call = data[(data._CallImpliedVolatility > .01) & (data._CallImpliedVolatility < 1) & (data.Expiration == expiration) & (data.CallLastSale > 0)] plot_put = data[(data._PutImpliedVolatility > .01) & (data._PutImpliedVolatility < 1) & (data.Expiration == expiration) & (data.PutLastSale > 0)] row = math.floor((index - 1) / ncols) ax1 = plt.subplot2grid((nrows, ncols), (row, (index - 1) % ncols), colspan=1, rowspan=1, fig=fig) xloc = plt.MaxNLocator(max_xticks) ax1.xaxis.set_major_locator(xloc) ax1.set_title('{} @ {} - {}'.format(options.symbol, options.underlying_price, _emphasise_text(key))) ax1.plot(plot_call.Strike, plot_call._CallImpliedVolatility, marker='o', color='red', markersize=3, linewidth=0, label='call') ax1.plot(plot_put.Strike, plot_put._PutImpliedVolatility, marker='o', color='blue', markersize=3, linewidth=0, label='put') ax1.legend(loc=1, numpoints=1, frameon=True, prop={'size': 10}) ax1.set_ylim([0, 1]) ax1.set_xlabel('Strike Price') ax1.set_ylabel('IV') ax1.margins(x=0) _enforce_fontsize(ax1, fontsize=9) if historic_volatility: delta = timedelta(days=365) stocks = cls.read_stock_data(options.symbol, start_date=(options.current_time - delta), end_date=options.current_time) stock = stocks[options.symbol] cls.calculate_returns(stock) years = plt.matplotlib.dates.YearLocator() months = plt.matplotlib.dates.MonthLocator() weekday = plt.matplotlib.dates.WeekdayLocator() formatter = plt.matplotlib.dates.DateFormatter('%m-%y') row = math.floor((index - 1) / ncols) + 1 colspan = math.floor(ncols / 2) ax1 = plt.subplot2grid((nrows, ncols), (row, 0), colspan=colspan, rowspan=2, fig=fig) ax1.set_title('Historical Volatility', fontsize=10) ax1.plot(stock['Volatility'], linestyle='-', linewidth=1) ax1.set_ylim([0, 1]) ax1.grid(True) ax1.xaxis.set_major_locator(months) ax1.xaxis.set_major_formatter(formatter) ax1.xaxis.set_minor_locator(weekday) ax1.margins(x=0) _enforce_fontsize(ax1, fontsize=10) ax1 = plt.subplot2grid((nrows, ncols), (row, colspan), colspan=colspan, rowspan=2, fig=fig) ax1.set_title('%s - %s @ %s for %s' % (options.symbol, options.company, options.underlying_price, options.current_time), fontsize=10) ax1.plot(stock['Close'], linestyle='-', linewidth=1) ax1.grid(True) ax1.xaxis.set_major_locator(months) ax1.xaxis.set_major_formatter(formatter) ax1.xaxis.set_minor_locator(weekday) ax1.margins(x=0) _enforce_fontsize(ax1, fontsize=10) # ax1 = plt.subplot2grid((nrows, ncols), (row + 2, 0), colspan=2, rowspan=2, fig=fig) # # KDE (Kernel Density Estimation) # stock['LinerReturn'].plot(label='KDE', ax=ax1, kind='kde') # # stock['LinerReturn'].plot(label='Histogram', ax=ax1, kind='hist', alpha=0.6, bins=100, secondary_y=True) # ax1.grid(True) # mean = stock['LinerReturn'].mean() # ax1.annotate('mean', xy=(mean, 0.008), xytext=(mean + 10, 0.010)) # # # vertical dotted line originating at mean value # ax1.axvline(mean, linestyle='--', linewidth=2, color='red') # ax1.margins(x=0) # _enforce_fontsize(ax1, fontsize=10) fig.tight_layout() if output_image: fig.savefig(cls.normalize_path(output_image), bbox_inches='tight') else: plt.show()
with open('Lscore_' + savename + '.txt', 'w') as f: for Lscore in Snapshots['Lscore']: f.write("%.8f\n" % (Lscore)) nrows = 2 ncols = 3 FONTSIZE = 20 pylab.subplots(figsize=(20, 9), nrows=nrows, ncols=ncols) PosMat = np.vstack(Snapshots['pos_trackActive']) + 1 ax1 = pylab.subplot(nrows, ncols, 1) pylab.plot( PosMat[:, :5], '.-' ) pylab.ylabel('position', fontsize=FONTSIZE) pylab.title('largest active', fontsize=FONTSIZE) ax1.get_yaxis().set_major_locator(pylab.MaxNLocator(integer=True)) BetaMat = np.vstack(Snapshots['beta_trackActive']) ax4 = pylab.subplot(nrows, ncols, 4, sharex=ax1) pylab.plot( BetaMat[:, :5], '.-' ) pylab.ylabel('beta', fontsize=FONTSIZE) nActive = len(Snapshots['activeLabels']) if nActive > 5: nSmall = nActive - 5 ax2 = pylab.subplot(nrows, ncols, 2, sharex=ax1, sharey=ax1) pylab.plot( PosMat[:, -nSmall:], '.-' ) pylab.title('smallest active', fontsize=FONTSIZE) ax2.get_yaxis().set_major_locator(pylab.MaxNLocator(integer=True)) ax5 = pylab.subplot(nrows, ncols, 5, sharex=ax4)
line = line.split(',') if line[1] not in actualvac and line[1] in dates: actualvac[line[1]] = int(line[-1]) elif line[1] in actualvac: actualvac[line[1]] = actualvac[line[1]] + int(line[-1]) print(actualvac) lists = sorted(dates.items()) # sorted by key, return a list of tuples lists1 = sorted(actualvac.items()) x, y = zip(*lists) # unpack a list of pairs into two tuples x1, y1 = zip(*lists1) print(len(x)) print(len(y1)) fig, ax = plt.subplots() ax.plot(x, y, label='Date') ax.plot(x1, y1, label='Vaccines') ax.xaxis.set_major_locator(plt.MaxNLocator(10)) ax.yaxis.set_major_locator(plt.MaxNLocator(3)) # Set up grid, legend, and limits ax.legend(frameon=False) #plt.plot(x, y) plt.show() scorelist = [] vaccinelist = [] for k, v in actualvac.items(): scorelist.append(dates[k]) vaccinelist.append(v) corr, _ = pearsonr(scorelist, vaccinelist) print('Pearsons correlation: %.3f' % corr)
def main(): if(a00acc() != 1): print "Cannot find a valid NAG license" return try: QuoteData = 'QuoteData.dat' # except IndexError: # sys.stderr.write("Usage: imp_vol.py QuotaData.dat\n") # sys.exit(1) # if os.path.isfile(QuoteData): qd = open(QuoteData, 'r') qd_head = [] qd_head.append(qd.readline()) qd_head.append(qd.readline()) qd.close() except: sys.stderr.write("Couldn't read %s" % QuoteData) print "Implied Volatility for %s %s" % (qd_head[0].strip(), qd_head[1]) # Parse the header information in QuotaData first = qd_head[0].split(',') second = qd_head[1].split() qd_date = qd_head[1].split(',')[0] company = first[0] underlyingprice = float(first[1]) month, day = second[:2] today = cumulative_month[month] + int(day) - 30 data = pandas.io.parsers.read_csv(QuoteData, sep=',', header=2, na_values=' ') # Need to fill the NA values in dataframe data = data.fillna(0.0) # Let's look at data where there was a recent sale data = data[data.Calls > 0] data = data[(data['Last Sale'] > 0) | (data['Last Sale.1'] > 0)] # Get the Options Expiration Date exp = data.Calls.apply(getexpiration) exp.name = 'Expiration' # Get the Strike Prices strike = data.Calls.apply(getstrike) strike.name = 'Strike' data = data.join(exp) data = data.join(strike) print 'Calculating Implied Vol of Calls...' impvolcall = pandas.Series(pandas.np.zeros(len(data.index)), index=data.index, name='impvolCall') for i in data.index: impvolcall[i] = (calcvol(data.Expiration[i], data.Strike[i], today, underlyingprice, (data.Bid[i] + data.Ask[i]) / 2, Nag_Call)) print 'Calculated Implied Vol for %d Calls' % len(data.index) data = data.join(impvolcall) print 'Calculating Implied Vol of Puts...' impvolput = pandas.Series(numpy.zeros(len(data.index)), index=data.index, name='impvolPut') for i in data.index: impvolput[i] = (calcvol(data.Expiration[i], data.Strike[i], today, underlyingprice, (data['Bid.1'][i] + data['Ask.1'][i]) / 2.0, Nag_Put)) print 'Calculated Implied Vol for %i Puts' % len(data.index) data = data.join(impvolput) fig = plt.figure(1) fig.subplots_adjust(hspace=.4, wspace=.3) # Plot the Volatility Curves # Encode graph layout: 3 rows, 3 columns, 1 is first graph. num = 331 max_xticks = 4 for date in dates: # add each subplot to the figure plot_year, plot_month = date.split() plot_date = (int(plot_year) - 13) * 365 + cumulative_month[plot_month] plot_call = data[(data.impvolCall > .01) & (data.impvolCall < 1) & (data.Expiration == plot_date) & (data['Last Sale'] > 0)] plot_put = data[(data.impvolPut > .01) & (data.impvolPut < 1) & (data.Expiration == plot_date) & (data['Last Sale.1'] > 0)] myfig = fig.add_subplot(num) xloc = plt.MaxNLocator(max_xticks) myfig.xaxis.set_major_locator(xloc) myfig.set_title('Expiry: %s 20%s' % (plot_month, plot_year)) myfig.plot(plot_call.Strike, plot_call.impvolCall, 'pr', label='call') myfig.plot(plot_put.Strike, plot_put.impvolPut, 'p', label='put') myfig.legend(loc=1, numpoints=1, prop={'size': 10}) myfig.set_ylim([0,1]) myfig.set_xlabel('Strike Price') myfig.set_ylabel('Implied Volatility') num += 1 plt.suptitle('Implied Volatility for %s Current Price: %s Date: %s' % (company, underlyingprice, qd_date)) print "\nPlotting Volatility Curves/Surface" """ The code below will plot the Volatility Surface It uses e02ca to fit with a polynomial and e02cb to evalute at intermediate points """ m = numpy.empty(len(dates), dtype=get_nag_int_type()) y = numpy.empty(len(dates), dtype=numpy.double) xmin = numpy.empty(len(dates), dtype=numpy.double) xmax = numpy.empty(len(dates), dtype=numpy.double) data = data.sort('Strike') # Need to sort for NAG Algorithm k = 3 # this is the degree of polynomial for x-axis (Strike Price) l = 3 # this is the degree of polynomial for y-axis (Expiration Date) i = 0 for date in dates: plot_year, plot_month = date.split() plot_date = (int(plot_year) - 13) * 365 + cumulative_month[plot_month] call_data = data[(data.Expiration == plot_date) & (data.impvolPut > .01) & (data.impvolPut < 1) & (data['Last Sale.1'] > 0)] exp_sizes = call_data.Expiration.size if(exp_sizes > 0): m[i] = exp_sizes n = len(dates) if(i == 0): x = call_data.Strike call = call_data.impvolPut xmin[0] = x.min() xmax[0] = x.max() else: x2 = call_data.Strike x = x.append(x2) call2 = call_data.impvolPut call = call.append(call2) xmin[i] = x2.min() xmax[i] = x2.max() y[i] = plot_date-today i+=1 nux = numpy.zeros(1,dtype=numpy.double) nuy = numpy.zeros(1,dtype=numpy.double) inux = 1 inuy = 1 if(len(dates) != i): print "Error with data: the CBOE may not be open for trading or one expiration date has null data" return 0 weight = numpy.ones(call.size, dtype=numpy.double) output_coef = (c_double * ((k + 1) * (l + 1)))(0.0) # To input data into NAG function we convert variables to ctypes mx = m.ctypes.data_as(POINTER(get_ctype())) xx = x.ctypes.data_as(POINTER(c_double)) yx = y.ctypes.data_as(POINTER(c_double)) callx = call.ctypes.data_as(POINTER(c_double)) weightx = weight.ctypes.data_as(POINTER(c_double)) xminx = xmin.ctypes.data_as(POINTER(c_double)) xmaxx = xmax.ctypes.data_as(POINTER(c_double)) nuxx = nux.ctypes.data_as(POINTER(c_double)) nuyx = nuy.ctypes.data_as(POINTER(c_double)) fail = NagError() #Call the NAG Chebyshev fitting function e02cac(mx,n,k,l,xx,yx,callx,weightx,output_coef,xminx,xmaxx,nuxx,inux,nuyx,inuy,fail) if(fail.code != 0): print fail.message return 0 """ Now that we have fit the function, we use e02cb to evaluate at different strikes/expirations """ nStrikes = 100 # number of Strikes to evaluate spacing = 20 # number of Expirations to evaluate for i in range(spacing): mfirst = 1 mlast = nStrikes xmin = data.Strike.min() xmax = data.Strike.max() x = numpy.linspace(xmin, xmax, nStrikes) ymin = data.Expiration.min() - today ymax = data.Expiration.max() - today y = (ymin) + i * numpy.floor((ymax - ymin) / spacing) xx = x.ctypes.data_as(POINTER(c_double)) fx=(c_double * nStrikes)(0.0) fail=NagError() e02cbc(mfirst,mlast,k,l,xx,xmin,xmax,y,ymin,ymax,fx,output_coef,fail) if(fail.code != 0): print fail.message if 'xaxis' in locals(): xaxis = numpy.append(xaxis, x) temp = numpy.empty(len(x)) temp.fill(y) yaxis = numpy.append(yaxis, temp) for j in range(len(x)): zaxis.append(fx[j]) else: xaxis = x yaxis = numpy.empty(len(x), dtype=numpy.double) yaxis.fill(y) zaxis = [] for j in range(len(x)): zaxis.append(fx[j]) fig = plt.figure(2) ax = fig.add_subplot(111, projection='3d') ax.plot_trisurf(xaxis, yaxis, zaxis, cmap=cm.jet) ax.set_xlabel('Strike Price') ax.set_ylabel('Days to Expiration') ax.set_zlabel('Implied Volatility for Put Options') plt.suptitle('Implied Volatility Surface for %s Current Price: %s Date: %s' % (company, underlyingprice, qd_date)) plt.show()
return listt maxYOrderOfTen = 5 myLogAxesList = makeLogAxesLabels(0, maxYOrderOfTen) ax.plot_wireframe(X, np.log10(Y), Nentry, linewidth=0.5, rstride=5, cstride=125, color=color) ax.yaxis.set_major_formatter(LogFormatter()) ax.yaxis.set_major_locator(plt.MaxNLocator(maxYOrderOfTen)) ax.set_yticklabels(myLogAxesList) pos = ax.get_position() pos.x0 = pos.x0 - 0.01 pos.x1 = pos.x1 - 0.01 ax.set_position(pos) ax.set_ylabel(r"Concentration ($\mu$M)") ax.set_xlabel('Voltage (mV)') ax.set_zlabel('Entry Rate (molecules/s)') ax.tick_params(axis='both') axarr[1, 3].axis('off') #============================================================================= #=========================== Final print statements ==========================
def plot_dom_parameters( data, detector, filename, label, title, vmin=0.0, vmax=10.0, cmap="cividis", under="deepskyblue", over="deeppink", underfactor=1.0, overfactor=1.0, missing="lightgray", hide_limits=False, ): """Creates a plot in the classical monitoring.km3net.de style. Parameters ---------- data: dict((du, floor) -> value) detector: km3pipe.hardware.Detector() instance filename: filename or filepath label: str title: str underfactor: a scale factor for the points used for underflow values overfactor: a scale factor for the points used for overflow values hide_limits: do not show under/overflows in the plot """ x, y, _ = zip(*detector.doms.values()) fig, ax = plt.subplots(figsize=(10, 6)) cmap = plt.get_cmap(cmap).copy() cmap.set_over(over, 1.0) cmap.set_under(under, 1.0) m_size = 100 scatter_args = { "edgecolors": "None", "vmin": vmin, "vmax": vmax, } sc_inactive = ax.scatter(x, y, c=missing, label="missing", s=m_size * 0.9, **scatter_args) xa, ya = map(np.array, zip(*data.keys())) zs = np.array(list(data.values())) in_range_idx = np.logical_and(zs >= vmin, zs <= vmax) sc = ax.scatter(xa[in_range_idx], ya[in_range_idx], c=zs[in_range_idx], cmap=cmap, s=m_size, **scatter_args) if not hide_limits: under_idx = zs < vmin ax.scatter(xa[under_idx], ya[under_idx], c=under, label="< {0}".format(vmin), s=m_size * underfactor, **scatter_args) over_idx = zs > vmax ax.scatter(xa[over_idx], ya[over_idx], c=over, label="> {0}".format(vmax), s=m_size * overfactor, **scatter_args) cb = plt.colorbar(sc) cb.set_label(label) ax.set_title("{0}\n{1} UTC".format(title, datetime.utcnow().strftime("%c"))) ax.set_xlabel("DU") ax.set_ylabel("DOM") ax.set_ylim(-2) ax.set_yticks(range(1, 18 + 1)) major_locator = pylab.MaxNLocator(integer=True) sc_inactive.axes.xaxis.set_major_locator(major_locator) ax.legend( bbox_to_anchor=(0.0, -0.16, 1.0, 0.102), loc=1, ncol=2, mode="expand", borderaxespad=0.0, ) fig.tight_layout() plt.savefig(filename, dpi=120, bbox_inches="tight") plt.close("all")
# ######################################################################### # Read the time and displacement times = finput["time"][:] sigma_zz_ = sigma_zz - upU_p # kinetic energy ax.plot(times, sigma_zz_, 'r', linewidth=2, label=r'''Effective Stress $\sigma^{\prime}$''') ax.hold(True) max_yticks = 5 yloc = plt.MaxNLocator(max_yticks) ax.yaxis.set_major_locator(yloc) max_xticks = 5 yloc = plt.MaxNLocator(max_xticks) ax.xaxis.set_major_locator(yloc) ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.35), ncol=2, fancybox=True, shadow=True, prop={'size': 24}) pylab.savefig( "Coupled_Soft_Contact_Steady_State_SF_Ststem_Under_Compression_Porosity_Effective_Stress_Principle.pdf",
def plot_pops_NC(self, df_nsa_aotd, a, resample='1min'): outs = [] returns = {} i = 0 for e, meas in enumerate(df_nsa_aotd.data): # test and skip bad quality values if meas.based_on_file_pops in self.inst_perform_pops.fname.values: qualtest = self.inst_perform_pops[self.inst_perform_pops.fname == meas.based_on_file_pops] if qualtest.quality.loc[0] == 'bad': self.send_message( 'bad quality measurement skiped ({})'.format( meas.based_on_file_pops)) continue # if resample: # meas = meas.resample(datetime=resample).mean() colorbar = False a, lc, cm = plt_tools.plot.plot_gradiant_color( meas.time.values + np.timedelta64(self.timezone, 'h'), meas.altitude.values, meas.pops_particle_number_concentration.values, ax=a, colorbar=colorbar) out = dict(lc=lc, cm=cm) out['mean'] = float( meas.pops_particle_number_concentration.median().values) out['std'] = float( meas.pops_particle_number_concentration.std().values) # out['cmax'] = out['mean'] + (1 * out['std']) # meast = meas.resample(datetime = '10min').mean() # trying to get rid of those plumes close to the ground meast = meas.copy(deep=True) meast.pops_particle_number_concentration[ meast.altitude < 20] = np.nan meast.pops_particle_number_concentration[np.isnan( meast.altitude)] = np.nan out['cmax'] = meast.pops_particle_number_concentration.max() out['cmin'] = meast.pops_particle_number_concentration.min() out['alt_max'] = meas.altitude.max() outs.append(out) i += 1 cmax = max([out['cmax'] for out in outs]) cmin = min([out['cmin'] for out in outs]) returns['clim'] = (cmin, cmax) lcs = [out['lc'] for out in outs] # returns['zobjects'] = lcs a.zobjects = lcs for lc in lcs: lc.set_clim(cmin, cmax) # lc.set_clim(0,25) lc.set_cmap(self.cm_meins) lc.set_linewidth(self.lw_pgc) a.set_ylim(-10, max([out['alt_max'] for out in outs]) * 1.2) a.xaxis.set_major_formatter(plt.DateFormatter("%H:%M:%S")) # a.set_xlabel('') f = a.get_figure() f.autofmt_xdate() a.set_ylabel('Altitude (m)') # colorbar cb, cax = plt_tools.colorbar.colorbar_axis_split_off(lc, a) # self.lc = lc # self.cb, self.cax = cb, cax a.cax = cax cb.locator = plt.MaxNLocator(5, prune='both') cb.update_ticks() cax.set_ylabel('NC$_{POPS}$ (#/cm$^3$)', labelpad=0.5) returns['a'] = a return returns