How can I display Index of a data point on the Data Cursor?
73 次查看(过去 30 天)
显示 更早的评论
When I use the Data Cursor option on a plot, I am able to view the X and Y-coordinates on the tool tip. However I wish to see the index of that point. I have tried editing the textUpdate function as follows:
function output_txt = myfunction(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');
x = pos(1);
y = pos(2);
idx = find(xydata == x,y);
[row,~] = ind2sub(size(xydata),idx);
output_txt{end+1} = cell2mat(labels(row));
However this gives an error. Does anyone have any suggestions?
Thanks in advance
Deepa
2 个评论
Adam
2017-7-7
编辑:Adam
2017-7-7
You haven't shown what you are doing with that function (how you are calling it) or what the error is so you can't really expect to get too much help if you don't give all relevant information.
dcm = datacursormode( hFig );
dcm.UpdateFcn = @updateDataCursor;
is the kind of thing to use to create a custom data cursor if you put the relevant code in updateDataCursor which may be what your 'myFunction' is, but that would just be a guess since you haven't shown that part of the code.
采纳的回答
Deepa T
2017-7-12
编辑:Deepa T
2017-7-12
3 个评论
Samuli Karvinen
2020-1-15
Hey,
Oh I see, what data have put in there? The data tip objects?
Thanks in advance!
Samuli
更多回答(3 个)
Les Beckham
2017-7-8
Try this (modify the num2str calls as you wish to get the number of digits you desire):
function output_txt = datatip_cb15digits(obj,event_obj)
% datatip_cb15digits.m - datatip callback function - modified to display 15 digits
% 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');
handles = get(gca, 'Children');
h=handles((handles == event_obj.Target));
dim = 2; % initially assume this is a 2d plot
output_txt = {['X: ',num2str(pos(1),15)],...
['Y: ',num2str(pos(2),15)]};
% 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),15)];
dim = 3;
end
% display the index of the currently selected datapoint
if (dim == 2)
i = find(get(h, 'XData') == pos(1) & get(h, 'YData') == pos(2));
else
i = find(get(h, 'XData') == pos(1) & get(h, 'YData') == pos(2) ...
& get(h, 'ZData') == pos(3));
end
output_txt{end+1} = ['i: ', num2str(i)];
5 个评论
Walter Roberson
2017-7-9
Correct, the data index is specific to the line that was clicked on, and indicates the relative offset into the line, as in XData(index) YData(index) . This need not be sorted by x or y, and is completely independent of every other line or graphics object.
If you have access to all of the data to be plotted, you could always unique() the complete list of y values concatenated together, and request the third output of unique() so you know the index of each of the values relative the list of unique values, and then you could break that list up using mat2cell() according to the length of each original line, and then you could set() the UserData for each line to include the y indices for each point. Then your update handler can use the data index to index the UserData to get the information to display.
Walter Roberson
2017-7-9
Suppose you have a cell, Xs, of all of the X values, and a cell Ys, of the corresponding Y values, such as might be plotted with
XYs = [Xs(:).'; Ys(:).'];
plot(XYs{:})
Then,
%create a giant column vector of all of the Y values
%and find the unique Y values and the indices of each
%original value into the unique list.
%this code does not assume anything about the orientation
%of the vectors
[uY, ~, uYidx] = unique( cell2mat( cellfun(@(V) V(:), Ys(:), 'Uniform', 0) ) );
Ylens = cellfun(@length, Ys);
Yidxcell = mat2cell(uYidx, Ylens, 1);
XYs = [Xs(:).'; Ys(:).'];
linehandles = plot(XYs{:});
for K = 1 : length(linehandles)
set(linehandles(K), 'UserData', Yidxcell{K});
end
Together with
function txt = myupdatefcn(obj, event_obj)
pos = get(event_obj,'Position');
x = pos(1); y = pos(2);
I = get(event_obj, 'DataIndex');
Yidxs = get(obj, 'UserData');
if isempty(Yidxs) || length(Yidxs) < I;
Yidx = '?';
else
Yidx = Yidxs(I);
end
txt = {['X: ',num2str(x)],...
['Y: ',num2str(y)],...
['I: ', Yidx]};
2 个评论
Les Beckham
2017-7-9
There are definitely some very clever Matlab tricks and manipulations going on here, but in what legitimate use case would anyone ever create a plot this way? Since the OP never gave us an example of how the data is being plotted or what they are really trying to achieve, I'm skeptical that your very creative answer will really solve the poorly defined problem. OP did comment that "That sounds like what I want to do," so, hopefully I'm wrong.
I would definitely be interested in some sort of real world example where this approach would apply.
Walter Roberson
2017-7-10
Les, see https://www.mathworks.com/matlabcentral/answers/347916-i-have-an-array-which-is-increasing-at-one-point-it-starts-to-decrease-this-trend-starts-repeatin#comment_467698 where I implemented a plot using exactly this scheme of cells of coordinates.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!