简体   繁体   English

在不使用 Hist 的情况下在 Matlab 中生成直方图

[英]Producing a histogram in Matlab with out using Hist

I am using histograms in Matlab to look at the distribution of some data from my experiments.我在 Matlab 中使用直方图来查看我的实验中一些数据的分布。 I want to find the mean distribution (mean height of the bars) from a group of tests then produce an average histogram.我想从一组测试中找到平均分布(条形的平均高度),然后生成一个平均直方图。

By using this code:通过使用此代码:

data = zeros(26,31);

for i = 1:length(files6)
    x = csvread(files6(i).name);
    
    x = x(1:end,:);
    time = x(:,1);
    variable = x(:,3);
    
    thing(:,1) = x(:,1);
    thing(:,2) = x(:,3);
    figure()
    binCenter = {0:tbinstep:tbinend 0:varbinstep:varbinend};
    hist3(thing, 'Ctrs', binCenter, 'CDataMode','auto','FaceColor','interp');
    colorbar
    
    [N,C] = hist3(thing, 'Ctrs', binCenter);
    data = data + N;
    
    clearvars x time variable
end
    
avedata = data / i;

I can find the mean of N, which will be the Z value for the plot (histogram) I want, and I have X,Y (which are the same for all tests) from:我可以找到 N 的平均值,这将是我想要的 plot(直方图)的 Z 值,并且我有 X,Y(所有测试都相同)来自:

x = 0:tbinstep:tbinend;
y = 0:varbinstep:varbinend;

But how do I bring these together to make the graphical out that shows the average height of the bars?但是我如何将这些组合在一起以制作显示条形平均高度的图形? I can't use hist3 again as that will just calculate the distribution of avedata.我不能再次使用 hist3 ,因为它只会计算 avedata 的分布。

AT THE RISK OF STARTING AN XY PROBLEM using bar3 has been suggested, but that asks the question "how do I go from 2 vectors and a matrix to 1 matrix bar3 can handle? Ie how do I plot x(1), y(1), avedata(1,1) and so on for all the data points in avedata?"有人建议使用 bar3启动 XY 问题的风险,但这会问一个问题“我如何从 2 个向量和一个矩阵到 1 个矩阵 bar3 的 go 可以处理?即我如何处理 plot x(1), y( ), avedata(1,1) 等是否适用于 avedata 中的所有数据点?”

TIA TIA

By looking at hist3 source code in matlab r2014b, it has his own plotting implemented inside that prepares data and plot it using surf method.通过查看 matlab r2014b 中的hist3源代码,它在内部实现了自己的绘图,准备数据和 plot 它使用surf方法。 Here is a function that reproduce the same output highly inspired from the hist3 function with your options ( 'CDataMode','auto','FaceColor','interp' ).这是一个 function,它再现了相同的 output,灵感来自hist3 function 以及您的选项( 'CDataMode','auto','FaceColor','interp' )。 You can put this in a new file called hist3plot.m :您可以将其放入名为hist3plot.m的新文件中:

function [ h ] = hist3plot( N, C )
%HIST3PLOT Summary of this function goes here
%   Detailed explanation goes here

xBins = C{1};
yBins = C{2};

% Computing edges and width
nbins = [length(xBins), length(yBins)];
xEdges = [0.5*(3*xBins(1)-xBins(2)), 0.5*(xBins(2:end)+xBins(1:end-1)), 0.5*(3*xBins(end)-xBins(end-1))];
yEdges = [0.5*(3*yBins(1)-yBins(2)), 0.5*(yBins(2:end)+yBins(1:end-1)), 0.5*(3*yBins(end)-yBins(end-1))];
xWidth = xEdges(2:end)-xEdges(1:end-1);
yWidth = yEdges(2:end)-yEdges(1:end-1);
del = .001; % space between bars, relative to bar size
% Build x-coords for the eight corners of each bar.
xx = xEdges;
xx = [xx(1:nbins(1))+del*xWidth; xx(2:nbins(1)+1)-del*xWidth];
xx = [reshape(repmat(xx(:)',2,1),4,nbins(1)); NaN(1,nbins(1))];
xx = [repmat(xx(:),1,4) NaN(5*nbins(1),1)];
xx = repmat(xx,1,nbins(2));
% Build y-coords for the eight corners of each bar.
yy = yEdges;
yy = [yy(1:nbins(2))+del*yWidth; yy(2:nbins(2)+1)-del*yWidth];
yy = [reshape(repmat(yy(:)',2,1),4,nbins(2)); NaN(1,nbins(2))];
yy = [repmat(yy(:),1,4) NaN(5*nbins(2),1)];
yy = repmat(yy',nbins(1),1);
% Build z-coords for the eight corners of each bar.
zz = zeros(5*nbins(1), 5*nbins(2));
zz(5*(1:nbins(1))-3, 5*(1:nbins(2))-3) = N;
zz(5*(1:nbins(1))-3, 5*(1:nbins(2))-2) = N;
zz(5*(1:nbins(1))-2, 5*(1:nbins(2))-3) = N;
zz(5*(1:nbins(1))-2, 5*(1:nbins(2))-2) = N;
% Plot the bars in a light steel blue.
cc = repmat(cat(3,.75,.85,.95), [size(zz) 1]);
% Plot the surface
h = surf(xx, yy, zz, cc, 'CDataMode','auto','FaceColor','interp');
% Setting x-axis and y-axis limits
xlim([yBins(1)-yWidth(1) yBins(end)+yWidth(end)]) % x-axis limit
ylim([xBins(1)-xWidth(1) xBins(end)+xWidth(end)]) % y-axis limit

end

You can then call this function when you want to plot outputs from Matlab's hist3 function.然后,当您想要从 Matlab 的hist3 function 输出 plot 时,您可以调用此 function。 Note that this can handle non uniform positionning of bins:请注意,这可以处理箱的非统一定位:

close all; clear all;

data = rand(10000,2);
xBins = [0,0.1,0.3,0.5,0.6,0.8,1];
yBins = [0,0.1,0.3,0.5,0.6,0.8,1];

figure()
hist3(data, {xBins yBins}, 'CDataMode','auto','FaceColor','interp')
title('Using hist3')

figure()
[N,C] = hist3(data, {xBins yBins});
hist3plot(N, C); % The function is called here
title('Using hist3plot')

Here is a comparison of the two outputs:这是两个输出的比较:

使用 hist3 函数 使用 hist3plot 函数

So if I understand your question and code correctly, you are plotting the distribution of multiple experiments' data as histograms, then you want to calculate the average shape of all the previous histograms.因此,如果我正确理解了您的问题和代码,您将多个实验数据的分布绘制为直方图,那么您想要计算所有先前直方图的平均形状。

I usually avoid giving approaches the asker isn't explicitly asking for, but for this one I must comment that it is a very strange thing to do.我通常避免给出提问者没有明确要求的方法,但对于这个我必须评论说这是一件非常奇怪的事情。 I've never heard of calculating the average shape of multiple histograms before.我以前从未听说过计算多个直方图的平均形状。 So just in case , you could simply append all your experiment's data into a single variable, and plot a normalized histogram of that using histogram2 .因此,以防万一,您可以简单地将 append 所有实验数据放入一个变量中,并 plot 使用 histogram2 的归一化histogram2 This code outputs a relative frequency histogram .此代码输出相对频率直方图 (Other normalization methods ) (其他归一化方法

% Append all data in a single matrix
x = []
for i = 1:length(files6)
    x = [x; csvread(files6(i).name)];
end

% Plot normalized bivariate histogram, normalized
xEdges = 0:tbinstep:tbinend;
yEdges = 0:varbinstep:varbinend;
histogram2(x(:,1), x(:,3), xEdges, yEdges, 'Normalize', 'Probability')

Now, if you really are looking to draw the average shape of multiple histograms, then yes, use bar3 .现在,如果您真的想绘制多个直方图的平均形状,那么可以,使用bar3 Since bar3 doesn't accept an (x,y) value argument, you can follow the other answer, or modify the XTickLabel and YTickLabel property to match whatever your bin range is, afterwards.由于bar3不接受 (x,y) 值参数,因此您可以遵循其他答案,或修改XTickLabelYTickLabel属性以匹配您的 bin 范围。

... % data = yourAverageData;

% Save axis handle to `h`
h = bar3(data);

% Set property of axis
h.XTickLabels = 0:tbinstep:tbinend;
h.YTickLabels = 0:varbinstep:varbinend;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM