gpt4 book ai didi

matlab - 在不删除颜色条的情况下在现有轴内显示新图像

转载 作者:太空宇宙 更新时间:2023-11-03 20:03:56 25 4
gpt4 key购买 nike

我正在开发一个通过创建多个 axes 来初始化的 GUI连同一个看不见的 colorbar 对于每一个(这样做是为了使轴保持其预定义的 Position ) 1 。存储所有轴和颜色条的句柄。

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

我对这种方法有疑问,因为我使用的是 imagesc 更新我的轴,这会删除与轴关联的所有颜色条,使存储的句柄无效。

我的问题是:我如何使用 imagescimage在不删除颜色条的情况下更新与颜色条关联的轴?

重现此问题的方法如下:

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 中找到的对象.


我假设删除颜色条是不可避免的一些想法(如果找不到“合理”的解决方案,我会继续这样做):

  1. 绑定(bind) DeleteFcn 将其数据保存到一些颜色栏 struct .在 imagesc 之后创建一个新的颜色条已经完成,然后遍历 struct 的字段并将所有属性分配给新的颜色条对象。
  2. 使用 findall(hFig,'type','colorbar') “每隔一段时间”检查所有颜色条是否存在或验证每个轴都有有效的 ColorbarPeerHandle根据下面的附录。如果无效,请重新创建 CB。
  3. 当不同的轴激活时删除所有颜色条,只创建我想显示的 CB。

附录 - ColorBar/Axes 关联:

  • 与特定轴关联的颜色条的句柄 hAx可以通过以下方式获得(在 hg2 中):

     hCb = getappdata(hAx,'ColorbarPeerHandle');
  • axes 的句柄与颜色条对象关联 hCb可以使用 2 获得:

     hAx = hCb.Axes;

最佳答案

我已经想出了几个解决方案:

  1. safeUpdateImage1 - 基于对 cla(...) 的规避,使用后在轴内创建一个新的 Image 对象保持。这对于轴中不一定存在 Image 的情况很有用。
  2. safeUpdateImage2 - 关注 mikkola's suggestion ,基于更新现有的 Image 对象。这对于已经有一个 ColorBar 一个与轴关联的 Image 的情况很有用。

下面是对原始问题的两种解决方案的演示:

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

关于matlab - 在不删除颜色条的情况下在现有轴内显示新图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33906622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com