How to access Matlab's handle object's sub-property: 'allowedStyles' - matlab

I would like to progmatically access the 'sub-property' of a lineseries object's 'MarkerFaceColor' property called 'allowedStyles'. This 'sub-property' can be seen in Matlab's inspector, (inspect(handle)) by expanding the 'MarkerFaceColor' property row.
I would like to do something like the following or get the equivalent of such a command.
allowedstyles = get(hh,'MarkerFaceColorAllowStyles');
Screen shot of Matlab's Inspect window indicating information I seek.
https://drive.google.com/file/d/0B0n19kODkRpSRmJKbkQxakhBRG8/edit?usp=sharing
update:
For completeness my final solution for accessing this information via a cellstr was to write the following function. Thanks to Hoki.
FYI, this information (allowed styles) is useful for a GUI when you want to offer user choices for a property such as MarkerFaceColor, where you don't know the type of graphics object they are modifying. I populate a listbox with these 'allowedStyles' along with an option to set a colour. Mesh plot 'MarkerFaceColor' allows styles {'none','auto','flat'}, while a lineseries plot has {'none','auto'}.
function out = getAllowedStyles(hh,tag)
% hh - handle returned from plot, surf, mesh, patch, etc
% tag - the property i.e. 'FaceColor', 'EdgeColor', etc
out = [];
try
aa = java(handle(hh(1)));
bb = eval(sprintf('aa.get%s.getAllowedStyles;',tag));
bb = char(bb.toString);
bb(1) = []; bb(end) = [];
out = strtrim(strsplit(bb,','));
end
end

