Manipulating cfit data/curve to shift fit line along xaxis

16 views (last 30 days)
Hello, I would like to know if there is a way to plot a cfit variable shifted horizontally with reference to other data.
Below in figure 1, I have illustrated a set of raw data to which I'd like to fit the red portion to
y=a*exp(-x/b)+c
After creating an x and y variable that represent just the red portion of figure 1 as if that data started at x=0, I went to the curve fitting app to select good starting points and tolerances. By selecting "generate code" and running it, I could then access the cfit variable.
Figure 2 shows the full data from figure 1 plotted with cfit where, clearly, because the data that was fit had been edited to start at x=0, the cfit line also begins at x=0. As you can see, my data has three peaks. In this example, they happen to all look similar, but that will not always be the case.
I want to have the entirety of the raw data shown with a fit for each peak traced over the peak the fit was generated from. Effectivley, I just need to plot the cfit variable shifted horizontally. Does anyone have advice on how to accomplish this?
  6 Comments
Megan Renny
Megan Renny on 29 Apr 2022
If by "consolodation" you meant overlaying each cycle like a scatter plot and fitting to a situation where each x value would have one y value per cycle, then no, I am just doing what Mathieu NOE suggested.
I would not say my question is quite answerd, as I belive manipulating the cfit variable from the the fit function in my code would be easiest if it is possible. Being able to use something like
plot(cfit,'ShiftFit',[xshift yshift],x,y)
would be ideal if there is a native way to do this that I don't know of. Having to generate yfit values for each cycle for each data set would introduce extra clutter to my code that I would like to avoid if possible.
Matt J
Matt J on 29 Apr 2022
Edited: Matt J on 29 Apr 2022
I am just doing what Mathieu NOE suggested.
If so, then the syntax,
plot(cfit,'ShiftFit',[xshift yshift],x,y)
would not be applicable because here you have only one cfit object, whereas what Mathieu proposes (and what I have also implemented for you in my original answer below), is to perform 3 separate fits, one for each cycle.
Having to generate yfit values for each cycle for each data set would introduce extra clutter to my code that I would like to avoid if possible.
It wouldn't, because you would just put the code that implements it for one data set into its own separate function and repeatedly call that function in a loop. There is no reason it should occupy more than one line in your main code.

Sign in to comment.

Answers (1)

Matt J
Matt J on 29 Apr 2022
Edited: Matt J on 29 Apr 2022
Download these files,
and then do like in the following:
x=x(:); y=y(:); %ensure columns
G=groupTrue([diff(x)>0 & diff(y)>=0;0]);
[starts,stops]=groupLims(G,1); %starting and stopping indices of each segment
N=numel(starts);
plot(x,y); hold on
for i=1:N
xx=x(starts(i):stops(i))-x(starts(i));
yy=y(starts(i):stops(i));
fobj{i}=fit(xx,yy,'exp1');
plot(xx+x(starts(i)),fobj{i}(xx));
end
hold off
  3 Comments
Megan Renny
Megan Renny on 29 Apr 2022
Hi thank you again for your kind feedback and advcie. I think my issue is not in trying to fit the data. I have an algorithm that takes the user's set experimental parameters from another script and uses them to find the limits of which parts of the data set to fit.
The issue I was having was just trying to visually see how good the fit reflected the data by graphing the fitline over the peak it came from for the purposes of reviewing the fit quality of 1000+ data sets in app designer!
Matt J
Matt J on 29 Apr 2022
My answer gives that to you. You can remove the line,
fobj=fit( cell2mat(xx), cell2mat(yy) ,'exp1');
if you've come by your fobj in some other manner.

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!