Identify exact jittered point from swarmchart plot
Ältere Kommentare anzeigen
I created a horizontal swarmchart in app designer. The input data have numeric values and grouping tags (intGroups) associated with each point. Each point's color is associated with its group. I also defined a ButtonDownFcn to get the point that the user clicks on (using code from a previous Matlab Answer).
The issue is that when I click a point, swarmchart's XData and YData give the undithered coordinates (i.e., the y-values are all the same). So if I click a point that is far from center (due to a lot of points having that same value), the code below may or may not identify that point I clicked, so I may not get the correct group.
Is there a way to ensure that I get the exact point I clicked (or its index in the vector), not others that are in the same vicinity?
for zz = 1:length(intVarsUnique)
hPlot = swarmchart(axPlot, xData(:, zz), intVars(:, zz), [], categorical(strGroupColors), 'filled', 'o', ...
'YJitter','density', ...
'HitTest', 'on', 'ButtonDownFcn', @(src, eventData) fcnPlot_ButtonDown(app, src, eventData));
if ~ishold(axPlot)
hold(axPlot, 'on');
end
end % zz
hold(axPlot, 'off');
function fcnPlot_ButtonDown(app, hPlot, eventData)
% Based on code from Yair Altman in https://www.mathworks.com/matlabcentral/answers/1903190-get-data-point-that-was-clicked-on-in-graph
% Get the click coordinates from the click event data
x = eventData.IntersectionPoint(1);
y = eventData.IntersectionPoint(2);
line_xs = hPlot.XData;
line_ys = hPlot.YData;
dist2 = (x-line_xs).^2 + (y-line_ys).^2;
[~,min_idx] = min(dist2);
closest_x = line_xs(min_idx);
closest_y = line_ys(min_idx);
msgbox(sprintf('Clicked on: (%g,%g)\nClosest pt: (%g,%g)', x, y, closest_x, closest_y));
% Code to locate point in vector and ID group...
end
5 Kommentare
Attach a representative dataset and example point to better illustrate.
OTOMH, however, I don't see an obvious solution in general if data groups are not isolated sufficiently from each other that one from group B is closer than the nearest in group A without additional help to restrict which group is desired--the distance alone won't do it.
But, running one of the example codes and looking inside the returned scatter object, the actual jittered coordinates are not exposed nor even visible using Yair's undocumented handles tool, so there isn't an acessible but hidden property to use to retrieve the actual plotted position coordinates of the jittered datapoint; nor could I find an array of jitter values to apply to the fixed x/y values. They have to be inside somewhere, but they do not seem to be accessible at all.
About the best idea I've got is to either look at the specific y-value returned and try to find in which group it resides which is problematical if all datapoints are not unique.
The 'MarkerFaceColor' is 'flat' since uses the colormap so the alternative is to try to match the CData rgb triplet
x=[1:3].*ones(500,3); y=[2 4 6].*randn(500,3)+[0 2 4];
c=eye(3);
hSW=swarmchart(x,y,[],c,'filled')
vertcat(hSW.MarkerFaceColor) % uninformative
vertcat(hSW.CData) % does return the rgb color (r, g, b here...)
Yair Altman
am 9 Sep. 2025
@dpb - perhaps you didn't use my getundoc utility, or perhaps you missed the prive XYZJitter* properties that it reports. See my answer below for additional details.
@Yair Altman, I did use a local copy of your utility(*), yes, but, indeed, I didn't see the jitter properties...am in debugging session at the moment so it's not handy to go explore again at the moment, but I'll have to recheck.
I don't recall why, for some reason I just renamed it locally; I guess because I never recalled the spelling so as was...
ADDENDUM:
Aha! The difference is that in R2021b here the two properties of interest are not only hidden but were not made public as noted in earlier answer...
From the same example as above locally,
I saw the jitter properties names, problem is they weren't accessible and I made the presumption they wouldn't have been made so since which clearly is no longer so; not sure when might have changed, although has to have been after R2022b which is latest release have installed.
>> undocumented(hSW(1)) % Yair's utility renamed so I can remember exactly how spelled <g>
ans =
struct with fields:
...
Jitter: off
JitterAmount: 0.2000
JitterAmountMode: 'auto'
JitterAmount_I: 0.2000
JitterDirty: '???'
JitterDirtyMode: 'auto'
JitterDirty_I: '???'
JitterMode: 'auto'
Jitter_I: off
LegendDisplay: on
...
...
XJitterMode: 'manual'
XJitterWidthMode: 'manual'
XJitterWidth_I: 0.9000
XJitter_I: 'density'
XLimInclude: on
XLimIncludeMode: 'auto'
XLimInclude_I: on
XVariable_I: ''
XYZJitterMode: 'auto'
XYZJittered: '???'
...
>> hSW(1).XYZJittered
No public property 'XYZJittered' for class 'Scatter'.
>> hSW(1).XYZJitter
Unrecognized method, property, or field 'XYZJitter' for class 'matlab.graphics.chart.primitive.Scatter'.
>>
Yair Altman
am 9 Sep. 2025
Bearbeitet: Yair Altman
am 9 Sep. 2025
Undocumented properties are often protected or private, not just hidden, and in such cases you can't access them directly using the base object. Instead, you must use the struct function, i.e.
struct(hSW(1)).XYZJittered
AHA! I had overlooked could do that, thanks for pointing it out. Glad that I persisted... <g>
However, another case of so many where Mathworks seems to have a penchant for hiding things from the end user that clearly would/could be of use to the user. Having to go to such lengths to discover such is very counter-productive in terms of the end-user effort.
Akzeptierte Antwort
Weitere Antworten (0)
Kategorien
Mehr zu Tables finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
