【问题标题】:How to fit a curve on a discrete sequence data (stem) in Matlab?如何在 Matlab 中的离散序列数据(茎)上拟合曲线?
【发布时间】:2019-09-11 04:20:38
【问题描述】:

我有两个矩阵FDXTDX(两个类)和dim: 2xnFDX(1, :)FDX(2, :) 分别是对象的数量和它们的平均值(也适用于TDX)。我使用stem 绘制上述离散序列数据,现在我想显示一条曲线而不是它的线,以从点(如 pdf)或(如将曲线拟合到直方图)创建密度图,以便更好地比较两个班。

有什么方法可以在 Matlab 中的 stem 的以下图上拟合曲线?

我还看到了一些链接,例如 link1link2,但它们是关于直方​​图或连续数据的。另外,我使用了fit 曲线(link 代替了词干,但两条创建的曲线令人困惑。

例子:

FDX = [9,12,7,7,8,4,10,8,5,9,10; 0.626023067402372,0.647560923068733,0.266314729708634,0.512920709657816,0.408389652529404,0.444588941849425,0.800367166464757,1.28429713933315,0.391101796334982,0.219880153736852,0.439931802866314];
TDX = [1,1,2,1,1,1,1,1,1,1,1; 0.0888514059469934,0.0730468099283854,0.246560340244561,0.300711548987410,0.0871198693779434,3.11190476190476,0.185185185185183,0.246964650258985,0.113415750915749,0.132034632034618,0.201388888888900];


f1 = fit(TDX(2, :)', TDX(1, :)','smoothingspline');
plot(f1,'b', TDX(2, :)', TDX(1, :)','oc');
hold on
% stem(TDX(2, :), TDX(1, :),'*c');
grid on   
hold on


f2 = fit(FDX(2, :)', FDX(1, :)','smoothingspline');
plot(f2,'r',FDX(2, :)', FDX(1, :)','om');
hold on
% stem(FDX(2, :), FDX(1, :),'*m');
grid on   
hold off

title('Displacement Curve X', 'Units', 'normalized', 'Position', [2.5, 1.1, 0]); 
xlabel('Mean')
ylabel('Number of Objs')
legend('MeanTDX','MeanFDX')
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);

在下面,有两个图FDXTDX,尺寸分别为2x4322x114。 和

词干输出:

拟合输出:

我想要的模型:

【问题讨论】:

  • 您是拟合还是只是根据数据用样条线插值\平滑?我没有看到合适的模型或表达式?
  • 我建议尝试组合幂和指数方程,“y = a * pow(x, b) * exp(c * x)”。良好的拟合初始参数估计值似乎是 a = 5.0E+03、b = 3.1E+00 和 c = -5.6E+00
  • @James Phillips:我无法定义“y”,因为 x 和 y 都有。例如:y = FDX(1,:);和x = FDX(2,:);也适用于TDX
  • 我明白了 - 我只是使用了从发布的散点图中提取的数据,它具有 x 和 y 数据的外观。
  • @bla:我不知道需要哪种方法,但我想要一个模型来显示点的密度(两个类的两条曲线)。我还在 Mathwork 中看到了 csaps 函数和 pchip 函数,但我不知道如何将它们用于我的向量。我为我的数据编写了一个脚本,发生了错误,The data sites should be distinct

标签: matlab curve-fitting curve


【解决方案1】:

您可以使用曲线拟合工具箱,它提供了非常好的功能。由于您没有指定要使用的特定模型,我只是假设您具有正态分布的数据(类似于您的“主干输出”图像)。但是您可以使用fittype() 函数基本上指定您想要的任何模型。检查here 以获取有关其参数的信息。还要考虑您选择的模型,它应该合理地代表数据。

为简单起见,我选择使用一些示例数据,但希望它也适用于您的真实数据和您想要的模型。

points = 100;
x = -points:points;
y = normpdf(x, -20, 20);
n = -0.01+2*0.01*rand(size(x));
y = y+n; % invent some noisy normal distributed test data

[xData, yData] = prepareCurveData(x, y);

% Set up fittype and options. (here assume normal dist)
ft = fittype(@(u, s, x)(1/(s*sqrt(2*pi))*exp(-(x-u).^2/(2*s^2))), 'coefficients', {'u', 's'}, 'independent', 'x', 'dependent', 'y')

% Fit model to data.
[fitresult, gof] = fit(xData, yData, ft);

% Plot fit with data.
figure
h = plot(fitresult, xData, yData);
legend(h, 'data', 'fit', 'Location', 'NorthEast');
xlabel('x'); ylabel('y'); grid on

% Extract the equation(ft) and the coefficients
coeffnames(fitresult)
coeffvalues(fitresult)

如果您使用 stem 来显示数据,这也应该有效。

【讨论】:

  • 我用你的脚本来处理我的数据,但曲线不太适合这些点。这是一条低峰度曲线。
  • @eli 我明白了。这是可能的,但取决于您的数据。曲线拟合找到数据点和曲线之间误差最小的曲线,这并不意味着曲线将“高于”您拥有的点。这种拟合方法通常也是需要的,因为生成的曲线最好地描述了数据(= 最小误差)。在您添加到问题中的所需曲线的新图像中,您将曲线绘制在几乎所有点的上方,因此总误差不会很小。我想这不是你想要的。
  • 是的,我想要的曲线的新图像已编辑。您的建议是我想要的曲线,但我的数据的峰度很低。但我想知道,构造具有正态分布的直方图的“histfit”函数与我的问题有什么区别?我的数据是否可以使用“histfit”之类的函数?
  • 我想你也可以使用histfit来达到你的目的。但总的来说histfit 的缺点是它只适合分布,而我的代码可以适合任何函数/模型。我假设如果您将histfit 与正态分布一起使用,它与我直接应用于您的数据的代码非常相似(两者都适合您的数据的正态分布)。但我不能 100% 确定您在 histfit 中选择的引脚数是否会影响您的结果。所以也许fitdist 更适合你。
猜你喜欢
  • 2016-10-06
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多