def test_max_iter_large(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, max_iter=300)
def test_access_a_specific_label(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) arrow_tips = [3.3, 3.3, 3.3, 3.4, 3.5, 3.4, 3.3] box_loc = [4.3, 4.3, 4.3, 4.4, 4.5, 4.4, 4.3] lineid_plot.plot_line_ids( wave, flux, line_wave, line_label1, arrow_tip=arrow_tips, box_loc=box_loc, ax=ax) a = ax.findobj(mpl.text.Annotation) for i in a: if i.get_label() == "Si II_num_4": i.set_visible(False) a = ax.findobj(mpl.lines.Line2D) for i in a: if i.get_label() == "Si II_num_4_line": i.set_visible(False)
def test_access_a_specific_label(): """User can access each box and line using label.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) arrow_tips = [3.3, 3.3, 3.3, 3.4, 3.5, 3.4, 3.3] box_loc = [4.3, 4.3, 4.3, 4.4, 4.5, 4.4, 4.3] lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=arrow_tips, box_loc=box_loc, ax=ax) a = ax.findobj(mpl.text.Annotation) for i in a: if i.get_label() == "Si II_num_4": i.set_visible(False) a = ax.findobj(mpl.lines.Line2D) for i in a: if i.get_label() == "Si II_num_4_line": i.set_visible(False) return fig
def plotSpecVsWLen(): wLen = getWavelengthArr(specFile, 0) spec = getImageData(specFile, 0) # wLen = range(len(spec)) for i in range(len(wLen)): print('wLen = ', wLen[i], ', spec = ', spec[i]) fig, ax = plt.subplots() fig.set_size_inches(18.5, 10.5) ax.plot(wLen, spec) #plt.show() ax.set_xlabel('Wavelength [$\mathrm{\AA}$]') ax.set_ylabel( '$\mathrm{F}_\lambda$ [$\mathrm{erg}$ $\mathrm{s^{-1}} \mathrm{cm^{-2}} \mathrm{\AA^{-1}}]$' ) #ax.set_xlim([0,2000]) yLim = 1e6 #ax.get_ylim()[1] ax.set_ylim([0, yLim * 1.3]) lineid_plot.plot_line_ids(wLen, spec, linePos, lineLabel, ax=ax, arrow_tip=yLim * 1.1, box_loc=yLim * 1.27) plt.title = specFile[specFile.rfind('/') + 1:] plt.savefig(specFile[:specFile.rfind('.')] + '.pdf', bbox_inches='tight') plt.show()
def line_ids(self, line_names, line_xvals, xval_units=None, auto_yloc=True, auto_yloc_fraction=0.9, **kwargs): """ Add line ID labels to a plot using lineid_plot http://oneau.wordpress.com/2011/10/01/line-id-plot/ https://github.com/phn/lineid_plot http://packages.python.org/lineid_plot/ Parameters ---------- line_names : list A list of strings to label the specified x-axis values line_xvals : list List of x-axis values (e.g., wavelengths) at which to label the lines xval_units : string A valid unit to convert to. If None, leaves units unchanged auto_yloc : bool If set, overrides box_loc and arrow_tip (the vertical position of the lineid labels) in kwargs to be `auto_yloc_fraction` of the plot range auto_yloc_fraction: float in range [0,1] The fraction of the plot (vertically) at which to place labels Examples -------- >>> import numpy as np >>> import pyspeckit >>> sp = pyspeckit.Spectrum( xarr=pyspeckit.units.SpectroscopicAxis(np.linspace(-50,50,101), unit='km/s', refX=6562.8, refX_unit='angstrom'), data=np.random.randn(101), error=np.ones(101)) >>> sp.plotter() >>> sp.plotter.line_ids(['H$\\alpha$'],[6562.8],xval_units='angstrom') """ import lineid_plot # convert line_xvals to current units xvals = [ self.Spectrum.xarr.x_to_coord(c, xval_units) for c in line_xvals ] if auto_yloc: yr = self.axis.get_ylim() kwargs['box_loc'] = (yr[1] - yr[0]) * auto_yloc_fraction + yr[0] kwargs['arrow_tip'] = (yr[1] - yr[0]) * (auto_yloc_fraction * 0.9) + yr[0] lineid_plot.plot_line_ids(self.Spectrum.xarr, self.Spectrum.data, xvals, line_names, ax=self.axis, **kwargs)
def test_small_change_to_y_loc_of_label(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] lineid_plot.plot_line_ids( wave, flux, line_wave, line_label1, box_axes_space=0.08)
def test_no_line_from_annotation_to_flux(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] # Set extend=False. lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, extend=False)
def plot_fit(wavelength, flux, error, chain, nburnin): halpha_complex_filter = (wavelength >= halpha_complex_region[0]) & ( wavelength <= halpha_complex_region[1]) hbeta_complex_filter = (wavelength >= hbeta_complex_region[0]) & ( wavelength <= hbeta_complex_region[1]) parameters = np.percentile(chain[:, nburnin:].reshape(-1, chain.shape[-1]), [16, 50, 84], axis=0) fig, axes = plt.subplots(2, 2, sharex='col') plt.subplots_adjust(wspace=0, hspace=0) models = bpt_lines_model(parameters[1], wavelength[halpha_complex_filter], wavelength[hbeta_complex_filter]) line_wvls = [[NIIa, NIIb, Halpha, SIIa, SIIb], [Hbeta, OIII4958, OIII5007]] line_labels = [[ '$NII[6548]$', '$NII[6584]$', r'$H\alpha$', '$SIIa$', '$SIIb$' ], [r'$H\beta$', '$OIII[4958]$', '$OIII[5007]$']] median_smoothed = smooth_spectrum(flux, wavelength) for ax, res_ax, filt, model, line_wvl, line_lab, cont in zip( axes[0], axes[1], [halpha_complex_filter, hbeta_complex_filter], models, line_wvls, line_labels, [parameters[:, -3], parameters[:, -2]]): wvl = wavelength[filt] flx = flux[filt] flx_upper = flx + error[filt] flx_lower = flx - error[filt] ax.plot(wvl, flx, 'k-') ax.fill_between(wvl, flx_lower, flx_upper, color='k', alpha=0.3) ax.plot(wvl, model, 'r-') res_ax.plot(wvl, flx - model, 'k-') res_ax.fill_between(wvl, flx_lower - model, flx_upper - model, color='k', alpha=0.3) lineid_plot.plot_line_ids(wvl, flx, line_wvl, line_lab, ax=ax) for w in line_wvl: res_ax.axvline(x=w, linestyle='--', color='r') cont_med, cont_std = np.median(median_smoothed[filt]), np.std( median_smoothed[filt]) ax.axhline(cont_med, color='g', ls=':') res_ax.axhline(0, color='g', ls=':') ax.axhspan(cont_med - cont_std, cont_med + cont_std, alpha=0.2, color='g') res_ax.axhspan(-cont_std, cont_std, color='g', alpha=0.2) return fig
def line_ids(self, line_names, line_xvals, xval_units=None, auto_yloc=True, auto_yloc_fraction=0.9, **kwargs): """ Add line ID labels to a plot using lineid_plot http://oneau.wordpress.com/2011/10/01/line-id-plot/ https://github.com/phn/lineid_plot http://packages.python.org/lineid_plot/ Parameters ---------- line_names : list A list of strings to label the specified x-axis values line_xvals : list List of x-axis values (e.g., wavelengths) at which to label the lines xval_units : string A valid unit to convert to. If None, leaves units unchanged auto_yloc : bool If set, overrides box_loc and arrow_tip (the vertical position of the lineid labels) in kwargs to be `auto_yloc_fraction` of the plot range auto_yloc_fraction: float in range [0,1] The fraction of the plot (vertically) at which to place labels Examples -------- >>> import numpy as np >>> import pyspeckit >>> sp = pyspeckit.Spectrum( xarr=pyspeckit.units.SpectroscopicAxis(np.linspace(-50,50,101), unit='km/s', refX=6562.8, refX_unit='angstrom'), data=np.random.randn(101), error=np.ones(101)) >>> sp.plotter() >>> sp.plotter.line_ids(['H$\\alpha$'],[6562.8],xval_units='angstrom') """ import lineid_plot # convert line_xvals to current units xvals = [self.Spectrum.xarr.x_to_coord(c, xval_units) for c in line_xvals] # xvals must not be quantities because matplotlib cannot handle these def strip_qty(x): return x.value if hasattr(x,'value') else x xvals = map(strip_qty, xvals) if auto_yloc: yr = self.axis.get_ylim() kwargs['box_loc'] = (yr[1]-yr[0])*auto_yloc_fraction + yr[0] kwargs['arrow_tip'] = (yr[1]-yr[0])*(auto_yloc_fraction*0.9) + yr[0] lineid_plot.plot_line_ids(self.Spectrum.xarr, self.Spectrum.data, xvals, line_names, ax=self.axis, **kwargs)
def line_ids_from_measurements(self, auto_yloc=True, auto_yloc_fraction=0.9, **kwargs): """ Add line ID labels to a plot using lineid_plot http://oneau.wordpress.com/2011/10/01/line-id-plot/ https://github.com/phn/lineid_plot http://packages.python.org/lineid_plot/ Parameters ---------- auto_yloc : bool If set, overrides box_loc and arrow_tip (the vertical position of the lineid labels) in kwargs to be `auto_yloc_fraction` of the plot range auto_yloc_fraction: float in range [0,1] The fraction of the plot (vertically) at which to place labels Examples -------- >>> import numpy as np >>> import pyspeckit >>> sp = pyspeckit.Spectrum( xarr=pyspeckit.units.SpectroscopicAxis(np.linspace(-50,50,101), units='km/s', refX=6562.8, refX_unit='angstroms'), data=np.random.randn(101), error=np.ones(101)) >>> sp.plotter() >>> sp.specfit(multifit=None, fittype='gaussian', guesses=[1,0,1]) # fitting noise.... >>> sp.measure() >>> sp.plotter.line_ids_from_measurements() """ import lineid_plot if hasattr(self.Spectrum, 'measurements'): measurements = self.Spectrum.measurements if auto_yloc: yr = self.axis.get_ylim() kwargs['box_loc'] = (yr[1] - yr[0]) * auto_yloc_fraction + yr[0] kwargs['arrow_tip'] = (yr[1] - yr[0]) * (auto_yloc_fraction * 0.9) + yr[0] lineid_plot.plot_line_ids( self.Spectrum.xarr, self.Spectrum.data, [v['pos'] for v in measurements.lines.values()], measurements.lines.keys(), ax=self.axis, **kwargs) else: warn( "Cannot add line IDs from measurements unless measurements have been made!" )
def test_custom_y_loc_for_annotation_point(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=3.3, ax=ax)
def test_small_change_to_y_loc_of_label(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, box_axes_space=0.08)
def test_annotate_kwargs_and_plot_kwargs(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] ak = lineid_plot.initial_annotate_kwargs() ak['arrowprops']['arrowstyle'] = "->" pk = lineid_plot.initial_plot_kwargs() pk['color'] = "red" lineid_plot.plot_line_ids( wave, flux, line_wave, line_label1, annotate_kwargs=ak, plot_kwargs=pk)
def line_ids_from_measurements(self, auto_yloc=True, auto_yloc_fraction=0.9, **kwargs): """ Add line ID labels to a plot using lineid_plot http://oneau.wordpress.com/2011/10/01/line-id-plot/ https://github.com/phn/lineid_plot http://packages.python.org/lineid_plot/ Parameters ---------- auto_yloc : bool If set, overrides box_loc and arrow_tip (the vertical position of the lineid labels) in kwargs to be `auto_yloc_fraction` of the plot range auto_yloc_fraction: float in range [0,1] The fraction of the plot (vertically) at which to place labels Examples -------- >>> import numpy as np >>> import pyspeckit >>> sp = pyspeckit.Spectrum( xarr=pyspeckit.units.SpectroscopicAxis(np.linspace(-50,50,101), units='km/s', refX=6562.8, refX_units='angstroms'), data=np.random.randn(101), error=np.ones(101)) >>> sp.plotter() >>> sp.specfit(multifit=True, fittype='gaussian', guesses=[1,0,1]) # fitting noise.... >>> sp.measure() >>> sp.plotter.line_ids_from_measurements() """ import lineid_plot if hasattr(self.Spectrum,'measurements'): measurements = self.Spectrum.measurements if auto_yloc: yr = self.axis.get_ylim() kwargs['box_loc'] = (yr[1]-yr[0])*auto_yloc_fraction + yr[0] kwargs['arrow_tip'] = (yr[1]-yr[0])*(auto_yloc_fraction*0.9) + yr[0] lineid_plot.plot_line_ids(self.Spectrum.xarr, self.Spectrum.data, [v['pos'] for v in measurements.lines.values()], measurements.lines.keys(), ax=self.axis, **kwargs) else: warn("Cannot add line IDs from measurements unless measurements have been made!")
def test_custom_y_loc_for_label_boxes_each_box_sep_loc(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) arrow_tips = [3.3, 3.3, 3.3, 3.4, 3.5, 3.4, 3.3] box_loc = [4.3, 4.3, 4.3, 4.4, 4.5, 4.4, 4.3] lineid_plot.plot_line_ids( wave, flux, line_wave, line_label1, arrow_tip=arrow_tips, box_loc=box_loc, ax=ax)
def test_annotate_kwargs_and_plot_kwargs(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] ak = lineid_plot.initial_annotate_kwargs() ak['arrowprops']['arrowstyle'] = "->" pk = lineid_plot.initial_plot_kwargs() pk['color'] = "red" lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, annotate_kwargs=ak, plot_kwargs=pk)
def test_custom_y_loc_for_annotation_point(): """User cna supply custom y_loc for annotation point.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=3.3, ax=ax) return fig
def test_custom_y_loc_for_label_boxes(): """User can specify y_loc for label box.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=3.3, ax=ax, box_loc=4.3) return fig
def test_custom_y_loc_for_label_boxes_each_box_sep_loc(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) arrow_tips = [3.3, 3.3, 3.3, 3.4, 3.5, 3.4, 3.3] box_loc = [4.3, 4.3, 4.3, 4.4, 4.5, 4.4, 4.3] lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=arrow_tips, box_loc=box_loc, ax=ax)
def test_minimal_plot(): """Test a minimal plot.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1) return fig
def test_multi_plot_user_axes(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() # First Axes ax = fig.add_axes([0.1, 0.06, 0.85, 0.35]) ax.plot(wave, flux) # Pass the Axes instance to the plot_line_ids function. lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, ax=ax) # Second Axes ax1 = fig.add_axes([0.1, 0.55, 0.85, 0.35]) ax1.plot(wave, flux) # Pass the Axes instance to the plot_line_ids function. lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, ax=ax1)
def test_custom_y_loc_for_annotation_point_each_label_sep_loc(): """User can specific y_loc for each label.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(wave, flux) ax.axis([1240, 1270, -3, 5]) arrow_tips = [3.3, 3.3, 3.3, 3.4, 3.5, 3.4, 3.3] lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, arrow_tip=arrow_tips, ax=ax) return fig
def plot_spectrum(x, y, z=0, lines=[], xlim=None, ylim=None, **kwargs): #fig = plt.figure(1) ax1 = plt.subplot(111) #ax = fig.add_axes([0.1,0.06, 0.85, 0.35]) # ax.plot(x, y) if xlim is not None: plt.xlim(xlim) if ylim is not None: plt.ylim(ylim) lvals = [] for l in lines: if l in a_lines: lvals.append(a_lines[l]) elif l in e_lines: lvals.append(e_lines[l]) #print lines, lvals lineid_plot.plot_line_ids(x / (1. + z), y * (1. + z), lvals, lines, ax=ax1) ax1.plot(x / (1. + z), y * (1. + z), **kwargs) if "label" in kwargs: ax1.legend() #plt.show() return ax1
def plot_spectrum(x,y,z=0,lines=[],xlim=None, ylim=None,**kwargs): #fig = plt.figure(1) ax1=plt.subplot(111) #ax = fig.add_axes([0.1,0.06, 0.85, 0.35]) # ax.plot(x, y) if xlim is not None: plt.xlim(xlim) if ylim is not None: plt.ylim(ylim) lvals=[] for l in lines: if l in a_lines: lvals.append(a_lines[l]) elif l in e_lines: lvals.append(e_lines[l]) #print lines, lvals lineid_plot.plot_line_ids(x/(1.+z), y*(1.+z), lvals, lines, ax=ax1) ax1.plot(x/(1.+z),y*(1.+z), **kwargs) if "label" in kwargs: ax1.legend() #plt.show() return ax1
def pltFT(path, name, xs, xb, units, tvec, argval): s = settings.settings() fig = plt.figure(figsize=(21, 7)) ax1 = plt.subplot2grid((2, 1), (1, 0), rowspan=1, colspan=1) # ax1=fig.add_axes([0.1,0.1, 0.8, 0.8]) l1 = ax1.plot(tvec, xb[1, :], color='r', label="obs") l2 = ax1.plot(tvec, xs[1, :], color='g', label="sim") handles, labels = ax1.get_legend_handles_labels() ax1.legend(handles, labels, loc=1, fontsize='12') ax1.set_xlim([5, 27]) ak = lineid_plot.initial_annotate_kwargs() tide = np.array(list(s['tidedict'].keys())) cor = np.array(list(s['cordict'].values())) tidlab = np.append(tide, cor) lineid_plot.plot_line_ids(tvec, xb[1, :], argval, tidlab, ax=ax1, max_iter=30000) plt.xlabel('Period [h]', fontsize=12, fontweight='bold') plt.ylabel('Phase (deg)', fontsize=12, fontweight='bold') ax2 = fig.add_axes([0.125, 0.57, 0.775, 0.34], sharex=ax1) l1 = ax2.plot(tvec, xb[0, :], color='r', label="obs") l2 = ax2.plot(tvec, xs[0, :], color='g', label="sim") handles, labels = ax2.get_legend_handles_labels() ax2.legend(handles, labels, loc=1, fontsize='12') lineid_plot.plot_line_ids(tvec, xb[0, :], argval, tidlab, ax=ax2, max_iter=30000) # plt.ylabel('Amplitude (' + units + ')', fontsize=12, fontweight='bold') plt.setp(ax2.get_xticklabels(), visible=False) plt.xticks(fontsize=12) plt.yticks(fontsize=12) plt.savefig(path + '/' + name + '.jpg', format='jpg') plt.close(fig)
def test_dont_add_label_to_artists(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids( wave, flux, line_wave, line_label1, max_iter=300, add_label_to_artists=False ) labels = lineid_plot.unique_labels(line_label1) for label in labels: assert fig.findobj(match=lambda x: x.get_label() == label) == [] assert fig.findobj(match=lambda x: x.get_label() == label + "_line") == []
def plotRefSpec(lam, flux, title='refArc_spupnic_may2007_d.fits'): fig, ax = plt.subplots() fig.set_size_inches(18.5, 10.5) #ax.plot(wLenArr[0:len(wLenArr)-1],spec) ax.plot(lam, flux) ax.set_xlabel('Wavelength [$\mathrm{\AA}$]') ax.set_ylabel( '$\mathrm{F}_\lambda$ [$\mathrm{erg}$ $\mathrm{s^{-1}} \mathrm{cm^{-2}} \mathrm{\AA^{-1}}]$' ) #ax.set_xlim([0,2000]) yLim = ax.get_ylim()[1] ax.set_ylim([0, yLim * 1.4]) lineid_plot.plot_line_ids(lam, flux, [float(i) for i in lineLabelRef], lineLabelRef, ax=ax, arrow_tip=yLim * 1.1, box_loc=yLim * 1.27) plt.title = title plt.savefig(refSpecFile[:refSpecFile.rfind('.')] + '.pdf', bbox_inches='tight') plt.show()
def plotAug2013(): spec = getImageData(aug2013Arc, 0) wLen = getWavelengthArr(aug2013Arc, 0) fig, ax = plt.subplots() fig.set_size_inches(18.5, 10.5) ax.plot(wLen, spec) ax.set_xlabel('Wavelength [$\mathrm{\AA}$]') ax.set_ylabel( '$\mathrm{F}_\lambda$ [$\mathrm{erg}$ $\mathrm{s^{-1}} \mathrm{cm^{-2}} \mathrm{\AA^{-1}}]$' ) #ax.set_xlim([0,2000]) yLim = ax.get_ylim()[1] ax.set_ylim([0, yLim * 1.4]) lineid_plot.plot_line_ids(wLen, spec, [float(l) for l in lineLabel], lineLabel, ax=ax, arrow_tip=yLim * 1.1, box_loc=yLim * 1.27) plt.savefig(aug2013Arc[:aug2013Arc.rfind('.')] + '.pdf', bbox_inches='tight') plt.show()
def test_small_change_to_y_loc_of_label(): """User can make small changes to y_loc_of_label.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, box_axes_space=0.08) return fig
def test_no_line_from_annotation_to_flux(): """Must create plot with no line from annotation to flux point.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, extend=False) return fig
def test_max_iter_large(): """User can specify large max_iter.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, max_iter=300) return fig
def test_multi_plot_user_axes(): """User can supply custom axes.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig = plt.figure() # First Axes ax = fig.add_axes([0.1, 0.06, 0.85, 0.35]) ax.plot(wave, flux) # Pass the Axes instance to the plot_line_ids function. lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, ax=ax) # Second Axes ax1 = fig.add_axes([0.1, 0.55, 0.85, 0.35]) ax1.plot(wave, flux) # Pass the Axes instance to the plot_line_ids function. lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, ax=ax1) return fig
def test_customize_box_and_line(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1) b = ax.findobj(match=lambda x: x.get_label() == 'Si II_num_1')[0] b.set_rotation(0) b.set_text("Si II$\lambda$1260.42") line = ax.findobj(match=lambda x: x.get_label() == 'Si II_num_1_line')[0] line.set_color("red") line.set_linestyle("-")
def test_dont_add_label_to_artists(): wave = 1240 + np.arange(300) * 0.1 flux = np.random.normal(size=300) line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, max_iter=300, add_label_to_artists=False) labels = lineid_plot.unique_labels(line_label1) for label in labels: assert fig.findobj(match=lambda x: x.get_label() == label) == [] assert fig.findobj( match=lambda x: x.get_label() == label + "_line") == []
def test_customize_box_and_line(): """User can change box and line aspects after plotting.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1) b = ax.findobj(match=lambda x: x.get_label() == 'Si II_num_1')[0] b.set_rotation(0) b.set_text("Si II$\lambda$1260.42") line = ax.findobj(match=lambda x: x.get_label() == 'Si II_num_1_line')[0] line.set_color("red") line.set_linestyle("-") return fig
def test_annotate_kwargs_and_plot_kwargs(): """User can supply custom annotate and plot kwargs.""" wave = 1240 + np.arange(300) * 0.1 flux = RFLUX line_wave = [1242.80, 1260.42, 1264.74, 1265.00, 1265.2, 1265.3, 1265.35] line_label1 = ['N V', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II', 'Si II'] ak = lineid_plot.initial_annotate_kwargs() ak['arrowprops']['arrowstyle'] = "->" pk = lineid_plot.initial_plot_kwargs() pk['color'] = "red" fig, ax = lineid_plot.plot_line_ids(wave, flux, line_wave, line_label1, annotate_kwargs=ak, plot_kwargs=pk) return fig
def line_ids(self, line_names, line_xvals, xval_units=None, auto_yloc=True, velocity_offset=None, velocity_convention='radio', auto_yloc_fraction=0.9, **kwargs): """ Add line ID labels to a plot using lineid_plot http://oneau.wordpress.com/2011/10/01/line-id-plot/ https://github.com/phn/lineid_plot http://packages.python.org/lineid_plot/ Parameters ---------- line_names : list A list of strings to label the specified x-axis values line_xvals : list List of x-axis values (e.g., wavelengths) at which to label the lines. Can be a list of quantities. xval_units : string The unit of the line_xvals if they are not given as quantities velocity_offset : quantity A velocity offset to apply to the inputs if they are in frequency or wavelength units velocity_convention : 'radio' or 'optical' or 'doppler' Used if the velocity offset is given auto_yloc : bool If set, overrides box_loc and arrow_tip (the vertical position of the lineid labels) in kwargs to be `auto_yloc_fraction` of the plot range auto_yloc_fraction: float in range [0,1] The fraction of the plot (vertically) at which to place labels Examples -------- >>> import numpy as np >>> import pyspeckit >>> sp = pyspeckit.Spectrum( xarr=pyspeckit.units.SpectroscopicAxis(np.linspace(-50,50,101), unit='km/s', refX=6562.8, refX_unit='angstrom'), data=np.random.randn(101), error=np.ones(101)) >>> sp.plotter() >>> sp.plotter.line_ids(['H$\\alpha$'],[6562.8],xval_units='angstrom') """ import lineid_plot if velocity_offset is not None: assert velocity_offset.unit.is_equivalent(u.km/u.s) doppler = getattr(u, 'doppler_{0}'.format(velocity_convention)) equivalency = doppler(self.Spectrum.xarr.refX) xvals = [] for xv in line_xvals: if hasattr(xv, 'unit'): pass else: xv = u.Quantity(xv, xval_units) xv = xv.to(u.km/u.s, equivalencies=equivalency) if velocity_offset is not None: xv = xv + velocity_offset xv = xv.to(self.Spectrum.xarr.unit, equivalencies=equivalency) xvals.append(xv.value) if auto_yloc: yr = self.axis.get_ylim() kwargs['box_loc'] = (yr[1]-yr[0])*auto_yloc_fraction + yr[0] kwargs['arrow_tip'] = (yr[1]-yr[0])*(auto_yloc_fraction*0.9) + yr[0] lineid_plot.plot_line_ids(self.Spectrum.xarr, self.Spectrum.data, xvals, line_names, ax=self.axis, **kwargs)
# ax.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax.set_yticks([5e-16/1e-16, 6e-16/1e-16, 7e-16/1e-16, 8e-16/1e-16, 9e-16/1e-16]) #Overplot lines fit_line_positions = np.genfromtxt('data/lineplotlinelist.txt', dtype=None) import lineid_plot linelist = [] linenames = [] for n in fit_line_positions: linelist.append(n[1]) linenames.append(n[0]) linelist = np.array(linelist) linelist = wavelength_conversion(linelist, conversion='vacuum_to_air') lineid_plot.plot_line_ids(wl, medfilt(flux, 3)/norm, linelist, linenames, ax=ax) for i in ax.lines: if '$' in i.get_label(): i.set_alpha(0.3) i.set_linewidth(0.75) a = ax.findobj(mpl.text.Annotation) for i in a: if '$' in i.get_label(): i.set_size(16) for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(16)
def main(fname, lines=False, linelist=False, model=False, telluric=False, sun=False, rv=False, rv1=False, rv2=False, ccf='none', ftype='1D', fitsext='0', order='77', convert=False, resolution=False, nolines=False): """Plot a fits file with extensive options :fname: Input spectra :lines: Absorption lines :linelist: A file with the lines :model: Model spectrum :telluric: Telluric spectrum :sun: Solar spectrum :rv: RV of input spectrum :rv1: RV of Solar/model spectrum :rv2: RV of telluric spectrum :ccf: Calculate CCF (sun, model, telluric, both) :ftype: Type of fits file (1D, CRIRES, GIANO) :fitsext: Slecet fits extention to use (0,1,2,3,4) :returns: RV if CCF have been calculated """ print('\n-----------------------------------') path = os.path.expanduser('~/.plotfits/') pathsun = os.path.join(path, 'solarspectrum_01.fits') pathtel = os.path.join(path, 'telluric_NIR.fits') pathwave = os.path.join(path, 'WAVE_PHOENIX-ACES-AGSS-COND-2011.fits') pathGIANO = os.path.join(path, 'wavelength_GIANO.dat') if not os.path.isdir(path): os.mkdir(path) print('Created: %s' % path) if sun and (not os.path.isfile(pathsun)): print('Downloading solar spectrum...') _download_spec(pathsun) if telluric and (not os.path.isfile(pathtel)): print('Downloading telluric spectrum...') _download_spec(pathtel) if model and (not os.path.isfile(pathwave)): print('Downloading wavelength vector for model...') import urllib url = 'ftp://phoenix.astro.physik.uni-goettingen.de/HiResFITS//WAVE_PHOENIX-ACES-AGSS-COND-2011.fits' urllib.urlretrieve(url, pathwave) fitsext = int(fitsext) order = int(order) if ftype == '1D': I = fits.getdata(fname) hdr = fits.getheader(fname) w = get_wavelength(hdr, convert=convert) elif ftype == 'CRIRES': d = fits.getdata(fname, fitsext) hdr = fits.getheader(fname, fitsext) I = d['Extracted_OPT'] w = d['Wavelength']*10 elif ftype == 'GIANO': d = fits.getdata(fname) I = d[order - 32] # 32 is the first order wd = np.loadtxt(pathGIANO) w0, w1 = wd[wd[:, 0] == order][0][1:] w = np.linspace(w0, w1, len(I), endpoint=True) elif ftype == 'UVES': raise NotImplementedError('Please be patient. Not quite there yet') # d = fits.getdata(fname) # I = d[''] if np.median(I) != 0: I /= np.median(I) else: I /= I.max() # Normalization (use first 50 points below 1.2 as constant continuum) maxes = I[(I < 1.2)].argsort()[-50:][::-1] I /= np.median(I[maxes]) I[I<0] = 0 dw = 10 # Some extra coverage for RV shifts if rv: I, w = dopplerShift(wvl=w, flux=I, v=rv) w0, w1 = w[0] - dw, w[-1] + dw if sun and not model: I_sun = fits.getdata(pathsun) hdr = fits.getheader(pathsun) w_sun = get_wavelength(hdr) i = (w_sun > w0) & (w_sun < w1) w_sun = w_sun[i] I_sun = I_sun[i] if len(w_sun) > 0: I_sun /= np.median(I_sun) if ccf in ['sun', 'both'] and rv1: print('Warning: RV set for Sun. Calculate RV with CCF') if rv1 and ccf not in ['sun', 'both']: I_sun, w_sun = dopplerShift(wvl=w_sun, flux=I_sun, v=rv1) else: print('Warning: Solar spectrum not available in wavelength range.') sun = False elif sun and model: print('Warning: Both solar spectrum and a model spectrum are selected. Using model spectrum.') sun = False if model: I_mod = fits.getdata(model) hdr = fits.getheader(model) if 'WAVE' in hdr.keys(): w_mod = fits.getdata(pathwave) else: w_mod = get_wavelength(hdr) w_mod = vac2air(w_mod) # Correction for vacuum to air (ground based) i = (w_mod > w0) & (w_mod < w1) w_mod = w_mod[i] I_mod = I_mod[i] if len(w_mod) > 0: if resolution: I_mod = pyasl.instrBroadGaussFast(w_mod, I_mod, resolution, edgeHandling="firstlast", fullout=False, maxsig=None) # https://phoenix.ens-lyon.fr/Grids/FORMAT # I_mod = 10 ** (I_mod-8.0) I_mod /= np.median(I_mod) # Normalization (use first 50 points below 1.2 as continuum) maxes = I_mod[(I_mod < 1.2)].argsort()[-50:][::-1] I_mod /= np.median(I_mod[maxes]) if ccf in ['model', 'both'] and rv1: print('Warning: RV set for model. Calculate RV with CCF') if rv1 and ccf not in ['model', 'both']: I_mod, w_mod = dopplerShift(wvl=w_mod, flux=I_mod, v=rv1) else: print('Warning: Model spectrum not available in wavelength range.') model = False if telluric: I_tel = fits.getdata(pathtel) hdr = fits.getheader(pathtel) w_tel = get_wavelength(hdr) i = (w_tel > w0) & (w_tel < w1) w_tel = w_tel[i] I_tel = I_tel[i] if len(w_tel) > 0: I_tel /= np.median(I_tel) if ccf in ['telluric', 'both'] and rv2: print('Warning: RV set for telluric, Calculate RV with CCF') if rv2 and ccf not in ['telluric', 'both']: I_tel, w_tel = dopplerShift(wvl=w_tel, flux=I_tel, v=rv2) else: print('Warning: Telluric spectrum not available in wavelength range.') telluric = False rvs = {} if ccf != 'none': if ccf in ['sun', 'both'] and sun: # remove tellurics from the Solar spectrum if telluric and sun: print('Correcting solar spectrum for tellurics...') print('Calculating CCF for the Sun...') rv1, r_sun, c_sun, x_sun, y_sun = ccf_astro((w, -I + 1), (w_sun, -I_sun + 1)) if rv1 != 0: print('Shifting solar spectrum...') I_sun, w_sun = dopplerShift(w_sun, I_sun, v=rv1) rvs['sun'] = rv1 print('DONE\n') if ccf in ['model', 'both'] and model: print('Calculating CCF for the model...') rv1, r_mod, c_mod, x_mod, y_mod = ccf_astro((w, -I + 1), (w_mod, -I_mod + 1)) if rv1 != 0: print('Shifting model spectrum...') I_mod, w_mod = dopplerShift(w_mod, I_mod, v=rv1) rvs['model'] = rv1 print('DONE\n') if ccf in ['telluric', 'both'] and telluric: print('Calculating CCF for the model...') rv2, r_tel, c_tel, x_tel, y_tel = ccf_astro((w, -I + 1), (w_tel, -I_tel + 1)) if rv2 != 0: print('Shifting telluric spectrum...') I_tel, w_tel = dopplerShift(w_tel, I_tel, v=rv2) rvs['telluric'] = rv2 print('DONE\n') if len(rvs) == 0: ccf = 'none' if ccf != 'none': from matplotlib.gridspec import GridSpec fig = plt.figure(figsize=(16, 5)) gs = GridSpec(1, 5) if len(rvs) == 1: gs.update(wspace=0.25, hspace=0.35, left=0.05, right=0.99) ax1 = plt.subplot(gs[:, 0:-1]) ax2 = plt.subplot(gs[:, -1]) ax2.set_yticklabels([]) elif len(rvs) == 2: gs.update(wspace=0.25, hspace=0.35, left=0.01, right=0.99) ax1 = plt.subplot(gs[:, 1:4]) ax2 = plt.subplot(gs[:, 0]) ax3 = plt.subplot(gs[:, -1]) ax2.set_yticklabels([]) ax3.set_yticklabels([]) else: fig = plt.figure(figsize=(16, 5)) ax1 = fig.add_subplot(111) # Start in pan mode with these two lines # manager = plt.get_current_fig_manager() # manager.toolbar.pan() # Use nice numbers on x axis (y axis is normalized)... x_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) ax1.xaxis.set_major_formatter(x_formatter) if sun and not model: ax1.plot(w_sun, I_sun, '-C2', lw=1, alpha=0.6, label='Sun') if telluric: ax1.plot(w_tel, I_tel, '-C3', lw=1, alpha=0.6, label='Telluric') if model: ax1.plot(w_mod, I_mod, '-C2', lw=1, alpha=0.6, label='Model') ax1.plot(w, I, '-k', lw=1, label='Star') # Add crosshair xlim = ax1.get_xlim() cursor = Cursor(ax1) plt.connect('motion_notify_event', cursor.mouse_move) ax1.set_xlim(xlim) if (linelist or lines) and lineidImport and not nolines: try: lines, elements = np.loadtxt(linelist, usecols=(0, 1), skiprows=1, unpack=True) idx = (lines <= max(w)) & (lines >= min(w)) lines = lines[idx] elements = elements[idx] Fe1Lines, Fe2Lines, otherLines = [], [], [] for line, element in zip(lines, elements): if np.allclose(element, 26.0): Fe1Lines.append('FeI: {}'.format(line)) elif np.allclose(element, 26.1): Fe2Lines.append('FeII: {}'.format(line)) else: otherLines.append('{}: {}'.format(element, line)) lines = lines*(1.0 + rv1 / 299792.458) if rv1 else lines*1 if len(Fe1Lines): lineid_plot.plot_line_ids(w, I, lines[elements==26.0], Fe1Lines, ax=ax1, add_label_to_artists=False) if len(Fe2Lines): pk = lineid_plot.initial_plot_kwargs() pk['color'] = 'red' lineid_plot.plot_line_ids(w, I, lines[elements==26.1], Fe2Lines, ax=ax1, add_label_to_artists=False, plot_kwargs=pk) except IOError: pass ax1.set_ylim(min(I)-0.05*min(I), 1.05*max(I)) ax1.set_xlabel('Wavelength') ax1.set_ylabel('"Normalized" flux') if len(rvs) == 1: if 'sun' in rvs.keys(): ax2.plot(r_sun, c_sun, '-k', alpha=0.9, lw=2) ax2.plot(x_sun, y_sun, '--C1', lw=2) ax2.set_title('CCF (sun)') if 'model' in rvs.keys(): ax2.plot(r_mod, c_mod, '-k', alpha=0.9, lw=2) ax2.plot(x_mod, y_mod, '--C1', lw=2) ax2.set_title('CCF (mod)') if 'telluric' in rvs.keys(): ax2.plot(r_tel, c_tel, '-k', alpha=0.9, lw=2) ax2.plot(x_tel, y_tel, '--C1', lw=2) ax2.set_title('CCF (tel)') ax2.set_xlabel('RV [km/s]') elif len(rvs) == 2: if 'sun' in rvs.keys(): ax2.plot(r_sun, c_sun, '-k', alpha=0.9, lw=2) ax2.plot(x_sun, y_sun, '--C1', lw=2) ax2.set_title('CCF (sun)') if 'model' in rvs.keys(): ax2.plot(r_mod, c_mod, '-k', alpha=0.9, lw=2) ax2.plot(x_mod, y_mod, '--C1', lw=2) ax2.set_title('CCF (mod)') ax3.plot(r_tel, c_tel, '-k', alpha=0.9, lw=2) ax3.plot(x_tel, y_tel, '--C1', lw=2) ax3.set_title('CCF (tel)') ax2.set_xlabel('RV [km/s]') ax3.set_xlabel('RV [km/s]') if rv: ax1.set_title('%s\nRV correction: %s km/s' % (fname, int(rv))) elif rv1 and rv2: ax1.set_title('%s\nSun/model: %s km/s, telluric: %s km/s' % (fname, int(rv1), int(rv2))) elif rv1 and not rv2: ax1.set_title('%s\nSun/model: %s km/s' % (fname, int(rv1))) elif not rv1 and rv2: ax1.set_title('%s\nTelluric: %s km/s' % (fname, int(rv2))) elif ccf == 'model': ax1.set_title('%s\nModel(CCF): %s km/s' % (fname, int(rv1))) elif ccf == 'sun': ax1.set_title('%s\nSun(CCF): %s km/s' % (fname, int(rv1))) elif ccf == 'telluric': ax1.set_title('%s\nTelluric(CCF): %s km/s' % (fname, int(rv2))) elif ccf == 'both': ax1.set_title('%s\nSun/model(CCF): %s km/s, telluric(CCF): %s km/s' % (fname, int(rv1), int(rv2))) else: ax1.set_title(fname) if sun or telluric or model: ax1.legend(loc=3, frameon=False) plt.show() return rvs
def main(): # latexify() import numpy as np root_dir = '/Users/jselsing/Work/X-Shooter/CompositeRedQuasar/processed_data/' data_file = np.genfromtxt(root_dir+'Composite.dat') wl = data_file[:,0] mean = data_file[:,1] err_mean = data_file[:,2] wmean = data_file[:,3] err_wmean = data_file[:,4] geo_mean = data_file[:,5] median = data_file[:,6] n_spec = data_file[:,7] std = data_file[:,8] std_norm = data_file[:,9] wmean_cont = data_file[:,10] from scipy.interpolate import InterpolatedUnivariateSpline mask = (np.where(err_wmean != 0)) f = InterpolatedUnivariateSpline(wl[mask], wmean_cont[mask], w=err_wmean[mask], k=5) wmean_cont = f(wl) f = InterpolatedUnivariateSpline(wl[mask], err_wmean[mask], k=5) err_wmean = f(wl) #Saving to .dat file dt = [("wl", np.float64), ("wmean_cont", np.float64), ("err_wmean", np.float64) ] data = np.array(zip(wl, wmean_cont, err_wmean), dtype=dt) file_name = "data/templates/Selsing2015_interpolated.dat" np.savetxt(file_name, data, header="wl weighted mean error of weighted mean", fmt = ['%5.1f', '%1.4f', '%1.4f' ]) pl.plot(wl,wmean_cont) pl.semilogy() pl.show() exit() #Fitting power laws from scipy import optimize def power_law(x_tmp, a_tmp, k_tmp): tmp = a_tmp * x_tmp ** k_tmp return tmp def power_law2(x_tmp, a1_tmp, x_c, k1_tmp, k2_tmp): tmp1 = power_law(x_tmp, a1_tmp,k1_tmp)[x_tmp<x_c] scale2loc = np.argmin(np.abs(x_tmp - x_c)) a2_tmp = power_law(x_tmp[scale2loc], a1_tmp, (k1_tmp - k2_tmp)) tmp2 = power_law(x_tmp, a2_tmp,k2_tmp)[x_tmp>= x_c] return np.concatenate((tmp1,tmp2)) par_guess = [1, -1.7] par_guess2 = [1, 5000, -1.7, -1.7] wmean[np.where(np.isnan(wmean) == True)] = 0 mask = (wl > 1300) & (wl < 1350) | (wl > 1425) & (wl < 1475) | (wl > 5500) & (wl < 5800) | (wl > 7300) & (wl < 7500) #| (wl > 9700) & (wl < 9900) | (wl > 10200) & (wl < 10600) popt, pcov = optimize.curve_fit(power_law, wl[mask], wmean_cont[mask], p0=par_guess, sigma=err_wmean[mask], absolute_sigma=True) popt2, pcov2 = optimize.curve_fit(power_law2, wl[mask], wmean_cont[mask], p0=par_guess2, sigma=err_wmean[mask], absolute_sigma=True) print(*popt) print(*popt2) #Plotting latexify(columns=2) fig, ax = pl.subplots() ax.plot(wl, medfilt(wmean_cont, 5), lw = 0.5, alpha=1.0, linestyle = 'steps-mid', label='X-shooter mean composite', color=cmap[1]) ax.plot(wl, power_law(wl, *popt), linestyle='dashed', label ='Pure power law fit', color=cmap[2]) sdss_compo = np.genfromtxt('/Users/jselsing/Work/X-Shooter/CompositeRedQuasar/processed_data/sdss_compo.dat') sdss_wl = sdss_compo[:,0] sdss_flux = sdss_compo[:, 1] norm_reg = 1430 mask = (wl > norm_reg) & (wl < norm_reg + 20) norm1 = np.median(wmean_cont[mask]) mask = (sdss_wl > norm_reg) & (sdss_wl < norm_reg + 20) norm2 = np.median(sdss_flux[mask]) ax.plot(sdss_wl, sdss_flux * (norm1/norm2), linestyle='solid', label ='Full sample SDSS composite', color=cmap[0]) #Overplot lines fit_line_positions = np.genfromtxt('data/plotlinelist.txt', dtype=None) linelist = [] linenames = [] for n in fit_line_positions: linelist.append(n[1]) linenames.append(n[0]) pl.semilogy() # Formatting axes import matplotlib as mpl ax.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax.get_xaxis().tick_bottom() ax.xaxis.set_minor_locator(mpl.ticker.NullLocator()) ax.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax.set_yticks([0.3, 1, 3, 10, 30, 100, 300]) ax.yaxis.set_minor_locator(mpl.ticker.NullLocator()) # pl.legend(loc=3) ax.set_xlim((1000, 11500)) ax.set_ylim((0.2, 500)) format_axes(ax) ax.set_xlabel(r'Wavelength [$\AA$]') ax.set_ylabel(r'Rescaled flux density F$_\lambda$') pl.tight_layout() val = [] for p in range(len(linelist)): xcoord = linelist[p] mask = (wl > xcoord - 1) & (wl < xcoord + 1) y_val = np.mean(wmean_cont[mask]) val.append(2 * y_val) print(val) arrow_tips = val lineid_plot.plot_line_ids(wl, wmean_cont, linelist, linenames, arrow_tip=arrow_tips, ax=ax) for i in ax.lines: if '$' in i.get_label(): i.set_alpha(0.3) a = ax.findobj(mpl.text.Annotation) for i in a: if '$' in i.get_label(): i.set_size(10) pl.savefig('../documents/figs/compo_full_sample.pdf') pl.show()
def main(): """ # Script to produce plot of GRB121024A """ # Load data from file data = np.genfromtxt("../data/GRB121024A_OB1_stitched_spectrum.dat") wl = data[:, 0] flux = data[:, 1] error = data[:, 2] n_elem = len(wl) # Get linelist import lineid_plot fit_line_positions = np.genfromtxt("../data/grblines_Christensen2011.dat", dtype=None) linelist = [0] * len(fit_line_positions) linenames = [0] * len(fit_line_positions) for ii, nn in enumerate(fit_line_positions): linelist[ii] = float(nn[0]) linenames[ii] = nn[1].decode("utf-8") linelist = np.array(linelist) linenames = np.array(linenames) # print(linenames) # Redshifts of systems z = [2.300] ls = ["dashed"] # Make plot n_axes = 7 fig, (ax1, ax2, ax3, ax4, ax5, ax6, ax7) = pl.subplots(n_axes, 1) for ii, ax in enumerate([ax1, ax2, ax3, ax4, ax5, ax6, ax7]): cut = slice(int(np.round(n_elem * (ii / n_axes))), int(np.round(n_elem * (ii / n_axes + 1 / n_axes)))) ax.plot(wl[cut], flux[cut], color="black", lw=0.5, linestyle="steps-mid", rasterized=True, zorder=2) interp = interpolate.interp1d(wl[cut], signal.medfilt(flux[cut], 11)) for oo, pp in enumerate(z): idx = [ ii for ii, kk in enumerate(linelist * (1 + pp)) if (kk > wl[cut][0] and kk < wl[cut][-1]) ] # for aa, ss in zip(linelist[idx]*(1 + pp), linenames[idx]): # ax.axvline(aa, ymin=interp(aa)/2, linestyle=ls[oo], color="black", alpha=0.7, lw=0.5) # ax.text(aa, 1.5, ss) lineid_plot.plot_line_ids(wl[cut], flux[cut], linelist[idx] * (1 + pp), linenames[idx], arrow_tip=1.2, box_loc=1.6, ax=ax) ax.plot(wl[cut][::10], signal.medfilt(error[cut][::10], 11), color=sns.color_palette("muted")[0], alpha=0.9, zorder=1) ax.axhline(1, linestyle="dashed", color=sns.color_palette("muted")[2], alpha=0.9, zorder=10) ax.axhline(0, linestyle="dotted", color="black", alpha=0.7) ax.set_xlim(min(wl[cut]), max(wl[cut])) ax.set_ylim(-0.2, 2) ax.tick_params(axis='x', direction='in') # ax.spines['top'].set_visible(False) ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom') # ax.axvspan(12600, 12800, color = "grey", alpha = 0.4) ax.axvspan(13500, 14500, color="grey", alpha=0.4) ax.axvspan(18000, 19500, color="grey", alpha=0.4) # Save figure for tex # pl.legend() ax4.set_ylabel(r"$F_{\lambda}$") # ax7.set_xlabel(r"$\rm{Observed\,wavelength\,}$ (\AA)") ax7.set_xlabel(r"Observed Wavelength (\AA)") pl.tight_layout() pl.subplots_adjust(hspace=0.2) pl.savefig("../document/figures/GRB121024A.pdf", dpi="figure", rasterize=True) pl.show()
def main(): #Load composite composite = np.array(np.genfromtxt(glob.glob('/Users/jselsing/Work/Projects/QuasarComposite/Selsing2015.dat')[0])) wl = composite[:,0] flux = composite[:,1] * wl / 10000 error = composite[:,2] from scipy.interpolate import InterpolatedUnivariateSpline as spline f = spline(wl[np.where(flux != 0)], flux[np.where(flux != 0)]) flux = f(wl) import scipy.signal as sig flux = sig.savgol_filter(flux, 31, 1) fig, ax = pl.subplots(figsize=(16,10)) ax.plot(wl, flux) fit_line_positions = np.genfromtxt('linelist.txt', dtype=None) linelist = [] linenames = [] for n in fit_line_positions: linelist.append(n[1]) linenames.append(n[0]) import matplotlib as mpl ax.set_xlim((700, 7200)) ax.set_ylim((0, 8)) format_axes(ax) for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(16) from matplotlib import rcParams rcParams['text.usetex']=True ax.set_xlabel(r'Hvileb$\textsf{\o}$lgel$\textsf{\oe}$ngde $\textsf{\AA}$') ax.set_ylabel(r'Skaleret flux $\lambda$F$_\lambda$') pl.tight_layout() val = [] for p in range(len(linelist)): xcoord = linelist[p] mask = (wl > xcoord - 1) & (wl < xcoord + 1) y_val = np.mean((flux)[mask]) val.append(1.2 * y_val) # change_sign = np.ones_like(val) # for n in [1, 6, 8, 11, 12, 15]: # change_sign[n] /= 3 arrow_tips = val#*change_sign lineid_plot.plot_line_ids(wl, (flux), linelist, linenames, arrow_tip=arrow_tips, ax=ax, maxiter=1000) for i in ax.lines: if '$' in i.get_label(): i.set_alpha(0.3) a = ax.findobj(mpl.text.Annotation) for i in a: if '$' in i.get_label(): i.set_size(14) pl.savefig('komposit.pdf') pl.show()
wave430 = data430.field('wavelength') flux430 = data430.field('flux') wave1 = wave430[0] flux1 = flux430[0] # Read in 750L grating wavelength and flux. infile750 = "g750l.fits" data750 = pf.getdata(infile750,1) wave750 = data750.field('wavelength') flux750 = data750.field('flux') wave2 = wave750[0] flux2 = flux750[0] # Combine all wavelength and flux arrays. # Parts of the 230L grating are not included to cut off noise. # Parts of the 430L grating are not included to cut off noise. wave_all = np.append(wave0[60:1014],wave1[87:1022]) flux_all = np.append(flux0[60:1014],flux1[87:1022]) # Define the line wavelengths and labels for lines. line_wavel = [1851.5, 2036.6, 2329.1, 2757.7, 3573.4, 3626., 3942.9, 3963.5, 4267.5, 4348.4, 3088.3, 3139.1] line_label = ["Lya", "Si IV", "Si II", "Si II", "Fe II", "Fe II", "Fe II", "Fe II", "Mg II", "Mg I", "Zn II", "Zn II"] # Plot the actual data and axes using the lineid_plot module. # Plot the labels using pylab. fsize = 18 lineid_plot.plot_line_ids(wave_all,flux_all,line_wavel,line_label) pl.ylabel("Flux [ergs/s/cm$^2$/$\AA$]",fontsize=fsize) pl.xlabel("Wavelength [$\AA$]",fontsize=fsize)
def main(): root_dir = '/Users/jselsing/Work/X-Shooter/CompositeRedQuasar/processed_data/' data_file = np.genfromtxt(root_dir+'Composite.dat') wl = data_file[:,0] mean = data_file[:,1] err_mean = data_file[:,2] wmean = data_file[:,3] err_wmean = data_file[:,4] geo_mean = data_file[:,5] median = data_file[:,6] n_spec = data_file[:,7] std = data_file[:,8] std_norm = data_file[:,9] wmean_cont = data_file[:,10] #Fitting power laws from scipy import optimize def power_law(x_tmp, a_tmp, k_tmp): tmp = a_tmp * x_tmp ** k_tmp return tmp def power_law2(x_tmp, a1_tmp, x_c, k1_tmp, k2_tmp): tmp1 = power_law(x_tmp, a1_tmp,k1_tmp)[x_tmp<x_c] scale2loc = np.argmin(np.abs(x_tmp - x_c)) a2_tmp = power_law(x_tmp[scale2loc], a1_tmp, (k1_tmp - k2_tmp)) tmp2 = power_law(x_tmp, a2_tmp,k2_tmp)[x_tmp>= x_c] return np.concatenate((tmp1,tmp2)) def power_law3(x_tmp, a_tmp, k_tmp, b_tmp): tmp = a_tmp * x_tmp ** (k_tmp + b_tmp * x_tmp) return tmp par_guess = [1, -1.70] par_guess2 = [1, 5000, -1.7, -1.7] wmean[np.where(np.isnan(wmean) == True)] = 0 mask = (wl > 1300) & (wl < 1350) | (wl > 1425) & (wl < 1475) | (wl > 5500) & (wl < 5800) | (wl > 7300) & (wl < 7500) err = ((std)[std != 0])[mask] popt, pcov = optimize.curve_fit(power_law, wl[mask], wmean_cont[mask], p0=par_guess, sigma=np.sqrt(err**2 + err_wmean[mask]**2), absolute_sigma=True, maxfev=5000) popt2, pcov2 = optimize.curve_fit(power_law2, wl[mask], wmean_cont[mask], p0=par_guess2, sigma=np.sqrt(err**2 + err_wmean[mask]**2), absolute_sigma=True, maxfev=5000) print(*popt) print(*popt2) par_guess = [1, -1.7] wl_new = wl wm = [] m = [] geo = [] med = [] #Fit np.random.seed(12345) mask = (wl_new > 1300) & (wl_new < 1350) | (wl_new > 1425) & (wl_new < 1475) | (wl_new > 5500) & (wl_new < 5800) | (wl_new > 7300) & (wl_new < 7500) for i in np.arange(10): print('Iteration: ', i) err = ((std)[std != 0])[mask] resampled_spec = np.random.normal((wmean_cont)[mask], np.sqrt(err**2 + err_wmean[mask]**2)) popt_wmean, pcov_wmean = optimize.curve_fit(power_law, wl_new[mask], resampled_spec, p0=par_guess, sigma=np.sqrt(err**2 + err_wmean[mask]**2), absolute_sigma=True) wm.append(popt_wmean) err = ((std)[std != 0])[mask] resampled_spec = np.random.normal((mean)[mask], np.sqrt(err**2 + err_mean[mask]**2)) popt_mean, pcov_mean = optimize.curve_fit(power_law, wl_new[mask], resampled_spec, p0=par_guess, sigma=np.sqrt(err**2 + err_mean[mask]**2), absolute_sigma=True) m.append(popt_mean) err = ((std)[std != 0])[mask] resampled_spec = np.random.normal((median[std != 0])[mask], err) popt_median, pcov_median = optimize.curve_fit(power_law, wl_new[mask], resampled_spec, p0=par_guess, sigma=err, absolute_sigma=True, maxfev=600) med.append(popt_median) err = ((std)[std != 0])[mask] resampled_spec = np.random.normal((geo_mean[std != 0])[mask], err) # pl.plot(wl_new[mask], resampled_spec) popt_geo, pcov_geo = optimize.curve_fit(power_law, wl_new[mask], resampled_spec, p0=par_guess, sigma=err, absolute_sigma=True, maxfev=600) geo.append(popt_geo) # pl.plot(wl, geo_mean) # pl.show() print("""Composite fit slope wmean...{0} +- {1}""".format(np.mean(wm, axis=0)[1],np.std(wm, axis=0)[1])) print("""Composite fit slope mean...{0} +- {1}""".format(np.mean(m, axis=0)[1], np.std(m, axis=0)[1])) print("""Composite fit slope median...{0} +- {1}""".format(np.mean(med, axis=0)[1], np.std(med, axis=0)[1])) print("""Composite fit slope geo...{0} +- {1}""".format(np.mean(geo, axis=0)[1], np.std(geo, axis=0)[1])) # Plotting latexify(columns=2, fig_height=7) import matplotlib.gridspec as gridspec fig = pl.figure() gs = gridspec.GridSpec(4, 1, height_ratios=[2,1,1,1]) ax1 = pl.subplot(gs[0]) ax2 = pl.subplot(gs[1]) ax3 = pl.subplot(gs[2]) ax4 = pl.subplot(gs[3]) #Plotting # ax1.plot(wl, power_law2(wl, *popt2) , 'b--') # ax1.plot(wl, power_law(wl, *popt) , 'b--') ax1.plot(wl, wmean_cont, lw = 0.5, linestyle = 'steps-mid', label='X-shooter wmean composite') nbins = len(wl) from methods import hist log_binned_wl = np.array(hist(wl,[min(wl),max(wl)], int(2*nbins),'log')) from scipy.interpolate import InterpolatedUnivariateSpline sps = InterpolatedUnivariateSpline(wl, std_norm) std_plot = smooth(medfilt(sps(log_binned_wl) , 9), window='hanning', window_len=15) wave_std = log_binned_wl ax2.plot(wave_std, std_plot, lw = 0.5, linestyle = 'steps-mid', label='Normalised variability') ax3.plot(wl, wmean_cont/medfilt(err_wmean, 5), lw = 0.5, linestyle = 'steps-mid', label = 'Signal-to-noise') ax4.plot(wl,medfilt( n_spec, 1), label='Number of spectra', lw=0.5) #Overplot lines fit_line_positions = np.genfromtxt('data/plotlinelist.txt', dtype=None) linelist = [] linenames = [] for n in fit_line_positions: linelist.append(n[1]) linenames.append(n[0]) pl.xlabel(r'Rest Wavelength [$\AA$]') ax1.set_ylabel(r'Normalised flux density F$_{\lambda}$') ax2.set_ylabel(r'Normalised Variability $\delta$F$_{\lambda}$') ax3.set_ylabel(r'S/N Ratio') ax4.set_ylabel(r'Number of spectra') ax1.semilogy() ax1.semilogx() ax1.set_xlim((1000, 11500 )) ax1.set_ylim((0.1, 750)) ax2.semilogy() ax2.semilogx() ax2.set_xlim((1000, 11500 )) ax2.set_ylim((0.001, 90)) ax3.semilogx() ax3.set_xlim((1000, 11500 )) ax4.semilogx() ax4.set_xlim((1000, 11500 )) ax4.set_ylim((0, 9)) # Formatting axes import matplotlib as mpl ax4.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax4.set_xticks([1000, 2000, 3000, 5000, 9000]) ax1.xaxis.set_major_locator(mpl.ticker.NullLocator()) ax2.xaxis.set_major_locator(mpl.ticker.NullLocator()) ax3.xaxis.set_major_locator(mpl.ticker.NullLocator()) ax1.yaxis.set_minor_locator(mpl.ticker.NullLocator()) ax2.yaxis.set_minor_locator(mpl.ticker.NullLocator()) ax1.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax1.set_yticks([0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500]) ax2.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax2.set_yticks([0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30]) ax3.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax3.set_yticks([50, 100, 150, 200, 250, 300]) ax4.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax4.set_yticks([0, 1, 2, 3, 4, 5, 6, 7, 8]) pl.tight_layout() fig.subplots_adjust(hspace=0) format_axes(ax1) format_axes(ax2) format_axes(ax3) format_axes(ax4) val = [] for p in range(len(linelist)): xcoord = linelist[p] mask = (wl > xcoord - 1) & (wl < xcoord + 1) y_val = np.mean(wmean_cont[mask]) val.append(1.5 * y_val) arrow_tips = val lineid_plot.plot_line_ids(wl, wmean_cont, linelist, linenames, arrow_tip=arrow_tips, ax=ax1) for i in ax1.lines: if '$' in i.get_label(): i.set_alpha(0.3) i.set_linewidth(0.75) for p in range(len(linelist)): xcoord = linelist[p] mask = (wl > xcoord - 1) & (wl < xcoord + 1) y_val = np.mean(wmean_cont[mask]) ax1.vlines(xcoord, ax1.get_ylim()[0], y_val, color='black',linestyle='dashed', lw=0.75, alpha=0.3) ax2.axvline(x=xcoord, color='black',linestyle='dashed', lw=0.75, alpha=0.3) ax3.axvline(x=xcoord, color='black',linestyle='dashed', lw=0.75, alpha=0.3) ax4.axvline(x=xcoord, color='black',linestyle='dashed', lw=0.75, alpha=0.3) a = ax1.findobj(mpl.text.Annotation) for i in a: if '$' in i.get_label(): i.set_size(10) fig.savefig("../documents/figs/Combined.pdf", rasterized=True, dpi=600) pl.show()
label="power-law") line3, = ax2.plot(X, Black_Body(X, s1, s2, s3) / 1e-15, '--', color=pal[2], linewidth=3, label="blackbody") ax2.tick_params(axis='x', which='both', direction='in', length=4, width=1.7) ax2.tick_params(axis='y', which='both', direction='in', length=4, width=1.7) #mostrar continuo #ax2.plot(continuox,continuoy,".",linewidth=20,color='orange') #ax2.patch.set_facecolor('gray') #ax2.patch.set_alpha(0.1) lineid_plot.plot_line_ids(X, Y, wave, label, ax=ax2, max_iter=1000) fig.set_facecolor('w') legend_properties = {'weight': 'bold'} plt.legend(handles=[line1, line2, line3], loc="upper right", prop=legend_properties) #### box superior #### ax1 = fig.add_axes([0.085, 0.800, 0.901, 0.10]) ax1.set_xticks([]) ax1.set_yticks([]) ax1.plot() ax1.patch.set_facecolor('gray') ax1.patch.set_alpha(0.05) #os.chdir('/home/usuario/INPE/agns/trabalho/sample/plots')
def plot(self, ymin = None, ymax = None, windows = None, file_name = None, title = None, ident = False): """ Plot the synthetic spectra. If the synthetic spectra were not calculated, it will calculate. Parameters ---------- ymin : lower limit on y-axis ymax : upper limit on y-axis file_name: str; Name of the file to be saved. """ self.check_if_run() # make a copy of array spectrum_copy = self.spectrum.copy() if hasattr(self, 'observation'): observation_copy = self.observation.copy() #Apply radial velocity correction if needed. if 'rv' in self.parameters: observation_copy[:, 0] *= rvcorr(self.parameters['rv']) # Apply scale correction needed if 'scale' in self.parameters: spectrum_copy[:, 1] *= self.parameters['scale'] # check if figure was already plotted if plt.fignum_exists(1): fig_exists = True plt.clf() else: fig_exists = False # Plot fig = plt.figure(num = 1) # Set axes. # If identification of the linesis requiredm set different size to axes if ident: ax = fig.add_axes([0.1, 0.1, 0.85, 0.6]) else: ax = fig.gca() # If a observation spectra is available, plot it if hasattr(self, 'observation'): ax.plot(observation_copy[:, 0], observation_copy[:, 1], c='#377eb8', label = 'Observation') # Plot synthetuc spectrum ax.plot(spectrum_copy[:, 0], spectrum_copy[:, 1], c='#e41a1c', label = 'Synthetic') # If windows were set, plot it if windows is not None: plot_windows(windows) # set labels plt.xlabel(r'Wavelength $(\AA)$') if self.parameters['relative'] != 0: if ymin is None: ymin = 0 if ymax is None: ymax = 1.05 plt.ylabel('Normalized Flux') else: plt.ylabel('Flux') # Set size of plot plt.xlim([self.parameters['wstart'], self.parameters['wend']]) if ymin is not None: plt.ylim(ymin = ymin) if ymax is not None: plt.ylim(ymax = ymax) #### # Identify lines, if required if ident: # Obtain the spectral line wavelength and identification line_wave, line_label = self.lineid_select(ident) lineid_plot.plot_line_ids(spectrum_copy[:, 0], spectrum_copy[:, 1], line_wave, line_label, label1_size = 10, extend = False, ax = ax, box_axes_space = 0.15) plt.legend(fancybox = True, loc = 'lower right') if title is not None: plt.title(title, verticalalignment = 'baseline') # Plot figure if not fig_exists: fig.show() else: fig.canvas.draw() # Save file if file_name is not None: plt.savefig(file_name, dpi = 100)