我想在这里问两个问题。简而言之,他们是,
在MATLAB的散点图中,如何使用工具提示单击某个点并获取x,y数据以及与x,y点相关的其他一些数据?现在我有一个使用gscatter和文件交换文件的解决方法(见下文)。但是对于大型数据集来说它会变得混乱。
如何在它们之间的线上用箭头连接两个点?例如,在MATLAB制作的rlocus
图中,有一个漂亮的小箭头。在MATLAB中有任何本地方法可以执行任意绘图吗?
考虑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)
创建,
但是你可以想象,对于大型数据集(> 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')
给出,
所以从某种意义上说,我们可以看到这两点在第1天和第2天之间发生了多少变化但现在我不知道哪一天是第1天和第2天。这样会很好将箭头从第1天数据点转到第2天数据点。当然,如果上面的悬停/工具提示问题有足够灵活的答案,那么这也可能解决这个问题。
当然最后,我们也会在第1天和第2天将狮子和狼混在一起,但是回答这两个简单的问题也可能会在组合情节时回答问题。
答案 0 :(得分: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
现在我们点击图中的一个工具提示,然后选择选择文本更新功能:
并从浏览器中选择我们保存的回调函数。
结果:
以同样的方式,您可以根据需要将日期添加到工具提示中,或者使用我对Q2的回答......
以下是使用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
结果:
你也可以设置原始行不可见,用:
set(p,{'Visible'},{'off'})
但它会将图例文字变为灰色,无论如何它们完全被箭头覆盖。