1. 程式人生 > >在MATLAB產生的Figure中實現區域性放大的功能

在MATLAB產生的Figure中實現區域性放大的功能

文章參考了知乎網的一篇原創文章:點選開啟連結

基本概念和用到的函式說明

控制代碼

在這個例項中,需要用到MATLAB中的一個很特殊的概念,叫“控制代碼”。

控制代碼是MATLAB語言獨有的引數,相當於C語言的指標。從本質上來說,它相當於一個double型,但它會指向一個物件,這個物件也會有若干的屬性。可以用“set()”函式和“get()”來改寫。後續會介紹這兩個函式的用法。

控制代碼分為多種,如函式柄,物件柄,圖形柄等。對於圖形控制代碼來說,它就是指向一個圖形,比如語句:H=plot(x,y),其中的“H”就是一個圖形控制代碼。用它可以更改這個圖形的各項屬性如線寬、線顏色等等。

"set()"函式和“get()”函式

涉及到控制代碼的操作需要兩個特殊的函式。

"set()":用法為:set(物件控制代碼,‘物件屬性1’,'物件屬性1的值','物件屬性2','物件屬性2的值',.......),可以有很多屬性,但這些屬性必須是物件所具有的。通過“set()”函式可以對這些物件的屬性進行直接的設定。

set(gcf,'color','white');
比如上述程式碼,gcf是當前圖形視窗的控制代碼值,是一個double,set()函式實現的是把這個圖形視窗'color'屬性設定為'white'。

"get()":用法為:get(物件控制代碼,'屬性名1','屬性名2'.......),通過"get()"函式,可以得到這些物件控制代碼的屬性值。

Pos=get(gca,'Position')
在上述程式碼中,gca是當前圖形創口中當前座標軸的控制代碼值。get()函式獲得了座標軸的屬性值'Position',並將其賦給了Pos。

幾個重要的關鍵字

gca:當前圖形視窗中當前座標軸的控制代碼值。

gcf:當前圖形視窗的控制代碼值。

gco:當前圖形視窗中當前物件的控制代碼值。

Position:對於Figure來說,通常指一個物件的位置,包括其實橫軸的起點座標,縱軸的起點座標,橫軸的跨度,縱軸的跨度。(注意,此處的座標是以顯示器為參考,座標的值的大小也取決於顯示器的畫素)。

XData和YData:分別是圖形中點的橫座標和縱座標。

xlim和ylim:分別指的是x軸的範圍和y軸的範圍。

例項

clc;clear;
set(gcf,'color','white');
Pos=get(gca,'Position');%拿到axes在figure中的座標以及刻度值
X0=Pos(1);
Y0=Pos(2);
DX=Pos(3);
DY=Pos(4);
DLX=xlim;
DLY=ylim;

%拿到axes中的曲線資料
h=findobj(gcf,'Type','line');
xdata=get(h,'XData');
ydata=get(h,'YData');

Color=get(h,'Color');
LineStyle=get(h,'LineStyle');
LineWidth=get(h,'LineWidth');
Marker=get(h,'Marker');
MarkerSize=get(h,'MarkerSize');
MarkerEdgeColor=get(h,'MarkerEdgeColor');
MarkerFaceColor=get(h,'MarkerFaceColor');

%選取需要放大顯示的細節部分
h1=imrect;%框選需要的區域
wait(h1);
pos=getPosition(h1);
x0=pos(1);
y0=pos(2);
dx0=pos(3);
dy0=pos(4);

%細節部分的下標
if iscell(xdata)==0
    indx1=find(xdata>=x0);
    indx2=find(xdata<=x0+dx0);
    indx=indx1(1):indx2(end);
else
    m=length(xdata);
    indx1=find(xdata{1}>=x0);
    indx2=find(xdata{1}<=x0+dx0);
    indx=indx1(1):indx2(end);
end

hold on;
LineX=x0:dx0/10:x0+dx0;
LineY=y0:dy0/10:y0+dy0;
plot(LineX,y0*ones(size(LineX)),'k');
plot(LineX,(y0+dy0)*ones(size(LineX)),'k');
plot(x0*ones(size(LineY)),LineY,'k');
plot((x0+dx0)*ones(size(LineY)),LineY,'k');

h2=imrect;
wait(h2);
pos=getPosition(h2);
x=pos(1);
y=pos(2);
dx=pos(3);
dy=pos(4);

xn=X0+DX*(x-DLX(1))/(DLX(2)-DLX(1));
yn=Y0+DY*(y-DLY(1))/(DLY(2)-DLY(1));
dxn=DX*dx/(DLX(2)-DLX(1));
dyn=DY*dy/(DLY(2)-DLY(1));
delete(h1);delete(h2);
axes('Position',[xn yn dxn dyn]);

if iscell(xdata)==0
    plot(xdata(indx),ydata(indx),'Color',Color,'LineStyle',LineStyle,'LineWidth',LineWidth,'Marker',Marker,'MarkerSize',MarkerSize,'MarkerEdgeColor',MarkerEdgeColor,'MarkerFaceColor',MarkerFaceColor);
else
    for i=1:m
        plot(xdata{i}(indx),ydata{i}(indx),'Color',Color{i},'LineStyle',LineStyle{i},'LineWidth',LineWidth{i},'Marker',Marker{i},'MarkerSize',MarkerSize{i},'MarkerEdgeColor',MarkerEdgeColor{i},'MarkerFaceColor',MarkerFaceColor{i});
        hold on;
    end
end

set(gca,'Box','off');
axis([x0 x0+dx0 y0 y0+dy0]);
效果如下: