Skip to content

Instantly share code, notes, and snippets.

@FilipDominec
Created June 21, 2017 16:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FilipDominec/aefff77ddbea068ad5d343e69495f51d to your computer and use it in GitHub Desktop.
Save FilipDominec/aefff77ddbea068ad5d343e69495f51d to your computer and use it in GitHub Desktop.
Example of singular value decomposition applied or real spectral data, ready to be copied&pasted into https://github.com/FilipDominec/plotcommander
plotstyle = "basis"
#plotstyle = "amplitude"
decimatex = 20
ncomponents = 5
a = ys[:, ::decimatex]
xs = xs[:, ::decimatex]
U, s, V = np.linalg.svd(a, full_matrices=True)
if plotstyle=="basis":
for x, y, label in zip(xs[:ncomponents], V[:ncomponents], range(ncomponents)):
ax.plot(x, y, label="SVD component %d" % (label+1), lw=5*.5**label)
ax.set_xlabel(xlabelsdedup)
ax.set_ylabel(ylabelsdedup)
if plotstyle=="amplitude":
for y, label in zip(np.dot(U,np.diag(s)).T, range(ncomponents)):
ax.plot(range(U.shape[0]), y, marker='s', label="SVD component %d" % (label+1), lw=5*.5**label)
ax.set_xlabel('dataset number')
ax.set_ylabel('SVD component amplitude')
ax.set_title('')
ax.legend(loc='best', prop={'size':10})
@FilipDominec
Copy link
Author

FilipDominec commented Jun 21, 2017

Scientific data are often measured as a function of one or more parameters. In this case, I irradiated a semiconductor sample with an electron beam in a SEM and registered the optical emission spectra. The plots are overlapping and are quite hard to understand:

svd1

However, there is clearly some complex dependence on the voltage! I could set up some fitting to determine how the spectral peaks grow, shift and/or broaden, but SVD can do a similar job, and it is fully automatic requiring no prior knowledge of how the data should look like. In a nutshell, SVD finds the optimum basis functions for the whole dataset, orders them starting from the most prominent basis function, and expresses each of the spectral curves as a sum of these. The first five basis functions are as such:

svd2

Now one can change the code as such:

#plotstyle = "basis"
plotstyle = "amplitude"

to retrieve the respective amplitudes of each basis function and for each data file. From the dependence of first three amplitudes on the acceleration voltage, it is easy to show how

  • the main spectral peak grows (blue, component 1)
  • how it shifts (orange, component 2)
  • how it gets narrower and how another peak emerges at shorter wavelength when electron acceleration voltage exceeds 15 kV (green, component 3) etc.
  • Higher numbered components tend to enable less physical interpretation and are mostly noise.

svd3

The presented code is just a snippet of python code; to use it, either select your data files in plotcommander (https://github.com/FilipDominec/plotcommander), or write a simple standalone python script that loads the data arrays into the xs and ys variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment