Как программно обновить содержимое гистограммы и местоположение всплывающей подсказки? (MATLAB hg2)

Я пытаюсь сделать анимацию, где несколько наборов данных циклически перебираются в histogram plot, а подсказка данных следует за самой высокой полосой в каждом кадре, как показано ниже:

Желаемый результат

Вот код, который достигает желаемого результата с помощью гистограммы:

%% // 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 представление от FEX, согласно комментарию на странице представления (это верно для 27/06/2012 версии makedatatip):

необходимо внести пару изменений в код:
*********** ИЗМЕНИТЬ 1*********
строка 122 должна быть: pos = [X (index (n)) Y (index (n)) 0];
*********** ИЗМЕНИТЬ 2*********
строки 135-141 должны быть закомментированы OUT

А также Изменить 3: строка 84 на Z = [];

поскольку makedatatip попытки получить доступ к 'XData' а также 'YData' свойства дескриптора ввода, которые отсутствуют в histogram участки, он отказывается работать. Итак, мой вопрос:

Как можно создавать и обновлять подсказки данных в histogram графики (используя matlab-hg2) вместе с самой гистограммой?

1 ответ

Решение

Оказывается, решение довольно простое, по крайней мере, когда требуется только одна подсказка данных. Вот необходимые шаги:

  1. Замените гистограмму гистограммой:

    hHist = histogram(data(1,:),edges);
    
  2. Создайте подсказку "вручную" вместо использования 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

Что приводит к:

Желаемый результат 2


Некоторые заметки \ наблюдения:

  • Подсказки могут быть добавлены только к поддерживаемым типам данных, которые в настоящее время состоят только из double значения (т.е. построение чего-то отличного от double, по-видимому, не позволяет добавлять к нему всплывающие подсказки). Это верно для MATLAB 2015a. Смотрите другое обсуждение об этом здесь.
  • Если всплывающие подсказки должны содержать строки в формате LaTeX, в этом разделе "Вопросы и ответы" описывается, что необходимо сделать.
  • GIF-анимации, которые я использовал, были созданы с использованием этого.
  • Для центрирования анимации в постах я использовал комбинацию "alt+0160" и "alt+255".
Другие вопросы по тегам