Manipulating cfit data/curve to shift fit line along xaxis

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

hello
why not extract the three segments (using the negative and positive spikes as start and en points) and then use a command line fit code for each one ?
this way you have the "optimal" fit for each segment without the need to "shift" one model for the next segment.
can you share the data ?
Or, would it make sense to shift all 3 segments to start at x=0, consolidate the (x,y) data, and fit a single set of a,b,c parameters to the consolidated data?
Hi, that's exactly what I'm doing! I am extracting the red portion for each of the 3 curves [or in some cases 5] and gathering the 3 fit parameters. The issue is that I'm doing this for over 1000 data sets that look like this, where the starting points of the next data set are the values obtained by the previous data set's fit. Because of this, sometimes, the fit begins to deviate a bit.
I am using app designer so that I can effectivley scroll through the data sets to look at them. I would LIKE to be able to look at the fits over the peaks as well so that I can determine about where the fit needs to be redone if ti deviates.
The issue is that each data sets has multiple cycles. I could just have Dataset1.cycleA in the listbox, but that seems like an unecessary complexity for literally just trying to shift the graph over a bit.
I think will try graphing the function with the cfit parameters included, but instead of using x, using x-xshift if it doesn't seem like a quick and easy thing to do using the actual cfit variable.
Hi, that's exactly what I'm doing!
Which one? @Mathieu NOE and I outlined two different ideas
I think will try graphing the function with the cfit parameters included, but instead of using x, using x-xshift if it doesn't seem like a quick and easy thing to do using the actual cfit variable.
So your question is withdrawn?
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.
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)

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

Or, would it make sense to shift all 3 segments to start at x=0, consolidate the (x,y) data, and fit a single set of a,b,c parameters to the consolidated data?
If this is what you want, then do instead,
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);
for i=1:N
xx{i}=x(starts(i):stops(i))-x(starts(i));
yy{i}=y(starts(i):stops(i));
end
fobj=fit( cell2mat(xx), cell2mat(yy) ,'exp1');
plot(x,y); hold on
for i=1:N
plot(xx{i}+x(starts(i)),fobj(xx{i}));
end
hold off
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!
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.

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products

Release

R2020b

Asked:

on 28 Apr 2022

Edited:

on 29 Apr 2022

Community Treasure Hunt

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

Start Hunting!