2

我尝试以编程方式制作一个 MATLAB GUI,并遇到我的滑块在使用后消失的问题。我隔离了问题以保持代码简短。在这个 GUI 中,我想在plotmatrix每次使用滑块时刷新(忽略滑块的值与我的程序完全无关的事实,如前所述,我真的想保持代码干净,这就是为什么我也删除了这个功能) . 这是代码(您必须将其作为函数运行):

function StackOverflowQuestion_GUI()
    % clear memory
    close all; clc;

    % initialize figure
    f = figure;

    % create main axes
    AX_main = axes('Parent',f,...
        'Units','normalized','Position',[.1 .2 .8 .7]);

    % create slider
    uicontrol('Parent',f,...
        'Style','slider','Callback',{@sliderCallback,AX_main},...
        'Units','normalized','Position',[0.05 0.05 0.9 0.05]);

    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix');
end

function sliderCallback(~,~,AX_main)   % callback for slider
    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix NEW');
end

任何帮助表示赞赏!我想我误解了 AXES 的概念。当我绘制到我创建的 AXES 句柄时,为什么图形的其他部分也会受到影响?如果有人可以向我解释这个图形处理系统基本上是如何工作的,那也太好了!

4

2 回答 2

6

虽然daren shan 的回答是正确的,但这种行为很奇怪,我很想知道它背后的原因。

遍历源代码,plotmatrix我们可以找到删除滑块对象的行:

% Create/find BigAx and make it invisible
BigAx = newplot(cax);

这里没有什么明显的,有什么作用newplot

newplot在高级图形代码的开头使用以确定图形输出的目标图形和轴。调用newplot 可以改变当前图形和当前轴。基本上,当您在现有图形和轴中绘制图形时,有三个选项:

  • 添加新图形而不更改任何属性或删除任何对象。

  • 在绘制新对象之前,删除所有未隐藏其句柄的现有对象。

  • 删除所有现有对象,无论其句柄是否隐藏,并在绘制新对象之前将大多数属性重置为默认值(具体信息请参见下表)。

哦...

newplot删除滑块对象也是如此。


那么为什么要hold阻止滑块被删除,尽管它是一个轴方法而不是一个图形方法?首先,请查看文档中的“算法”主题:

hold函数将or 对象的NextPlot属性设置为or 。AxesPolarAxes'add''replace'

因此hold on将其设置'add'为当前轴。但是,由于我目前无法弄清楚的原因,这NextPlot图形的 设置add为 。

我们可以通过一个简短的片段看到这一点:

f = figure('NextPlot', 'replacechildren'); 
ax = axes; 
fprintf('NextPlot Status, base:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)
hold on
fprintf('NextPlot Status, hold on:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)

哪个打印:

NextPlot Status, base:
Fig: replacechildren, Ax(1): replace

NextPlot Status, hold on:
Fig: add, Ax(1): add

奇怪的行为,但我不会详述。


为什么这很重要?返回newplot文档。首先,newplot读取图形的NextPlot属性以确定要做什么。默认情况下,图形的NextPlot属性设置为'add',因此它将保留所有当前的图形对象,但plotmatrix会显式更改:

if ~hold_state
    set(fig,'NextPlot','replacechildren')
end

所以newplot从:

在不清除任何已经存在的图形对象的情况下绘制到当前图形。

至:

移除其HandleVisibility属性设置为的所有子对象,on 并将图形NextPlot属性重置为add

这将清除当前图形,相当于发出clf 命令。

这解释了为什么滑块消失以及为什么hold on解决了这个问题。


根据文档,newplot我们还可以设置HandleVisibility滑块 UIcontrol 以防止其被破坏:

% create slider
uicontrol('Parent',f,...
    'Style','slider','Callback',{@sliderCallback,AX_main},...
    'Units','normalized','Position',[0.05 0.05 0.9 0.05], ...
    'HandleVisibility', 'off');
于 2017-03-24T17:40:13.793 回答
1

当您调用 时plotmatrix,该函数会完全重绘图形,为了保存其他元素,您应该使用hold on; hold off;以下语句:

function StackOverflowQuestion_GUI()
    % clear memory
    clear; close all; clc;

    % initialize figure
    f = figure;

    % create main axes
    AX_main = axes('Parent',f,...
        'Units','normalized','Position',[.1 .2 .8 .7]);

    % create slider
    uicontrol('Parent',f,...
        'Style','slider','Callback',{@sliderCallback,AX_main},...
        'Units','normalized','Position',[0.05 0.05 0.9 0.05]);

    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix');
end

function sliderCallback(~,~,AX_main)   % callback for slider
    hold on;
    plotmatrix(AX_main,randn(500,3));
    hold off;
    title('Random Plotmatrix NEW');
end
于 2017-03-24T15:50:44.353 回答