我在使用patch 或surface 之间犹豫不决,而hbaderts 在提出surface 选项时更快,所以我将向您展示如何使用patch。
我将在我的示例中提供更多构造细节,但如果您愿意,最终您可以将我的补丁替换为表面对象。
首先我开始构建一系列看起来像你的曲线:
colorCollection = get(0,'defaultAxesColorOrder') ;
nPlot = 4 ;
h.fig = figure ;
h.ax = axes('NextPlot','add') ;
x = linspace(0,180) ;
f = zeros( nPlot , numel(x) ) ;
for k=1:nPlot
f(k,:) = sin(k*x/180*pi) * 180 ;
h.plotf(k) = plot( x , f(k,:) , '.' , 'Color',colorCollection(k,:) ) ;
end
这将创建并绘制 4 条曲线。接下来是解决您“上方 10 像素和下方 10 像素”的请求。绘制的曲线或任何补丁/曲面将没有“像素”的概念,而只有数据空间中的值。所以你必须知道如何将像素转换为数据或反过来。
%// retrieve a few propery values
xlim = get(h.ax,'XLim') ; %// axes X limits
ylim = get(h.ax,'YLim') ; %// axes Y limits
set( [h.ax h.fig] , 'Unit','Pixels') %// set the axes units in pixel
axpos = get( h.ax,'Position') ; %// get the coordinates of the axes object on the figure (in pixels)
nPix.W = round(axpos(3)) ; %// axes WIDTH , in [pixel]
nPix.H = round(axpos(4)) ; %// axes HEIGHT , in [pixel]
%// calculate the vertical data/pixel ratio (to know how much "y" value
%// will correspond to "10" pixels)
nPixelOverlap = 10 ; %// this is defined in your question
pixelRatio = (ylim(2)-ylim(1)) ./ nPix.H ; %// =0.0052 in my example. => 1pixel=0.0052*y
dataOverlap = nPixelOverlap .* pixelRatio ; %// how much I have to add or remove to a curve to cover 10 pixels
一旦我有了这个神奇的系数dataOverlap,我就可以构建必须包含每条曲线的图形对象,它们的较高和较低Y 边界将是曲线的值,分别加上和减去dataOverlap .
在您的情况下,您似乎没有大向量(没有那么多 x 值),因此下面的部分解决方案可能对您的问题来说是多余的。但是,如果您必须对大型数据向量(例如数千个或更糟,数百万个元素)做同样的事情,那么创建具有这么多点的许多补丁(甚至表面)很可能几乎会冻结您的图形(如果响应时间非常慢,如果不会更糟)。一个简单的方法是绘制一个下采样版本。由于我们已经计算了轴跨越的像素数,我们可以创建这个大小的图形对象(所以我们基本上每个像素只有一个x 点,仅此而已)。
%// define a minimal "x" vector to populate every pixel in the axes
x4interp = linspace(xlim(1),xlim(2),nPix.W) ;
xpatch = [x4interp fliplr(x4interp)] ; %// common X vector for all the patch objects
ypatch = zeros( nPlot , numel(xpatch) ) ; %// preallocate Y arrays for each patch (one patch per initial curve)
for k=1:nPlot
ytemp = interp1( x , f(k,:) , x4interp ) ; %// reinterp the "k-th" curve value on the new "x" axis
%// prepare the patch "Y" data (=the curve reinterpolated value + and - the overlap
ypatch( k , : ) = [ytemp-dataOverlap fliplr(ytemp)+dataOverlap] ;
%// plot the actual patch
h.patch(k) = patch( xpatch , ypatch(k,:) , colorCollection(k,:) , 'FaceAlpha',0.2 , 'EdgeColor','none' ) ;
end
如果你一次性执行这个例子,你应该会得到非常相似的东西(颜色可能会有所不同,具体取决于你使用的 Matlab 版本):
正如我上面所说的,对于这个例子来说,最后一点重新插值是多余的(补丁实际上比曲线有 更多 个数据点),但好处是它具有很强的可扩展性。如果您的初始曲线有 107 个点,您可以使用完全相同的方法,补丁不会占用您的内存(您的曲线可能)。
请注意,像素/数据比率的计算取决于屏幕图形的大小。如果调整图形大小,则不会更新计算。您要么必须重新执行计算部分并更新图形对象,要么最简单的方法是先将图形设置为所需的大小,然后执行计算并绘制图形对象。