【问题标题】:How to add tooltips or overlay text in a Matlab figure如何在 Matlab 图形中添加工具提示或覆盖文本
【发布时间】:2019-08-16 18:10:54
【问题描述】:

我有一个包含两行或多行的图形。这些线具有与它们相关的其他重要信息,例如平均多少数据点来创建线等。我想在我的图中访问这些信息。

我认为一个很好的解决方案是,如果您可以将鼠标悬停在一条线上并获取该扩展信息。

然而,在数字上搜索工具提示/叠加层/悬停似乎没有什么成果。

例子:

figure; hold on;
plot(1:10,rand(10,1))
plot(1:10,rand(10,1))
% additional info
plot_1_info.name = 'Alice';
plot_2_info.name = 'Bob';
plot_1_info.age = 24;
plot_2_info.age = 12;

对此有什么好的解决方案或更好的方法吗?

【问题讨论】:

  • 2 个问题:1) 您使用的是哪个 MATLAB 版本? 2) UIFigures 适合你吗?
  • 1) R2018b Update3,如果我是正确的,最新的稳定版 2) 我认为我不了解它们,但我更喜欢尽可能简单的方法
  • 1) 最新的稳定版是 R2019a ;) 2) 这同样简单......更多的是与现有代码/图形的兼容性问题(uifigures 是“新”图形)。
  • 两个答案都很棒,选择 Wolfie 的一个是为了向后兼容,应该都是正确的

标签: matlab tooltip overlay matlab-figure mouseover


【解决方案1】:

您可以更改数据游标的行为,此选项具有良好的向后兼容性(我在 R2017b 中测试过以下内容,之前在 15b 中使用过类似的)。

详情请看我的cmets:

% Create some data
x = (1:2:20).';
y = rand(10,1);
name = { 'Alice'; 'Alice'; 'Alice'; 'Alice'; 'Bob'; 'Bob'; 'Bob'; 'Chris'; 'Chris'; 'Chris' };
age = [ 24; 24; 24; 24; 12; 12; 12; 17; 17; 17 ];
% Put it in a table, so we have it all together for indexing as plot data
tbl = table( x, y, name, age );

% Create the plot, assign the UserData property to the plot object
f = figure; 
plt = plot( x, y );
plt.UserData = tbl;

% Hijack the Data Cursor update callback so we can inject our own info
dcm = datacursormode( f );
set( dcm, 'UpdateFcn', @onDataCursor );

% Function which returns the text to be displayed on the data cursor
function txt = onDataCursor( ~, evt )
    % Get containing figure
    f = ancestor( evt.Target, 'figure' );
    % Get the index within the original data
    idx = getfield( getCursorInfo( datacursormode( f ) ), 'DataIndex' );
    % The original data is stored in the UserData property
    data = evt.Target.UserData;
    % Each element of the cell array is a new line on the cursor
    txt = { sprintf( 'X: %g', data.x(idx) ), ...
            sprintf( 'Y: %g', data.y(idx) ), ...
            sprintf( 'Name: %s', data.name{idx} ), ...
            sprintf( 'Age: %g', data.age(idx) ) };          
end

输出:

注意:我没有处理过有多个数据游标提示的情况。您可以轻松地在回调中实现对 idx 的循环来处理这个问题,我将其留作练习。


这种方法非常灵活。例如,如果我们有 3 行(每个“人”一个),那么它们每个都可以有自己的 UserData 结构,我们不需要重复表格行中的所有信息。

A = struct( 'X', 1:4, 'Y', rand(1,4), 'Name', 'Alice', 'Age', 24 );
B = struct( 'X', 1:3, 'Y', rand(1,3), 'Name', 'Bob', 'Age', 12 );
C = struct( 'X', 1:3, 'Y', rand(1,3), 'Name', 'Chris', 'Age', 17 );

f = figure; hold on;
plt = plot( A.X, A.Y ); plt.UserData = A;
plt = plot( B.X, B.Y ); plt.UserData = B;
plt = plot( C.X, C.Y ); plt.UserData = C;

% ... Now the struct fields can be accessed from the callback

【讨论】:

【解决方案2】:

使用new data tip customization system introduced in R2019a,我们可以执行以下操作:

figure(); hP = plot(1:10,rand(10,1),1:10,rand(10,1));
nPts = cellfun(@numel, {hP.XData});
hP(1).DataTipTemplate.DataTipRows(end+1) = dataTipTextRow('Name', repmat("Alice",nPts(1),1) );
hP(1).DataTipTemplate.DataTipRows(end+1) = dataTipTextRow('Age',  repmat(12,     nPts(1),1) );
hP(2).DataTipTemplate.DataTipRows(end+1) = dataTipTextRow('Name', repmat("Bob",  nPts(2),1) );
hP(2).DataTipTemplate.DataTipRows(end+1) = dataTipTextRow('Age',  repmat(24,     nPts(2),1) );
% (Of course the above can be organized in a nicer way using a function)

产量:

请注意,“悬停数据提示”有黑色文本,而“点击数据提示”有蓝色文本 - 这是默认行为。

【讨论】:

  • 我想我理解脚本,但它相当复杂。我想,用我的例子,我可以去hP=findall(gcf,'type','axes'),事情会一样吗?
  • 差不多 - hP=findall(gcf,'type','Line').
  • 您能否添加/编辑必须将 char 转换为 string 才能与 Alice 和 Bob 一起使用?
  • 这对我来说是最简单的解决方案
猜你喜欢
  • 2020-10-24
  • 2017-05-06
  • 2017-08-03
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
相关资源
最近更新 更多