Matlab 在三维图中表示三个变量

Matlab 在三维图中表示三个变量,matlab,3d,Matlab,3d,我在处理三个变量的三维绘图时遇到了一个问题 我有三个矩阵:温度、湿度和功率。在一年中,每小时对上述各项进行测量。对于每个矩阵,我们有365*24=8760点。然后,每天取一个平均分。所以 Tavg=365 X 1 Havg=365 X 1 Pavg=365 X 1 在静脉电点,功率取决于温度和湿度。我想用三维图来发现这种关系 我尝试在MATLAB中使用mesh、meshz、surf、plot3和许多其他命令,但不幸的是,我无法得到我想要的。例如,让我们先看前10天。这里,每天由平均温度、平均湿

我在处理三个变量的三维绘图时遇到了一个问题

我有三个矩阵:温度、湿度和功率。在一年中,每小时对上述各项进行测量。对于每个矩阵,我们有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];

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

我想您要求的是适合数据的曲面。曲线拟合工具箱可以很好地处理此问题:

% 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:。

挑战在于三维曲面打印功能(网格、曲面等)正在寻找z值的二维矩阵。所以要使用它们,你需要从数据中构造这样一个矩阵

目前,数据是三维空间中的大量点,因此,必须将这些点映射到曲面。一种简单的方法是将X-Y(温度-湿度)平面划分为多个单元,然后取所有Z(功率)数据的平均值。下面是一些示例代码,它使用accumarray()计算每个箱子的平均值: %指定存储箱大小 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])

您可能希望了解Delaunay三角剖分:

tri = delaunay(Tavg, Havg);
trisurf(tri, Tavg, Havg, Pavg);
使用示例数据,此代码生成一个有趣的“曲面”。但我相信这是做你想做的事情的另一种方式。

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

要生成更好的绘图,可以添加标签、一些透明度并覆盖原始点:

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

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

title('GridFit')

PS:@upperBound:谢谢你的Delaunay三角测量技巧。如果你想通过每一个点,这似乎是一条路要走。我是个新手,所以还不能发表评论。

以下是您的解决方案:

  • 保存/写入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);
    
  • 从命令行(或脚本)调用以下命令


  • 我尝试使用plot3,但我希望它是曲面或平面的形状。比如这个形状:我想这是使用网格,但我不知道怎么做。
    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);
    
    [Tavg_new,Pavg_new,V]=Myplot3D(Tavg,Pavg,Havg);
    surf(Tavg_new,Pavg_new,V)
    colormap jet;
    xlabel('Temperature')
    ylabel('Power/Pressure')
    zlabel('Humidity')