I think it is indeed ReadOnly (or at least I couldn't find the correct way to set the property, but it is definitely readable.
You need first to access the handle of the underlying Java object, then call the method which query the property:
h = plot([0 1]) ; %// This return the MATLAB handle of the lineseries
hl = java(handle(h)) ; %// this return the JAVA handle of the lineseries
allowedstyles = hl.getMarkerFaceColor.getAllowedStyles ; %// this return your property :)
Note that this property is actually an integer index. Your inspect windows translate it to a string saying [none,auto] while in my configuration even the inspect windows only shows 1.
If you want the exact string translation of other values than one, you can call only the parent method:
hl.getMarkerFaceColor
This will display the allowed style in plain text in your console window.
ans =
com.mathworks.hg.types.HGMeshColor#28ba43dd[style=none,allowedStyles=[none, auto],red=0.0,green=0.0,blue=0.0,alpha=0.0]
If you insist on getting this property as a string progamatically, then you can translate the above using the toString method.
S = char( hl.getMarkerFaceColor.toString )
S =
com.mathworks.hg.types.HGMeshColor#1ef346e8[style=none,allowedStyles=[none, auto],red=0.0,green=0.0,blue=0.0,alpha=0.0]
then parse the result.

Related

Find all objects in Matlab figure which have a callback

In my current figure I need to find all objects which have some callback set. More specifically, all objects which have a non-empty ButtonDownFcn.
I tried everything, e.g. findobj(gca, '-regexp', 'ButtonDownFcn', '\s+'), but I get this error: Warning: Regular expression comparison is not supported for the 'Callback' property: using ordinary comparison.
The problem is that the objects have no tags or anything which would "define" them uniquely, except that they are all "clickable". Is there an easy way to do it? Using findobj or findall.
Thanks.
findobj does not support regular expression comparison for the 'ButtonDownFcn' property, as the warning says. This probably happens because the contents of the property are not necessarily text (they can be function handles).
You can use a for loop over all objects of the figure:
result = [];
hh = findobj(gcf);
for h = hh(:).'
if ~isempty(get(h, 'ButtonDownFcn'))
result = [result h];
end
end
Or equivalently you can use arrayfun:
hh = findobj(gcf);
ind = arrayfun(#(h) ~isempty(get(h, 'ButtonDownFcn')), hh);
result = hh(ind);

Accessing graphic object properties using dot notation on Matlab versions anterior to R2014b

Trying to change the colors of an Axis in a matlab plot here.
Referencing matlab documentation: Matlab docs on setting axis properties
Code snippet:
subplot( 'Position', [ left bottom (1/(cols*2)) (1/rows) ] );
ax = gca;
ax.Color = 'y';
That's all but a copy and paste from the example in the docs (shown here):
But matlab throws up a warning and doesn't change the axis colors for me:
Warning: Struct field assignment overwrites a value with class
"double". See MATLAB R14SP2 Release Notes, Assigning Nonstructure
Variables As Structures Displays Warning, for details.
I tried assigning a double, like say 42.0, but it didn't like that any better.
Your warning message seems to indicate you are using a version anterior to Matlab R2014b.
If it is that, you do not have access to the dot notation directly because when you do ax=gca; you get a return value ax which is of class double. The value is the ID of the handle to the object (the current axis in this case) but not the handle itself.
When you try ax.Color = 'y';, Matlab thinks you want to overwrite your ax [double] with a new variable ax which would be a structure, with the field color, and throw a warning.
You can still access the dot notation for the graphic obects and properties but you have to first retrieve the real handle of the object, by using the function handle. For example:
ax = handle( gca) ; %// the value "ax" returned is an `object`, not a `double`
or even on an existing reference to a graphic object handle:
ax = gca ; %// retrieve the `double` reference to the handle
...
ax = handle(ax) ; %// the value "ax" returned is an `object`, not a `double`
after that you should be able to use the dot notation for all the public properties of the graphic object. ax.Color = 'y'; should now be valid

Issue with Setting Position of Uitable in MATLAB

I am trying to create a uitable in matlab. Consider the following simple example:
f = figure;
data = rand(3);
colnames = {'X-Data', 'Y-Data', 'Z-Data'};
t = uitable(f, 'Data', data, 'ColumnName', colnames, ...
'Position', [20 20 260 100]);
Next, I am trying toset the width and height of the uitable to match the size of the enclosing rectangle:
t.Position(3) = t.Extent(3);
t.Position(4) = t.Extent(4);
However I get the following error:
>> t.Position(3) = t.Extent(3);
t.Position(4) = t.Extent(4);
Attempt to reference field of non-structure array.
When I try to view what t is, I get:
>> t
t =
2.1030e+03
I don't know what this result means! I am a little confused as this is the first time I am working with uitable and I am very new to MATLAB too.
Any help would be appreciated. Thanks!
Per the comments, transposing my comment above into an answer.
For the example code to function properly you will need MATlAB R2014b or newer. Per the release notes for MATLAB R2014b, graphics handles are now objects and not doubles, bringing graphics objects in line with the rest of MATLAB's objects. One benefit to this is the user is now able to utilize the dot notation to address and set the properties of their graphics objects. This is a change from older versions where graphics handles were stored as a numeric ID pointing to the relevant graphics object, requiring the user to use get and set to access and modify the graphics object properties.
To resolve your issue, you just need to modify the dot notation usage to get or set where appropriate. Or upgrade MATLAB :)
For example,
t.Position(3) = t.Extent(3);
t.Position(4) = t.Extent(4);
becomes:
tableextent = get(t,'Extent');
oldposition = get(t,'Position');
newposition = [oldposition(1) oldposition(2) tableextent(3) tableextent(4)];
set(t, 'Position', newposition);

Find handles with a specific pattern

I have some handles that look like:
ans =
figure1: 189.0205
sampleNameEdit: 17.0216
selectCatPopup: 16.0237
radiobutton_Al: 14.0266
radiobutton_O: 190.0183
output: 189.0205
How can I easily look for those handles that start with radiobutton__? In the future, I will have many more radiobuttons that I would like to retrieve easily.
To search for a specific pattern in a handle's name, the best approach would be to follow Luis Mendo's advice in his answer. However, consider searching based on the type of object you are looking for. In this case, it would seem that all radiobutton objects need to be located.
The most straightforward way to find handles of for a certain style of uicontrol, is to search for handles with their Style Property set to radiobutton. Consider a figure with two controls: a text box and a radio button, with their handles stored in an ordinary array uih:
hf = figure; % parent of uicontrols
uih(1) = uicontrol('style','text');
uih(2) = uicontrol('style','radiobutton');
Here are my test handle vales (yours will be different):
>> uih
uih =
3.0012 4.0012
The first is the text box, and the second is the radio button.
Search by parent handle
If you have the parent handle (i.e. the figure handle, hf), you don't even need the list of handles uih! Just call findobj as follows:
hr = findobj(hf,'style','radiobutton')
hr =
4.0012
Search handle array
If you don't have the parent handle, but do have a list of handles to search, that's no problem either:
hr = findobj(uih,'style','radiobutton')
hr =
4.0012
Search struct of handles
In your case, you have the handles stored as fields in a struct:
handles =
ht: 3.0012
hr: 4.0012
hr = findobj(structfun(#(x)x,handles),'style','radiobutton')
hr =
4.0012
Don't worry, this finds all radio buttons!
Assuming you have a struct with each handle stored in a different field:
s.radiobutton_1 = 1; %// example data: struct with several fields
s.otherfield = 22;
s.radiobutton_2 = 333;
names = fieldnames(s); %// get all field names
ind = strmatch('radiobutton_',names); %// logical index to matching fields
selected = cellfun(#(name) s.(name), names(ind)); %// contents of those fields
returns the desired result:
selected =
1
333
It's not really clear where you get that ans from and what its structure is, and what exactly is supposed to "start with" "radiobutton_". However, if you want to get handles to all existing radiobuttons, findobj is the way to go:
h = findobj(findobj('Type', 'uicontrol'), 'Style', 'radiobutton');
You can restrict the search to children e.g. of the current figure using
h = findobj(findobj(gcf, 'Type', 'uicontrol'), 'Style', 'radiobutton');
and you can restrict the search to a given list of handles oh (without children) using
h = findobj(findobj(oh, 'flat', 'Type', 'uicontrol'), 'Style', 'radiobutton');

Customizing cursor in Matlab

In Matlab 2012a I have generated a figure from a previous code that is SSI as a function of age.
I want to customize datatip by updating my own function instead of the default one. I know how to change x and y and now I have Age and SSI for them. However, I have another piece of information -subjectID- which I want to add to the display text.
By clicking on each point, I want datatip to show Age, SSI and subject ID of corresponding data point.
This is what I have now:
matlab is a saved work place of my SSI-age.
function output_txt = myupdatefcn(obj,event_obj,...
matlab,labels,SubjectID)
pos = get(event_obj,'Position');
x = pos(1);
y = pos(2);
[~, ~, raw0_0] = xlsread('Data.xlsx','CONTROLS','A2:A106');
raw = [raw0_0];
SubjectID = cell2mat(raw);
output_txt = {['AGE: ',num2str(pos(1),4)],...
['SSI: ',num2str(pos(2),4)],...
['SubjectID: ',SubjectID]};
idx = find(matlab == x,1);
[row,col] = ind2sub(size(matlab),idx);
output_txt{end+1} = cell2mat(labels(row));
Obviously, this is not right. Can somebody please help me out here? Thank you.
If I read your code correctly, I make the following assumptions (which may be incorrect):
* the subjectID is a cell containing a vector of strings
* subjectID is X position of the clicked point
First, a quick digression: getting SubjectID into your plot
I noticed, in your function call, you have SubjectID as one of the input parameters. However, it appears that it would never be used, since the next line that uses it assigns it a value.
As written, this will read from the excel file each and every time that the update function is called. You might wish to move the load-from-excel portion into the same section of code where the data is first loaded. If I assume the SubjectID is text, you can store it in the UserData variable of the timeseries. That would make the following work:
Onward to the answer
So, if you include your SubjectID information in the userdata, when you first plot like so:
% ...not shown: get the ages, SSIs and SubjectIDs ....
plot(ages, SSIs, 'UserData', SubjectIDs); % Store SubjectIDs along with the line...
Then the following should work -- or at least put you on solid ground.
function output_txt = myupdatefcn(obj,event_obj)
pos = get(event_obj,'Position');
x = pos(1);
y = pos(2);
allIDs = get(event_obj.Target,'UserData');
thisSubject = event_obj.UserData{pos(1)};
output_txt = {['AGE: ',num2str(pos(1),4)],...
['SSI: ',num2str(pos(2),4)],...
['SubjectID: ',thisSubject]};
You can probably get rid of the last 3 lines of code, since you know a priori that all 3 values are accessible.
Hope that helps.