Matlab图'年龄'

use*_*193 7 matlab undocumented-behavior

这是一个关于"Matlab中记录较少的部分的专家"的问题:是否有一种(未记录的?)方式来确定数字的开放时间(即图的"年龄")?

figure; spy;
myfig=gcf;
age=get_age() %shoud output age of figure in some format
Run Code Online (Sandbox Code Playgroud)

Yai*_*man 8

您可以使用以下机制:

首先,创建一个小的Matlab函数,如下所示,将CreationTime属性附加到图形:

function setCreationTime(hFig,varargin)
   hProp = addprop(hFig,'CreationTime');
   hFig.CreationTime = now;
   hProp.SetAccess = 'private'; %make property read-only after setting its initial value

   hProp = addprop(hFig,'Age');
   hProp.GetMethod = @(h,e) etime(datevec(hFig.CreationTime), clock); %compute on-the-fly
   hProp.SetAccess = 'private'; %make property read-only
end
Run Code Online (Sandbox Code Playgroud)

现在将此函数指定为从现在开始的所有新数字的默认CreateFcn回调函数:

set(0,'DefaultFigureCreateFcn',@setCreationTime)
Run Code Online (Sandbox Code Playgroud)

就是这样 - 你完成了!

例如:

>> newFig = figure;
>> newFig.CreationTime
ans =
      737096.613706748

>> ageInDays = now - newFig.CreationTime
ageInDays = 
       0.01625078368466347
>> ageDuration = duration(ageInDays*24,0,0)
ageDuration = 
  duration
   00:23:24
>> ageString = datestr(ageInDays, 'HH:MM:SS.FFF')
ageString = 
    '00:23:24.068'

>> ageInSecs = newFig.Age
ageInSecs =
    1404.067710354923808
Run Code Online (Sandbox Code Playgroud)


Tom*_*zzo 5

据我所知,图形对象不会暴露这种信息.甚至没有在其未记录的基础Java类中.但我有一个想法可能代表这个问题的一个很好的解决方法.

使用图函数的以下重载:

figure(n)找到Number属性等于n的数字,并使其成为当前数字.如果该属性值不存在数字,则MATLAB®会创建一个新数字并将其Number属性设置为n.

为了为每个现有数字分配"唯一标识符",并将这些标识符与datenum表示创建时间的值相关联:

% Initialize the lookup table somewhere in your code:
lookup_table = zeros(0,2);
% Together with a variable that stores the next unique identifier to be assigned:
next_id = 1;

% When you need to instantiate a new figure...
    % 1) Retrieve the current datetime:
    cdate = now();
    % 2) Update the lookup table:
    lookup_table = [lookup_table; next_id cdate];
    % 3) Initialize the new figure:
    figure(next_id);
    % 4) Increment the next unique identifier:
    next_id = next_id + 1;
Run Code Online (Sandbox Code Playgroud)

然后,查找表的每一行将包含唯一的图标识符及其各自的创建日期.

其他一切都很容易处理.如果要查询数字正常运行时间...在查找表中找到其唯一标识符,并将当前时间(使用该now()命令获取)减去创建时间.我建议您为CloseRequestFcn您创建的每个图形定义一个句柄,这样当图形关闭时,您可以更新lookup_table并删除它.您可以使用其Number属性检索分配给特定图形的标识符.这是一个完整的工作实现:

global lookup_table;
global next_id;

lookup_table = zeros(0,2);
next_id = 1;

f1 = create_figure();
f2 = create_figure();

pause(10);

f1_ut = get_figure_uptime(f1)
f2_ut = get_figure_uptime(f2)

function f = create_figure()
    global lookup_table;
    global next_id;

    cdate = now();

    f = figure(next_id);
    f.CloseRequestFcn = @update_lookup_table; 

    lookup_table = [lookup_table; next_id cdate];
    next_id = next_id + 1;
end

function ut = get_figure_uptime(f)
    global lookup_table;

    tn = now();
    tc = lookup_table(lookup_table(:,1) == f.Number,2);

    if (isempty(tc))
        ut = -1;
    else
        ut = etime(datevec(tn),datevec(tc));
    end
end

function update_lookup_table(f,~)
    global lookup_table;
    lookup_table(lookup_table(:,1) == f.Number,:) = [];

    delete(f);
end
Run Code Online (Sandbox Code Playgroud)

或者,正如您在评论中所建议的那样,您可以为您创建的每个图形添加一个属性,在该图形中可以存储其创建时间.它更直接,无需处理查找表.为此,只需使用addprop functon,如下所示:

cdate = now();

f = figure();
addprop(f,'CreationTime');
f.CreationTime = cdate;
Run Code Online (Sandbox Code Playgroud)