How can I display Index of a data point on the Data Cursor?
조회 수: 74 (최근 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!