我试图在Matlab上创建一个包含多个轴断点的图(如下所示):
我尝试过使用Matlab文件交换中的breakyaxis
和breakaxis
之类的内容,但这些只允许一次休息,而不是多次。
有没有办法实现这个?
答案 0 :(得分:4)
NaN
( N ot a N umber )值可能是令人烦恼的事情,但在某些方面也很方便情况下。
当您绘制数据时,Matlab将在每个没有值的数据点(NaN
)留下空白。因此,原则是在数据集之间插入这些NaN
,并告诉Matlab绘制整个批次。在有NaN
的任何地方,Matlab会自动留空。
这是一个例子,因为你没有提供样本数据我首先必须定义3个类似你图中的数据集的短数据集:
%% // sample data sets
yf = @(x) 2*x+40+randi(7,size(x)) ;
x1 = 57:61 ; y1 = yf(x1) ;
x2 = 72:76 ; y2 = yf(x2) ;
x3 = 80:83 ; y3 = yf(x3) ;
这是一个编辑的答案,考虑到Y轴的中断。为了能够在数据集上调用全局操作,我必须将它们重新组合成单元阵列或结构。 struture方法将在不同的数据集上使用循环,而单元阵列允许使用cellfun
来压缩代码。我选择了这种方法并广泛使用cellfun
。
因此,第一步是将所有数据集放在单元格数组中
%% // have to group the data sets in a cell array or structure to implement global operations
xc = { x1 ; x2 ; x3 } ;
yc = { y1 ; y2 ; y3 } ;
现在重要的部分:
%// find the maximum vertical span of the datasets and the total span
maxVal = cellfun(@max,yc) ;
minVal = cellfun(@min,yc) ;
maxYspan = max( maxVal-minVal ) ;
totalSpan = max(maxVal)-min(minVal) ;
%// find a sensible Y value to add between the datasets, not too wide but
%// enough to see a break`
yBreakIncrement = round( totalSpan / 10 ) ; %// adjust that if necessary
yTickIncrement = round( maxYspan /5 ) ; %// adjust that if necessary
%% // rebuild the Y datasets
%// value to substract to each data set to bring them together (including the break space)
setSubstract = [0 ; cumsum( (minVal(2:end)-maxVal(1:end-1))- yBreakIncrement ) ] ;
%// get 3 new data sets brought together
Yall = cellfun(@minus , yc , num2cell(setSubstract) , 'uni',0) ;
%// concatenate the data sets, inserting NaN in the middle
Yall = cellfun( @(a,b) cat(2,a,b) , Yall , repmat({NaN},length(yc),1) , 'uni',0) ;
Yall = cat( 2, Yall{:} ) ;
%// remove the last trailing NaN
Yall(end) = [] ;
%% // Build the Y labels
%// generate ticks that covers each interval
Y_tickpos = cellfun(@colon, num2cell(minVal), repmat({yTickIncrement},length(yc),1) , num2cell(maxVal) , 'uni',0) ;
%// generate the Y labels based the real Y values
Y_labels = cellstr( num2str( cat(2, Y_tickpos{:} ).') ) ; %'// ignore this comment
%// now adjust the actual position
Y_tickpos = cellfun(@minus , Y_tickpos , num2cell(setSubstract) , 'uni',0) ;
Y_tickpos = cat( 2, Y_tickpos{:} ) ;
%% // Build the X labels (and axis)
%// create a continuous index for the X axis
X = 1:length(Yall) ;
X_labels = cellstr( num2str( cat(2, xc{:} ).') ) ; %'// generate the X labels based the X values
X_tickpos = X(~isnan(Yall)) ; %// prepare a vector for the label positions
%% // Display
plot(X,Yall) %// plot as usual
%// Set the labels at the chosen positions
set(gca, 'XTick' , X_tickpos , 'XTickLabel' , X_labels )
set(gca, 'YTick' , Y_tickpos , 'YTickLabel' , Y_labels )
那应该给你一样的东西:
希望能让你开始。尝试使原则适应您的数据。