Splitting two nearly overlapping curves
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Vahid Askarpour
el 2 de Jun. de 2025
Comentada: Les Beckham
el 3 de Jun. de 2025
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 comentarios
Respuesta aceptada
Star Strider
el 2 de Jun. de 2025
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 comentario
Star Strider
el 2 de Jun. de 2025
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')
.
Más respuestas (1)
Image Analyst
el 3 de Jun. de 2025
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 comentarios
Les Beckham
el 3 de Jun. de 2025
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.
Ver también
Categorías
Más información sobre Install Products en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!