MATLAB散布工具提示显示其他类型的数据和带箭头的连接点

时间:2017-05-24 14:34:31

标签: matlab plot tooltip matlab-figure

我想在这里问两个问题。简而言之,他们是,

  1. 在MATLAB的散点图中,如何使用工具提示单击某个点并获取x,y数据以及与x,y点相关的其他一些数据?现在我有一个使用gscatter和文件交换文件的解决方法(见下文)。但是对于大型数据集来说它会变得混乱。

  2. 如何在它们之间的线上用箭头连接两个点?例如,在MATLAB制作的rlocus图中,有一个漂亮的小箭头。在MATLAB中有任何本地方法可以执行任意绘图吗?

  3. 考虑MATLAB中的数据集

    clearvars
    LionNames={'Tyrion','Jamie','Cersei'};
    Data = rand(3,2,2);
    LionsDay1=struct('Names',{},'Data',[]);
    LionsDay2=struct('Names',{},'Data',[]);
    
    for i =1:numel(LionNames)
        LionsDay1(i).Names=LionNames{i};
        LionsDay1(i).Data=Data(i,:,1);
        LionsDay2(i).Names=LionNames{i};
        LionsDay2(i).Data=Data(i,:,2);
    end
    
    WolfNames = {'Robert','Arya','Sansa','Jon'};
    Data = rand(4,2,2);
    WolvesDay1=struct('Names',{},'Data',[]);
    WolvesDay2=struct('Names',{},'Data',[]);
    
    for i =1:numel(WolfNames)
        WolvesDay1(i).Names=WolfNames{i};
        WolvesDay1(i).Data=Data(i,:,1);
        WolvesDay2(i).Names=WolfNames{i};
        WolvesDay2(i).Data=Data(i,:,2);
    end
    

    这里每组的数据是x和y数据。出于这个问题或例子的目的,上面的数据结构并不是那么重要,但我已经做到了这一点,所以读者可以感受到大局。

    所以使用文件from MATLAB file exchange我能够分散绘图并命名每个点以及它的类。例如,

    lionsData=reshape([LionsDay1(:).Data],2,3);
    wolvesData=reshape([WolvesDay1(:).Data],2,4);
    xData=[lionsData(1,:) wolvesData(1,:)];
    yData=[lionsData(2,:) wolvesData(2,:)];
    group=repmat({'Lions'},[1,3]);
    group= [group repmat({'Wolves'},[1,4])];
    gscatter(xData',yData',group');
    
    Names=[LionNames WolfNames];
    labelpoints(xData,yData,Names)
    

    创建,

    Example

    但是你可以想象,对于大型数据集(> 50个数据点),这会变得混乱;或者如果这些点非常接近,那么第一个问题。点击一个点来显示名称会好得多。

    对于第二个问题,做,

    day1Lions=reshape([LionsDay1(:).Data],2,3);
    day2Lions=reshape([LionsDay2(:).Data],2,3);
    
    for k = 1 : size(day1Lions, 2)
        plot([day1Lions(1,k), day2Lions(1,k)], [day1Lions(2,k), day2Lions(2,k)],'s-');
        hold on
    end
    legend('Tyrion','Jamie','Cersei')
    

    给出,

    enter image description here

    所以从某种意义上说,我们可以看到这两点在第1天和第2天之间发生了多少变化现在我不知道哪一天是第1天和第2天。这样会很好将箭头从第1天数据点转到第2天数据点。当然,如果上面的悬停/工具提示问题有足够灵活的答案,那么这也可能解决这个问题。

    当然最后,我们也会在第1天和第2天将狮子和狼混在一起,但是回答这两个简单的问题也可能会在组合情节时回答问题。

1 个答案:

答案 0 :(得分:1)

答案1

一种解决方案是为data-tooltip定义自己的回调函数。为此,您首先需要在图中保存Names。我们可以使用UserData属性:

% modify the end of your code to:
gsh = gscatter(xData',yData',group');
Names = [LionNames WolfNames];
set(gsh,{'UserData'},{Names});

接下来,我们创建以下回调函数(我使用了Matlab的defualt并对其进行编辑),并将其保存在新的m文件中:

function output_txt = tooltip_callback(obj,event_obj)
% Display the position of the data cursor
% obj          Currently not used (empty)
% event_obj    Handle to event object
% output_txt   Data cursor text string (string or cell array of strings).

pos = get(event_obj,'Position');
output_txt = {['X: ',num2str(pos(1),4)],...
    ['Y: ',num2str(pos(2),4)],...
    event_obj.Target.UserData{event_obj.Target.XData==pos(1)}}; % <- this line is the only change
% If there is a Z-coordinate in the position, display it as well
if length(pos) > 2
    output_txt{end+1} = ['Z: ',num2str(pos(3),4)];
end

现在我们点击图中的一个工具提示,然后选择选择文本更新功能

tooltip menu

并从浏览器中选择我们保存的回调函数。

结果:

Names

以同样的方式,您可以根据需要将日期添加到工具提示中,或者使用我对Q2的回答......

答案2

以下是使用annotations执行此操作的方法:

ax = axes;  % create the axis
% plot all lines (no need for the loop) so we can put the legend after:
p = plot(day1Lions,day2Lions,'-');
legend('Tyrion','Jamie','Cersei')
% get the lines colors:
col = cell2mat(get(p,'Color'));
% loop through the arrows:
for k = 1:size(day1Lions, 2)
    % get the data coordinates:
    x = day1Lions(:,k);
    y = day2Lions(:,k);
    pos = ax.Position;
    % convert them to normalized coordinates:    
    %  white area * ((value - axis min)  / axis length)  + gray area
    normx = pos(3)*((x-ax.XLim(1))./range(ax.XLim))+ pos(1);
    normy = pos(4)*((y-ax.YLim(1))./range(ax.YLim))+ pos(2);
    % plot the arrow
    annotation('arrow',normx,normy,'Color',col(k,:))
end

结果:

arrows

你也可以设置原始行不可见,用:

set(p,{'Visible'},{'off'})

但它会将图例文字变为灰色,无论如何它们完全被箭头覆盖。