Splitting two nearly overlapping curves
6 次查看(过去 30 天)
显示 更早的评论
The attached x-y plot has a main peak on the right and a second peak (shoulder) on the left. Is there a Matlab function that can give the expressions for the two Gaussians that can add up to produce the attached plot?
Thanks,
Vahid
0 个评论
采纳的回答
Star Strider
2025-6-2
It might be possible, however it would likely require a lot of manual experimentation.
I experimented with an approach that involved subtracting the first identified Gaussian from the summed curve and then identifying the second Gaussian, however the results were not reliable. (Attempting to identify both gaussians from the original summed values without modifying them first yielded the same result even given different initial estimates.)
x = linspace(0, 10, 250);
g1 = 0.7*exp(-(x-3.5).^2);
g2 = exp(-(x-5).^2);
g12 = g1+g2;
figure
plot(x, g1)
hold on
plot(x, g2)
plot(x, g12)
hold off
grid
dgdx = gradient(g12);
[pks,locs] = findpeaks(dgdx)
xvals = x(locs)
figure
plot(x, dgdx)
grid
gmdl = @(b,x) b(1)*exp(-(x-b(2)).^2);
[B11,fv1] = fminsearch(@(b)norm(g12-gmdl(b,x)), [max(g12)*0.5; x(locs(1))*0.5])
[B12,fv2] = fminsearch(@(b)norm(g12-gmdl(B11,x)-gmdl(b,x)), [max(g12); x(locs(2))*1.5])
figure
plot(x, gmdl(B11,x))
hold on
plot(x, gmdl(B12,x))
hold off
grid
[B21,rn1] = lsqcurvefit(gmdl, [max(g12)*0.5; x(locs(1))*0.5], x, g12)
[B22,rn2] = lsqcurvefit(gmdl, [max(g12); x(locs(2))*1.5], x, g12-gmdl(B21,x))
figure
plot(x, gmdl(B21,x))
hold on
plot(x, gmdl(B22,x))
hold off
grid
I doubt that there is a way to autimatically identify both curves, however manualloy experimenting and then subtracting the first identified curve could work..
.
1 个评论
Star Strider
2025-6-2
There is another option I just thought of, howevr it may not be uniformly applicable to all such problems. It requires that one limb of the combined curve is completely defined by only one of the Gaussians. The approach is then to fit only that part of the curve, use that to define one Gaussian, subtract it from the summed Gaussian, and then fit that result.
The result is slightly better than the initial approach --
x = linspace(0, 10, 250);
g1 = 0.7*exp(-(x-3.5).^2);
g2 = exp(-(x-5).^2);
g12 = g1+g2;
figure
plot(x, g1)
hold on
plot(x, g2)
plot(x, g12)
hold off
grid
[g12_max,mx_idx] = max(g12)
high_end = x >= x(mx_idx);
x_high = x(high_end);
y_high = g12(high_end);
gmdl = @(b,x) b(1)*exp(-(x-b(2)).^2);
[B1,fv1] = fminsearch(@(b)norm(g12-gmdl(b,x)), [g12_max; x(mx_idx)])
new_g12 = g12 - gmdl(B1,x);
[new_max,new_max_idx] = max(new_g12)
[B2,fv2] = fminsearch(@(b)norm(g12-gmdl(B1,x)-gmdl(b,x)), [max(g12); x(new_max_idx)])
g1f = gmdl(B1,x);
g2f = gmdl(B2,x);
figure
plot(x, g1f, DisplayName="First Estimated Gaussian")
hold on
plot(x, g2f,DisplayName="Second Estimated Gaussian")
plot(x, g1f+g2f, DisplayName="Sum Of Estimated Gaussians")
plot(x, g12, '--k', DisplayName="Original Summed Gaussians")
hold off
grid
legend(Location='best')
.
更多回答(1 个)
Image Analyst
2025-6-3
I have a demo that will fit multiple (6 in the demo) Gaussians to a curve. Change the variable in the demo if you want some other number other than 6.

Also are attached a couple of other Gaussian fitting demos such as this one that fits two Gaussians sitting atop a linear ramp using fitnlm .

2 个评论
Les Beckham
2025-6-3
FYI, @Vahid Askarpour: you can't accept two answers, but you can definitely Vote for the second one to show your appreciation. Just click the Vote button (with the thumbs-up icon) at the top of the answer.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Install Products 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!