具有阴影刻面与阴影插值的绘图边缘的差异

时间:2017-08-23 22:17:14

标签: matlab plot

我对使用彩条的2D地图的绘图有疑问。在我的应用程序中,我的数据大小等于258x98。

如果我用冲浪和shading interp绘制这些数据,一切都很好。

Good map : with shading interp;

但如果我用shading faceted绘制它们,地图上方水平部分的不同行似乎都会丢失。

Bad map : with shading faceted

上边框最初不像shading interp;版本中的红色。

我发现a post谈到了这个问题;它可能来自shading faceted默认行为。

在绘图时,有人可以确认缺少行吗?如何修复它以便使用shading faceted

绘制所有边界数据

MCVE

我尝试用一​​个简单的例子重现这个问题。这是一个简单的Matlab脚本:

x_dim=256;
y_dim=96;
[X Y]=meshgrid(0:x_dim+1,0:y_dim+1);
Z = abs(X-x_dim/2).*abs(Y-y_dim/2);
Z(1:5,:)=x_dim*y_dim/2;
Z(end-4:end,:)=x_dim*y_dim/2;

surf(X,Y,Z);
view([0,0,1]);
hc=colorbar;
set(hc,'position',[0.932 0.3 0.02 0.6]);
xlim([0 x_dim+1]);
ylim([0 y_dim+1]);
xlabel('x domain');
ylabel('y domain');
%shading interp;

和带shading faceted的图(默认选项):

plot with shading faceted

您可以看到上部红色矩形的厚度小于下部的矩形。如下shading interp;,差异不太明显,可能会重现我的问题,即在我的问题的第一部分。

shading interp;

的数字

plot with shading interp

1 个答案:

答案 0 :(得分:1)

我做的第一件事就是放大以检查渲染看起来像什么。

图顶部的缩放

subplot(1,2,1);
surf(X,Y,Z);
view([0,0,1]);
colorbar;
xlim([0,1])
ylim([y_dim-5, y_dim-2])
title('shading faceted');

subplot(1,2,2);
surf(X,Y,Z);
view([0,0,1]);
colorbar;
xlim([0,1])
ylim([y_dim-5, y_dim-2])
shading interp
title('shading interp');

Zoom to top

您可以看到,您看到的颜色流失发生在网格线之间。 Z的值以整数间隔定义。插值渲染中的扩展红色发生在整数网格线之间的间隔中。

分面版本显示整个间隔的一个值,那么选择哪个值?较低或较高整数网格线的值?使用数据光标或检查矩阵值(即display(Z(93,1))),我们可以看到构面的颜色由下边缘的值决定。

documentation确认了这种行为:

  

shading flat每个网格线段和面具有恒定的颜色   由段或端点处的颜色值确定   具有最小索引或指数的面部角落。

     

shading faceted平面阴影,叠加黑色网格线。   这是默认的着色模式。

因此,平面着色(如平面着色)从具有最小索引或网格线的构面端点处的颜色值开始。

在哪里,

  

shading interp会改变每个线段和面部的颜色   在整个线上插入色彩映射索引或真彩色值   或面子。

这就是为什么图的底部在shading faceted设置中有一个更宽的红色条带,因为较低的索引网格线决定了小平面的颜色。

图底部的缩放

subplot(1,2,1);
surf(X,Y,Z);
view([0,0,1]);
colorbar;
xlim([0,1])
ylim([3,6])
title('shading faceted');

subplot(1,2,2);
surf(X,Y,Z);
view([0,0,1]);
colorbar;
xlim([0,1])
ylim([3,6])
shading interp
title('shading interp');

Zoom to bottom

因为这是shading faceted的预期行为。你必须在框外思考以获得你想要的渲染。

解决方案1:imagesc

如果您只想绘制曲面的顶部(view([0,0,1]),请使用imagesc(Z)。这会将Z中的每个元素绘制为一个像素,而不是将像素放在Z元素之间。整体外观类似于shading faceted,但索引移动到像素的中间。例如,

[X, Y] = meshgrid(0:2, 0:2);
Z = magic(3);

figure;
colormap('jet');

subplot(1, 3 ,1);
imagesc(Z);
axis xy
yticklabels({'0', '1', '2'})
yticks(1:3)
xticklabels({'0', '1', '2'})
xticks(1:3)
title('imagesc(Z)');

subplot(1,3,2);
surf(X, Y, Z);
shading faceted;
view([0,0,1]);
yticks(0:3)
xticks(0:3)
title('surf(X, Y, Z); shading faceted;');

subplot(1,3,3);
surf(X, Y, Z);
shading interp;
view([0,0,1]);
yticks(0:3)
xticks(0:3)
title('surf(X, Y, Z); shading interp;');

Rendering comparison for top view using imagesc, shading faceted and shading interp

你可以看到,从鸟眼的视角来看,边缘值会得到更好的渲染效果。使用imagesc而不是shading faceted

老实说,从任何其他角度来看,shading interp只是更直观。这里旋转的表面与上面相同。

Comparison of shading interp and faceted on rotated surface

您可以看到使用shading interp更直观地将高点和低点着色。

解决方案2:添加另一行和列

如果您出于某种原因确实需要使用shading faceted。您可以通过向数据添加另一行和列来欺骗可视化。从顶部开始,它将以您想要的方式呈现。警告:这会改变表面的形状

首先使X,Y网格变大,并复制Z

的最后一行和一列
[X_extend, Y_extend] = meshgrid(0:3, 0:3);
Z_extend = [Z, Z(:, end);];
Z_extend = [Z_extend; Z_extend(end, :)];

这里是shading faceted图,从上方和稍微旋转。

<code>shading faceted</code> with extended grid

上面的视图是我们想要的,但在旋转的视图中,表面已经改变。此旋转类似于上一张图片中的旋转,但您可以看到重复的行和列的形状通过在该侧的每条边上添加矩形面来更改曲面的边缘。

如果边缘的3D形状不重要,则仅使用此方法