链接MATLAB轴的不同属性 [英] Link different properties of MATLAB axes

查看:55
本文介绍了链接MATLAB轴的不同属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将一个MATLAB轴的"XLim"属性链接到另一轴的"YLim"属性?我已经研究过linkaxeslinkprop,但是据我所知,它们只能链接相同的属性,例如一个轴"XLim"到另一个轴"XLim",依此类推.

Is it possible to link, for example, the 'XLim' property of one MATLAB axis to the 'YLim' property of another axis? I have looked into linkaxes and linkprop but as far as I can tell, they can only link same properties, e.g. one axis 'XLim' to another axis 'XLim' and so on.

使用MATLAB 2014b.谢谢!

Using MATLAB 2014b. Thanks!

推荐答案

我想出了一种方法,虽然可以,但是仍然有些笨拙...

I worked up a way to it, it works but it remains slightly clunky ...

显然,该想法是将侦听器附加到要链接的两个属性,并在每次更改另一个属性时更新一个属性.

The idea is obviously to attach listeners to the two properties you want to link, and update one property each time the other one is changed.

需要花些时间才能将侦听器附加到内置axes对象的属性,您必须检索关联的meta.property.我将此包装在一个外部子功能findPropertyHandle中.

It takes a bit of fiddling around just to be able to attach a listener to the properties of the built-in axes object, you have to retrieve the associated meta.property. I package this in an external subfunction findPropertyHandle.

我将解决方案制成了泛型,因此您可以将任何类型的属性链接在一起.现在,我没有对输入检查进行编程,因此,它当然仅适用于 compatible 属性. XLimYLim显然兼容,但是如果尝试将XLimPlotBoxAspectRatioMode链接,则会在控制台中出现大量红色和橙色文本.

I made the solution generic so you can link any type of property together. Now I didn't program input checks so of course it will work only on compatible properties. XLim is obvisouly compatible with YLim, but if you try to link XLim with PlotBoxAspectRatioMode you're in for a deluge of red and orange text in your console.

%% Demo data and figure
x = linspace(0,24*pi,1000) ;
y = cos(x) ;
hf = figure ;
hax1 = subplot(1,2,1) ; hp1 = plot(x,y) ;
hax2 = subplot(1,2,2) ; hp2 = plot(y,x) ;

%% Find (meta)property handle
prop1 = findPropertyHandle( hax1 , 'XLim' ) ;
prop2 = findPropertyHandle( hax2 , 'YLim' ) ;

%% Add a listener to each property
% no callback yet because we need the reference of both listeners to be part of the callback arguments
lh1 = addlistener( hax1, prop1 , 'PostSet', @() [] ) ;
lh2 = addlistener( hax2, prop2 , 'PostSet', @() [] ) ;

%% group a few things for convenience
pl.obj2link   = [ hax1  ; hax2  ] ;     % axes handles
pl.props2link = { 'XLim' ; 'YLim' } ;   % name of properties to link
pl.listeners  = [ lh1 ; lh2 ] ;         % listener handle
pl.metaprops2link = [ prop1 ; prop2 ] ; % metaproperty handles

%% Set the callback of both listeners
% Have to use dot notation because the 'set' method is not defined for listener objects
lh1.Callback = @(h,e) LinkPropChangedFcn(h,e,pl) ;
lh2.Callback = @(h,e) LinkPropChangedFcn(h,e,pl) ;

LinkPropChangedFcn.m

function LinkPropChangedFcn( hobj, evt, plink )
%LinkPropChangedFcn Links 2 compatible properties

    % find which property was triggered
    changedPropIdx = find( hobj==plink.metaprops2link ) ;
    prop2changeIdx = 3-changedPropIdx ; % because cumsum([1 2])=3

    % disable the other listener to not trigger the property change on the
    % target object
    plink.listeners(prop2changeIdx).Enabled = false ;

    % retrieve property value
    val = get( plink.obj2link(changedPropIdx) , plink.props2link{changedPropIdx} ) ;

    % aplpy the value to the target object property
    set( plink.obj2link(prop2changeIdx) , plink.props2link{prop2changeIdx} , val ) ;

    % re-enable target listener
    plink.listeners(prop2changeIdx).Enabled = true ;

end

findPropertyHandle.m

function [ hprop ] = findPropertyHandle( hobj , propname )
%FINDPROPERTYHANDLE retrieve the handle of the meta.property object

    mco = metaclass(hobj) ;
    plist = mco.PropertyList;
    for k=1:numel(plist)
        if strcmpi(plist(k).Name,propname)
            fprintf('[%s] property was found at index #%d\n',propname,k)
            hprop = plist(k) ;
            return
        end
    end
    % no preperty was found if we are here
    hprop = [] ;
    fprintf('[%s] property was not found.\n',propname)

end


注意 我所说的笨拙是什么时候使用重置为原始视图"菜单而不是缩小".该功能不会触发XLim属性的PostSet事件,因此更改并不总是传播到其他轴/属性.为了克服这个问题,在使用重置为原始视图"之后,再次右键单击并缩小"即可.这不会在单击的axes中进一步缩小(如果您已经在原始视图"中),但是它将触发侦听器并更新第二个目标轴.


Note The clunkiness I was talking about is when instead of "zooming out" you use the "reset to original view" menu. This function does not trigger the PostSet event of the XLim property, so the change is not always propagated to the other axes/property. To overcome that, just after using "reset to original view", right click again and "zoom out". This will not zoom further out in the clicked axes (if you were already at the "original view"), but it will trigger the listener and update the second target axes.

这篇关于链接MATLAB轴的不同属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