在三维图中表示三个变量

时间:2011-07-20 00:35:27

标签: matlab 3d

我在处理三个变量的第三维图时遇到问题。

我有三个矩阵:温度,湿度和功率。在一年中,每小时,测量上述每一个。因此,我们为每个矩阵365 * 24 = 8760点。然后,每天采取一个平均点。所以,

Tavg = 365 X 1
Havg = 365 X 1
Pavg = 365 X 1

在电气观点上,功率取决于温度和湿度。我想用三维图发现这种关系。

我尝试在MATLAB中使用mesh,meshz,surf,plot3和许多其他命令但不幸的是我无法得到我想要的东西。例如,让我们前10天。在这里,每天都有平均温度,平均湿度和平均功率。

Tavg = [18.6275
   17.7386
   15.4330
   15.4404
   16.4487
   17.4735
   19.4582
   20.6670
   19.8246
   16.4810];

Havg = [75.7105
   65.0892
   40.7025
   45.5119
   47.9225
   62.8814
   48.1127
   62.1248
   73.0119
   60.4168];

Pavg = [13.0921
   13.7083
   13.4703
   13.7500
   13.7023
   10.6311
   13.5000
   12.6250
   13.7083
   12.9286];

我如何通过三维图表来表示这些矩阵?

5 个答案:

答案 0 :(得分:1)

挑战在于三维表面绘图功能(网格,冲浪等)正在寻找z值的二维矩阵。因此,要使用它们,您需要根据数据构建这样的矩阵。

目前,数据是三维空间中的点海,因此,您必须将这些点映射到曲面。一种简单的方法是将X-Y(温度 - 湿度)平面分成箱,然后取所有Z(功率)数据的平均值。下面是一些示例代码,它使用accumarray()来计算每个bin的平均值:     %指定箱尺寸     Tbin = 3;     Hbin = 20;

% Create binned average array
% First create a two column array of bin indexes to use as subscripts
subs = [round(Havg/Hbin)+1, round(Tavg/Tbin)+1];

% Now create the Z (power) estimate as the average value in each bin
Pest = accumarray(subs,Pavg,[],@mean);

% And the corresponding X (temp) & Y (humidity) vectors
Tval = Tbin/2:Tbin:size(Pest,2)*Tbin;
Hval = Hbin/2:Hbin:size(Pest,1)*Hbin;

% And create the plot
figure(1)
surf(Tval, Hval, Pest)
xlabel('Temperature')
ylabel('Humidity')
zlabel('Power')
title('Simple binned average')

xlim([14 24])
ylim([40 80])

图表有点粗糙(由于我是新手,因此无法发布图片),因为我们只有几个数据点。我们可以通过将其值设置为NaN来删除任何空容器来增强可视化。此外,分箱方法隐藏了Z(功率)数据的任何变化,因此我们还可以使用plot3覆盖区域点云,而无需绘制连接线。 (再没有图像b / c我是新的)

最终情节的附加代码:     %%扩展图

% Remove zeros (useful with enough valid data)
%Pest(Pest == 0) = NaN;

% First the original points
figure(2)
plot3(Tavg, Havg, Pavg, '.')

hold on
% And now our estimate
% The use of 'FaceColor' 'Interp' uses colors that "bleed" down the face
% rather than only coloring the faces away from the origin
surfc(Tval, Hval, Pest, 'FaceColor', 'Interp')

% Make this plot semi-transparent to see the original dots anb back side
alpha(0.5)

xlabel('Temperature')
ylabel('Humidity')
zlabel('Power')
grid on

title('Nicer binned average')
xlim([14 24])
ylim([40 80])

答案 1 :(得分:0)

我认为您要求表面适合您的数据。曲线拟合工具箱处理得很好:

% Fit model to data.
ft = fittype( 'poly11' );
fitresult = fit( [Tavg, Havg], Pavg, ft);

% Plot fit with data.
plot( fitresult, [xData, yData], zData );
legend( 'fit 1', 'Pavg vs. Tavg, Havg', 'Location', 'NorthEast' );
xlabel( 'Tavg' );
ylabel( 'Havg' );
zlabel( 'Pavg' );
grid on

如果您没有曲线拟合工具箱,则可以使用反斜杠运算符:

% Find the coefficients.
const = ones(size(Tavg));
coeff = [Tavg Havg const] \ Pavg; 

% Plot the original data points
clf
plot3(Tavg,Havg,Pavg,'r.','MarkerSize',20);
hold on

% Plot the surface.
[xx, yy] = meshgrid( ...
    linspace(min(Tavg),max(Tavg)) , ...
    linspace(min(Havg),max(Havg)) ); 
zz = coeff(1) * xx + coeff(2) * yy + coeff(3);
surf(xx,yy,zz)
title(sprintf('z=(%f)*x+(%f)*y+(%f)',coeff))
grid on
axis tight

这两个都适合线性多项式表面,即平面,但你可能想要使用更复杂的东西。这两种技术都可以适应这种情况。有关此主题的更多信息,请访问mathworks.com:How can I determine the equation of the best-fit line, plane, or N-D surface using MATLAB?

答案 2 :(得分:0)

你可能想看看Delaunay三角测量:

tri = delaunay(Tavg, Havg);
trisurf(tri, Tavg, Havg, Pavg);

使用您的示例数据,此代码会生成一个有趣的“表面”。但我相信这是做你想做的另一种方式。

答案 3 :(得分:0)

您也可以尝试使用MATLAB Central的John D'Errico的GridFit工具。该工具生成的表面类似于数据点之间的插值(由MATLAB的griddata完成),但结果更清晰,因为它可以平滑生成的曲面。概念上,对于附近或重叠的X,Y坐标的多个数据点被平均以产生平滑的结果而不是嘈杂的“涟漪”。该工具还允许在数据点之外进行一些推断。这是一个代码示例(假设已经安装了GridFit工具):

%Establish points for surface
num_points = 20;
Tval = linspace(min(Tavg),max(Tavg),num_points);
Hval = linspace(min(Havg),max(Havg),num_points);

%Do the fancy fitting with smoothing
Pest = gridfit(Tavg, Havg, Pavg, Tval, Hval);

%Plot results
figure(5)
surfc(XI,YI,Pest, 'FaceColor', 'Interp')

为了制作更好的情节,你可以添加标签,一些透明度和覆盖原始点:

alpha(0.5)
hold on
plot3(Tavg,Havg,Pavg,'.')

xlabel('Temperature')
ylabel('Humidity')
zlabel('Power')
grid on

title('GridFit')

PS:@upperBound:感谢Delaunay三角测量技巧。如果你想要了解每一点,这似乎是要走的路。我是新手,所以无法发表评论。

答案 4 :(得分:0)

以下是您的解决方案:

  1. 保存/写入Myplot3D功能

    function [x,y,V]=Myplot3D(X,Y,Z)
    x=linspace(X(1),X(end),100);
    y=linspace(Y(1),Y(end),100);
    [Xt,Yt]=meshgrid(x,y);
    V=griddata(X,Y,Z,Xt,Yt);
    
  2. 从命令行(或脚本)中调用以下内容

    [Tavg_new,Pavg_new,V]=Myplot3D(Tavg,Pavg,Havg);
    surf(Tavg_new,Pavg_new,V)
    colormap jet;
    xlabel('Temperature')
    ylabel('Power/Pressure')
    zlabel('Humidity')
    
  3. surface from 3 vectors