如何以编程方式更新直方图内容和数据提示位置? (MATLAB hg2)

How to programatically update histogram contents and datatip location? (MATLAB hg2)

我正在尝试制作一个动画,其中多个数据集在 histogram 图中循环,并且数据提示跟随每一帧中的最高条,如下所示:

这是使用 bar graph:

实现预期结果的代码
%% // Initialization
close all force; clear variables; clc;
%% // Generate some data:
indMax = 20; data = randi(indMax,[5,45]);
%% // Generate the 1st values to plot:
edges = 0.5:1:indMax+0.5;
counts = histcounts(data(1,:),edges);
[~,maxInd] = max(counts);
%% // Create the plot and the datatip:
figure(100); hBar = bar(1:indMax,counts); 
hDT = makedatatip(hBar,maxInd); hDT = handle(hDT);
grid on; hold on; grid minor; xlim([0,indMax+1]); ylim([0,10]);
%% // Update the figure and the datatip:
for indFrame = 2:size(data,1)       
   counts = histcounts(data(indFrame,:),edges);
   [~,maxInd] = max(counts);
   hBar.YData = counts; %// Update bar heights
   hDT.Cursor.DataIndex = maxInd; %// Update datatip location
   %// Alternatively to the above line: hDT.Position = [newX newY newZ];
   java.lang.Thread.sleep(1000);
   drawnow;
end

请注意,根据提交页面上的评论,数据提示是使用 makedatatip submission from FEX 的修改版本创建的(这适用于 makedatatip 的 27/06/2012 版本) :

a couple of changes need to be made to the code:
***********CHANGE 1*********
line 122 needs to be: pos = [X(index(n)) Y(index(n)) 0];
***********CHANGE 2*********
lines 135-141 should be commented OUT

还有改变3: line 84 to Z = [];

由于 makedatatip 试图访问输入句柄的 'XData''YData' 属性,这些属性在 histogram 图中不存在,因此它拒绝工作。所以我的问题是:

如何在 histogram 图中(使用 )以编程方式创建和更新数据提示以及直方图本身?

事实证明,解决方案非常简单,至少在只需要一个数据提示时是这样。以下是所需的步骤:

  1. 用直方图替换条形图:

    hHist = histogram(data(1,:),edges);
    
  2. 创建数据提示 "manually" 而不是使用 makedatatip:

    hDataCursorMgr = datacursormode(ancestor(hHist,'figure'));
    hDT = createDatatip(hDataCursorMgr,hHist);
    
  3. 根据需要更新位置:

    hDT.Cursor.DataIndex = maxInd;
    
  4. 要更新直方图的条形高度,无法直接更新 'Values' 属性(因为它是只读的),因此必须更新 'Data' 属性(让 MATLAB 自行重新计算条形高度):

    hHist.Data = data(indFrame,:);
    

所有东西放在一起:

%% // Initialization
close all force; clear variables; clc;
%% // Generate some data:
indMax = 20; data = randi(indMax,[5,45]);
%% // Generate the 1st values to plot:
edges = 0.5:1:indMax+0.5;
counts = histcounts(data(1,:),edges);
[~,maxInd] = max(counts);
%% // Create the plot and the datatip:
figure(100); hHist = histogram(data(1,:),edges);
hDataCursorMgr = datacursormode(ancestor(hHist,'figure'));
hDT = createDatatip(hDataCursorMgr,hHist); hDT.Cursor.DataIndex = maxInd;
grid on; hold on; grid minor; xlim([0,indMax+1]); ylim([0,10]);
%% // Update the plot and the datatip:
for indFrame = 2:size(data,1)       
   [~,maxInd] = max(histcounts(data(indFrame,:),edges));
   hHist.Data = data(indFrame,:);
   hDT.Cursor.DataIndex = maxInd;
   java.lang.Thread.sleep(1000);
   drawnow;
end

这导致:


一些笔记\观察:

  • 数据提示只能添加到支持的数据类型,目前仅由 double 值组成(即绘制除双精度以外的其他内容显然不允许您向其添加数据提示)。这适用于 MATLAB 2015a。请参阅有关它的另一个讨论 here
  • 如果数据提示应该包含一些 LaTeX 格式的字符串, 描述了需要做什么。
  • 我使用的 gif 动画是使用 this 创建的。
  • 为了让动画在帖子中居中,我结合使用了 "alt+0160" 和 "alt+255"。