我必须在一张图上绘制10个频率分布。为了保持整洁,我想避免使用箱子进行直方图,并且更喜欢使用符合每个直方图的轮廓的线条。
我尝试了以下
[counts, bins] = hist(data);
plot(bins, counts)
但是这给了我一个非常不精确和锯齿状的线。
我读到了ksdensity,这给了我一条漂亮的曲线,但它改变了我的y轴的缩放比例,我需要能够从y轴读取频率。
你能推荐别的吗?
答案 0 :(得分:3)
您正在使用柱状图的默认二进制数,我将假设您的核密度估算计算。
根据您所拥有的数据点数量,这肯定不是最佳的,正如您所发现的那样。首先要尝试的是计算optimum bin width以提供最平滑的曲线,同时尽可能保留基础PDF。 (另请参阅here,here和here);
如果您仍然不喜欢结果图的平滑程度,可以尝试使用bins
的{{1}}输出作为hist
的进一步输入。也许是这样的:
ksdensity
我没有您的数据,因此您可能需要稍微玩一下参数才能获得您想要的数据。
或者,您可以尝试通过从[kcounts,kbins] = ksdensity(data,bins,'npoints',length(bins));
获得的点数拟合spline
并将其绘制出来。
一些代码:
hist
结果:
请注意"最佳" bin width保留了一些精细的分布结构(我必须运行几次以获得尖峰),而data = randn(1,1e4);
optN = sshist(data);
figure(1)
[N,Center] = hist(data);
[Nopt,CenterOpt] = hist(data,optN);
[f,xi] = ksdensity(data,CenterOpt);
dN = mode(diff(Center));
dNopt = mode(diff(CenterOpt));
plot(Center,N/dN,'.-',CenterOpt,Nopt/dNopt,'.-',xi,f*length(data),'.-')
legend('Default','Optimum','ksdensity')
给出一个平滑的曲线。根据您在数据中寻找的内容,这可能是好的也可能是坏的。
答案 1 :(得分:2)
如何使用splines进行插值?
nbins = 10; %// number of bins for original histogram
n_interp = 500; %// number of values for interpolation
[counts, bins] = hist(data, nbins);
bins_interp = linspace(bins(1), bins(end), n_interp);
counts_interp = interp1(bins, counts, bins_interp, 'spline');
plot(bins, counts) %// original histogram
figure
plot(bins_interp, counts_interp) %// interpolated histogram
示例:让
data = randn(1,1e4);
原始直方图:
插值:
按照您的代码,上图中的y轴给出计数,而不是概率密度。要获得概率密度,您需要进行标准化:
normalization = 1/(bins(2)-bins(1))/sum(counts);
plot(bins, counts*normalization) %// original histogram
plot(bins_interp, counts_interp*normalization) %// interpolated histogram
检查:总面积应约为1:
>> trapz(bins_interp, counts_interp*normalization)
ans =
1.0009