Matlab 在现有轴内显示新图像,不删除颜色栏

Matlab 在现有轴内显示新图像,不删除颜色栏,matlab,matlab-figure,colorbar,matlab-hg2,Matlab,Matlab Figure,Colorbar,Matlab Hg2,我正在开发一个GUI,该GUI通过创建多个GUI以及为每个GUI创建一个不可见的GUI进行初始化(这样做是为了使轴保持其预定义的属性)。将存储所有轴和颜色栏的控制柄 与UI的交互可能导致在任意一个轴上绘制图像。我希望通过适当设置所有颜色条的Visible属性,在任何给定时间只显示活动轴的颜色条 我对这种方法有一个问题,因为我正在使用更新我的轴,这会删除与轴关联的任何颜色栏,使存储的句柄无效 我的问题是:如何使用imagesc或image更新与颜色条关联的轴,而不删除颜色条? 下面是如何重现此问题

我正在开发一个GUI,该GUI通过创建多个GUI以及为每个GUI创建一个不可见的GUI进行初始化(这样做是为了使轴保持其预定义的属性)。将存储所有轴和颜色栏的控制柄

与UI的交互可能导致在任意一个轴上绘制图像。我希望通过适当设置所有颜色条的
Visible
属性,在任何给定时间只显示活动轴的颜色条

我对这种方法有一个问题,因为我正在使用更新我的轴,这会删除与轴关联的任何颜色栏,使存储的句柄无效

我的问题是:如何使用
imagesc
image
更新与颜色条关联的轴,而不删除颜色条?

下面是如何重现此问题:

dbclear in newplot %// Needed for the code to be properly re-runnable
%// Create an example figure containing a colorbar:
figure(); imagesc(imread('cameraman.tif')); colorbar;
%// "Refreshing" the displayed image:
uiwait(msgbox('The image will now be refreshed. A breakpoint will be set in newplot.m'));
dbstop in newplot at 124 %// The line responsible for deleting the colorbar in R2015A/B
imagesc(imread('cameraman.tif'));
newplot.m
中设置断点的行为:

cla(ax, 'reset', hsave);
令人惊讶的是,这是一种调用
cla
(带有3个参数)的未记录方式,它保留了句柄位于
hsave
中的对象


我有一些想法,假设色条删除是不可避免的(如果找不到“理智”的解决方案,我将继续考虑):

  • 将a绑定到将其数据保存到某个
    struct
    的颜色栏。在
    imagesc
    完成后创建新的颜色栏,然后迭代
    struct
    的字段,并将所有属性指定给新的颜色栏对象
  • 使用
    findall(hFig,'type','colorbar')
    检查“每隔一段时间”是否存在所有色条,或根据以下附录验证每个轴是否具有有效的
    ColorbarPeerHandle
    。如果无效,请重新创建CB
  • 当不同轴处于活动状态时,删除所有颜色条,并仅创建我要显示的CB

  • 附录-色条/轴协会:
    • 与特定轴相关的色条手柄
      hAx
      (在hg2中)可通过以下方式获得:

    • 与colorbar对象相关联的轴的句柄可以通过以下方式获得:


    我设法想出了两个解决方案:

  • safeUpdateImage1
    -基于使用
    hold
    后通过在轴内创建新的
    图像
    对象来规避
    cla(…)
    。这适用于轴中不一定存在
    图像的情况
  • safeUpdateImage 2
    -基于更新现有的
    图像
    对象,执行以下操作。这适用于已存在与轴关联的
    色条和
    图像的情况。
  • 下面是两种解决方案以及原始问题的演示:

    function [] = Problem
    dbclear in newplot %// Needed for the code to be properly re-runnable
    %// Create an example figure containing a colorbar:
    Img = imread('cameraman.tif');
    figure(); imagesc(Img); hAx = gca; colorbar;
    %// Refreshing the displayed image (comment/uncomment as needed):
    switch questdlg('Please select an image update method:','Update method selection',...
                    'Broken','Safe1','Safe2','Safe1')
      case 'Broken'
        brokenUpdateImage(hAx,255-Img);
      case 'Safe1'
        safeUpdateImage1(hAx,255-Img);
      case 'Safe2'
      safeUpdateImage2(hAx,255-Img);  
    end
    end
    
    function brokenUpdateImage(hAx,newImg)
    uiwait(msgbox('The image will now be refreshed. A breakpoint will be set in NEWPLOT'));
    dbstop in newplot at 124 %// The line responsible for deleting the colorbar in R2015A/B
    imagesc(newImg,'Parent',hAx);
    end
    
    % For cases when the only desired child is an Image and the axes contents are unknown
    function safeUpdateImage1(hAx,newImg,imgType,imgUpdateFcn)
    if nargin < 4 || isempty(imgUpdateFcn)
      imgUpdateFcn = @imagesc;
    end
    if nargin < 3 || isempty(imgType)
      imgType = 'Image';  
    end
    if strcmp(hAx.NextPlot,'replace') %// Equivalent to checking "ishold == false"
      hAx.NextPlot = 'add'; %// Equivalent to "hold on"
      %// hCurrImgs = get(hAx,'Children'); %// Deletes all types of Children
      hCurrImgs = findall(hAx,'type','Image'); %// Deletes only graphical objects of type 
                                               %// "matlab.graphics.primitive.Image"
      for ind1=1:numel(hCurrImgs)
        delete(hCurrImgs(ind1));
      end
      imgUpdateFcn(newImg,'Parent',hAx);
      if strcmpi(imgType,'Image')
        axis(hAx,'tight','ij');    
    %// 'tight' - XLimMode, YLimMode, and ZLimMode change to 'auto'. The limits automatic- 
    %//           ally update to incorporate new data added to the axes. To keep the limits
    %//           from changing when using hold on, use axis tight manual.
    %// 'ij'  —   Reverse direction. For axes with a 2-D view, the y-axis is vertical with
    %//           values increasing from top to bottom.    
      end
    end
    end
    
    %// When it's known that the axes contains at least one Image:
    function safeUpdateImage2(hAx,newImg,~,~)
    %// <Input checking code>
    hCurrImgs = findall(hAx,'type','Image');
    %// <Optional code to decide which Image child to update>
    hCurrImgs(1).CData = newImg; %// In this example, only update the "topmost" child
    end
    
    函数[]=问题
    newplot%//中的dbclear需要正确地重新运行代码
    %//创建包含颜色栏的示例图形:
    Img=imread('cameran.tif');
    图();imagesc(Img);hAx=gca;色条;
    %//刷新显示的图像(根据需要进行注释/取消注释):
    开关questdlg('请选择图像更新方法:','更新方法选择',。。。
    ‘断开’、‘安全1’、‘安全2’、‘安全1’)
    案例“破碎”
    brokenUpdateImage(hAx,255 Img);
    案例“安全1”
    安全更新图像1(hAx,255 Img);
    案例“安全2”
    安全更新图像2(hAx,255 Img);
    结束
    结束
    函数brokenUpdateImage(hAx、newImg)
    uiwait(msgbox('现在将刷新映像。将在NEWPLOT中设置断点');
    newplot中的dbstop位于124%//负责删除R2015A/B中颜色条的行
    imagesc(newImg,'Parent',hAx);
    结束
    %对于唯一需要的子对象是图像且轴内容未知的情况
    函数safeUpdateImage1(hAx、newImg、imgType、imgUpdateFcn)
    如果nargin<4 | |是空的(imgUpdateFcn)
    imgUpdateFcn=@imagesc;
    结束
    如果nargin<3 | |为空(imgType)
    imgType='Image';
    结束
    如果strcmp(hAx.NextPlot,'replace')%//相当于检查“ishold==false”
    hAx.NextPlot='add';%//相当于“等等”
    %//hCurrImgs=get(hAx,'Children');%//删除所有类型的子项
    hCurrImgs=findall(hAx,'type','Image');%//仅删除类型为的图形对象
    %//“matlab.graphics.primitive.Image”
    对于ind1=1:numel(hCurrImgs)
    删除(hCurrImgs(ind1));
    结束
    imgUpdateFcn(newImg,'Parent',hAx);
    如果strcmpi(imgType,'Image')
    轴(hAx,'tight','ij');
    %//“紧密”-XLimMode、YLimMode和ZLimMode更改为“自动”。限制自动-
    %//ally update以合并添加到轴的新数据。保持极限
    %//在使用保持时,请使用轴紧手动进行更改。
    %//“ij”-反向。对于具有二维视图的轴,y轴与轴垂直
    %//值从上到下递增。
    结束
    结束
    结束
    %//已知轴至少包含一个图像时:
    函数safeUpdateMage2(hAx,newImg,~,~)
    %// 
    hCurrImgs=findall(hAx,'type','Image');
    %// 
    hCurrImgs(1).CData=newImg;%//在本例中,仅更新“最顶层”子级
    结束
    
    您可以访问由
    imagesc
    创建的图像对象的句柄吗?我想您可能可以直接操作它的
    CData
    属性来更新图形。@mikkola-我可以访问轴的所有方面,包括
    子对象。我想不起来为什么我没有试过。。可能是因为这意味着我需要编写自己版本的
    imagesc
    /
    image
    ,它通过修改
    XData
    /
    YData
    /
    CData
    进行更新,并且没有
    cla
    。如果它比我刚才描述的要简单得多,请随意将其作为一个解决方案发布(尽管我真的宁愿坚持使用现有的函数)…+1这似乎工作得很好。好的,j
     hAx = hCb.Axes;
    
    function [] = Problem
    dbclear in newplot %// Needed for the code to be properly re-runnable
    %// Create an example figure containing a colorbar:
    Img = imread('cameraman.tif');
    figure(); imagesc(Img); hAx = gca; colorbar;
    %// Refreshing the displayed image (comment/uncomment as needed):
    switch questdlg('Please select an image update method:','Update method selection',...
                    'Broken','Safe1','Safe2','Safe1')
      case 'Broken'
        brokenUpdateImage(hAx,255-Img);
      case 'Safe1'
        safeUpdateImage1(hAx,255-Img);
      case 'Safe2'
      safeUpdateImage2(hAx,255-Img);  
    end
    end
    
    function brokenUpdateImage(hAx,newImg)
    uiwait(msgbox('The image will now be refreshed. A breakpoint will be set in NEWPLOT'));
    dbstop in newplot at 124 %// The line responsible for deleting the colorbar in R2015A/B
    imagesc(newImg,'Parent',hAx);
    end
    
    % For cases when the only desired child is an Image and the axes contents are unknown
    function safeUpdateImage1(hAx,newImg,imgType,imgUpdateFcn)
    if nargin < 4 || isempty(imgUpdateFcn)
      imgUpdateFcn = @imagesc;
    end
    if nargin < 3 || isempty(imgType)
      imgType = 'Image';  
    end
    if strcmp(hAx.NextPlot,'replace') %// Equivalent to checking "ishold == false"
      hAx.NextPlot = 'add'; %// Equivalent to "hold on"
      %// hCurrImgs = get(hAx,'Children'); %// Deletes all types of Children
      hCurrImgs = findall(hAx,'type','Image'); %// Deletes only graphical objects of type 
                                               %// "matlab.graphics.primitive.Image"
      for ind1=1:numel(hCurrImgs)
        delete(hCurrImgs(ind1));
      end
      imgUpdateFcn(newImg,'Parent',hAx);
      if strcmpi(imgType,'Image')
        axis(hAx,'tight','ij');    
    %// 'tight' - XLimMode, YLimMode, and ZLimMode change to 'auto'. The limits automatic- 
    %//           ally update to incorporate new data added to the axes. To keep the limits
    %//           from changing when using hold on, use axis tight manual.
    %// 'ij'  —   Reverse direction. For axes with a 2-D view, the y-axis is vertical with
    %//           values increasing from top to bottom.    
      end
    end
    end
    
    %// When it's known that the axes contains at least one Image:
    function safeUpdateImage2(hAx,newImg,~,~)
    %// <Input checking code>
    hCurrImgs = findall(hAx,'type','Image');
    %// <Optional code to decide which Image child to update>
    hCurrImgs(1).CData = newImg; %// In this example, only update the "topmost" child
    end