What's the complete structure of a figure handle object? - matlab

Mathworks has done it again: my ancient R2012 (as bestowed by my company) returns a nice set of doubles identifying the figure window numbers in response to
currhandles=findall(0,'type','figure');
Now I got a fellow remotely IM-ing me 'cause the code I gave him fails under R2015 because findall now returns a structure for the figure handle. I can't play w/ his system (no RDC) and the mathworks documentation pages don't appear to specify the elements of the figure handle structure. In particular, I'd like to know if I can still retrieve the figure window number. Anyone know?

Of course.
currhandles(:).Number
will return all numbers as a comma-separated list.
Or specify a number you want:
currhandles(1).Number
The order appears to be the inverse order of initialization.
Alternatively you can define two anonymous functions to get an array directly:
figure(1); figure(2); figure(42);
getNumbers = #(x) [x.Number];
getFigureNumbers = #() getNumbers([findall(0,'type','figure')]);
getFigureNumbers()
ans =
42 2 1

Related

Creating functions in Matlab

Hi, I am trying to write a function as per the question. I have tried to create four sub-matrices which are the reverse of each other and then multiply to give the products demanded by the question. My attempt:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
What I'm unsure of is
(i) What do the the indivual sub-matrices(T(1:end,end-1:1);)need to be equal to? I was thinking of(1:3)?
(ii) I tried to create a generic sub-matrix which can take any size matrix input using end was this correct or can't you do that? I keep getting this error
Undefined function or variable 'T'.
Error in custom_blocksT (line 2)
T(1:end,end-1:1);
I have searched the Matlab documentation and stacked overflow, but the problem is I'm not quite sure what I'm supposed to be looking for in terms of solving this question.
If someone could help me I would be very thankfull.
There are many problems with your function:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
end
This is an extremely basic question, I highly recommend you find and work through some very basic MATLAB tutorials before continuing, even before reading this answer to be honest.
That said here is what you should have done and a bit of what you did wrong:
First, you are getting the error that T dos not exist because it doesn't. The only variables that exist in your function are those that you create in the function or those that are passed in as parameters. You should have passed in T as a parameter, but instead you passed in n and m which you don't use.
In the question, they call the function using the example:
custom_blocks([1:3;3:-1:1])
So you can see that they are only passing in one variable, your function takes two and that's already a problem. The one variable is the matrix, not it's dimensions. And the matrix they are passing in is [1:3;3:-1:1] which if you type in the command line you will see gives you
[1 2 3
3 2 1]
So for your first line to take in one argument which is that matrix it should rather read
function TOut = custom_blocks(TIn)
Now what they are asking you to do is create a matrix, TOut, which is just different multiples of TIn concatenated.
What you've done with say TIn(1:end,end-1:1)*2; is just ask MATLAB to multiple TIn by 2 (that's the only correct bit) but then do nothing with it. Furthermore, indexing the rows by 1:end will do what you want (i.e. request all the rows) but in MATLAB you can actually just use : for that. Indexing the columns by end-1:1 will also call all the columns, but in reverse order. So in effect you are flipping your matrix left-to-right which I'm sure is not what you wanted. So you could have just written TIn(:,:) but since that's just requesting the entire matrix unchanged you could actually just write TIn.
So now to multiply and concatenate (i.e. stick together) you do this
TOut = [TIn, TIn*2; TIn*3, TIn*4]
The [] is like a concatenate operation where , is for horizontal and ; is for vertical concatenation.
Putting it all together:
function TOut = custom_blocks(TIn)
TOut = [TIn, TIn*2; TIn*3, TIn*4];
end

How to allow multiple syntax options in MATLAB function calls

I am writing a set of customized plot functions in MATLAB, whose aim is to ensure a more consistent look of our company charts and to be fast.
In these customized functions, I would like to reproduce MATLAB's variability in allowing multiple syntax options for function calls, similar to the syntax options available for MATLAB's plot function.
So, say my function is plotFun.m, then the following function calls should all work:
plotFun(y)
plotFun(x,y)
plotFun(ax,_)
plotFun(_,Name,Value)
I am familiar with inputParser and several other techniques to parse name-value pairs passed as varargin, yet I cannot figure out how to parse the first arguments, that is ax, x and y...
I have scanned the file exchange and found several contributions for parsing name-value pairs (somehow overlapping with the inputParser functionality), but none of them seems to do the trick in this case.
EDIT:
In reply to thewaywewalk 's comment, here are some more details regarding what the syntax options should do.
Suppose plotFun does something similar as the line function (but with other defaults and a different set of allowed options).
y should be validated to be a numerical vector
x (if present) should be validated to be a numerical or datetime vector
plotFun(x,y)
If x is of class datetime, x = datenum(x), then
call line(x,y, 'Parent',gca)
plotFun(y)
should set x = 1:numel(y), then call line(x,y, 'Parent',gca) as above
plotFun(ax,_)
should do the same as above, but call line(x,y, 'Parent',ax) instead of gca
plotFun(_,Name,Value)
should parse and validate the name-value pairs and pass them to the call of line. I solved this task with the help of inputParser.
EDIT 2
In the world of my dreams, hitting Ctrl + F1 for plotFun would show the function hints, that is, a list of allowed syntax options (like the one I typed in the code block above), as opposed to showing a more cryptic plotFun(varargin)...

Matlab: How to use cellfun when using "createOptimProblem"?

I would like to find global minima using an objective function I defined.
The code I used is:
opts = optimoptions(#fmincon,'Algorithm','interior-point');
gs = GlobalSearch;
problem = createOptimProblem('fmincon','x0',a,'objective', #(s) obj(supdata,s),'options',opts);
[xg, fg, exitflag, output, solutions ]=run(gs, problem)
The problem is that supdata is for a specific firm, and I need to get the optimal result for each firm (there are thousands of them). I want to apply this code using a big data input (which I already have, in a cell array, with each cell being a specific firm), and the output xg fg... are also varies among firms.
I was hoping to use a loop inside the function obj, but people here suggested that I to change my function to use cellfun: see my original question. But I don't know how to incorporate it into globalsearch. It is more complicated than just calling the solver fmincon.

matlab zplane function: handles of vectors

I'm interested in understanding the variety of zeroes that a given function produces with the ultimate goal of identifying the what frequencies are passed in high/low pass filters. My idea is that finding the lowest value zero of a filter will identify the passband for a LPF specifically. I'm attempting to use the [hz,hp,ht] = zplane(z,p) function to do so.
The description for that function reads "returns vectors of handles to the zero lines, hz". Could someone help me with what a vector of a handle is and what I do with one to be able to find the various zeros?
For example, a simple 5-point running average filter:
runavh = (1/5) * ones(1,5);
using zplane(runavh) gives an acceptable pole/zero plot, but running the [hz,hp,ht] = zplane(z,p) function results in hz=175.1075. I don't know what this number represents and how to use it.
Many thanks.
Using the get command, you can find out things about the data.
For example, type G=get(hz) to get a list of properties of the zero lines. Then the XData is given by G.XData, i.e. X=G.XData.
Alternatively, you can only pull out the data you want
X=get(hz,'XData')
Hope that helps.

Getting Matlab handles events or properties

The question
How may I get the list of events and properties for a handle of double type, as a figure, axes?
The issue
Matlab documentation says to you to use the WindowButtonDownFcn, WindowButtonMotionFcn, and so on in order to listen to whatever happens at your interface. The issue is that this properties are very limited as the following fact:
Keeping Variables in Scope
When MATLAB evaluates function handles, the same variables are in
scope as when the function handle was created. (In contrast, callbacks
specified as strings are evaluated in the base workspace.) This
simplifies the process of managing global data, such as object
handles, in a GUI.
Yes, this is perfect, if you don't have to redefine, add, or remove callbacks from your ButtonDownFcn, because if you do so, you will lose the other function handles variable scopes, as you are declaring them at a new scope which may will certainly not contain your so needed variables.
So one way would be to listen to the events themselves, not to properties that are called when the events are actived, and by doing so, you will not have to bother to redeclare your ButtonDownFcn and how to keep your variables at scope, because the other solutions are very slow to implement!. If I could listen to the events directly, as I do with handle.listener or addlistener matlab listening tools, I would not have to bother with that.
One good approach already known
One of the best solutions it seems is this FEX, which empowers the weak matlab WindowButtonDownFcn, WindowButtonDownFcn and whatever properties "listeners" function matlab has, so that you can have any amounts of functions listening to changes at the your graphical interface without having to care if your other functions handles will lose their scope variables.
With this I don't need to get the matlab events as it wrappers everything for me. But it still amuses me that matlab lead your users to use a broken feature instead of documenting the better approach and lead people to wrap everything around so that they can use things as they should be.
Information that may be useful.
I know about the meta.class that will give me all the properties, events and so on that a class have. For one class I have that inherits from a handle:
>> EventMeta = ?Event
EventMeta =
class with properties:
Name: 'Event'
Description: ''
DetailedDescription: ''
Hidden: 0
Sealed: 0
Abstract: 0
ConstructOnLoad: 0
HandleCompatible: 1
InferiorClasses: {0x1 cell}
ContainingPackage: []
PropertyList: [64x1 meta.property]
MethodList: [29x1 meta.method]
EventList: [2x1 meta.event]
EnumerationMemberList: [0x1 meta.EnumeratedValue]
SuperclassList: [1x1 meta.class]
with that meta I can get the EventList from my Event class, which are:
>> EventMeta.EventList.Name
ans =
attemptToClick
ans =
ObjectBeingDestroyed
Well, this is not that great thing in this case, since I have implemented it and I know the events it has because I have the source. The thing is, if I can get the metaclass of a figure (if that is possible), I could have access to its implemented Events if they are available at the matlab.
Under the hood, Handle Graphics (HG) are implemented using the undocumented UDD mechanism, not the usual classdef-style OOP exposed to the user.
That's why you cant directly use the meta.class system to get meta-information on such handles.
As you already found out on Yair Altman's blog, there are undocumented ways to listen to events:
fig = hg.figure(); plot(rand(100,1))
lh = handle.listener(fig, 'WindowButtonDownEvent',#(~,~)disp('clicked'));
If you already have an existing HG object handle (represented with a numeric handle), use handle to convert it to a UDD handle:
f = figure();
fig = handle(f);
and yes I know, the term handle is quite overloaded in MATLAB and may refer to many things
As I was improving my question, I managed to find an answer for this (unfortunately it seems that I haven't seem them before at my searchs, and what's worse, some of the links I've opened beforeā€¦)
Here the undocummented matlab blog shows how to get the handles from a matlab handle object. And it seems that there was already a question about this made at 2011 about this issue here in stackoverflow, and properly answered by #gnovice. The answer is:
>> get(get(classhandle(handle(gcf)),'Events'),'Name')
ans =
'SerializeEvent'
'FigureUpdateEvent'
'ResizeEvent'
'WindowKeyReleaseEvent'
'WindowKeyPressEvent'
'WindowButtonUpEvent'
'WindowButtonDownEvent'
'WindowButtonMotionEvent'
'WindowPostChangeEvent'
'WindowPreChangeEvent'
I still would like to call your attention to the FEX as another good solution that may give you better possibilities for working with the graphical components offered by matlab.
Usage example:
>> k=handle.listener(gcf,'WindowButtonMotionEvent','disp(''MOVEMENT DETECTED!!'')');
>> MOVEMENT DETECTED!! % When you move the mouse on the figure
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> delete(k)
Try using get:
fig = gcf();
get(fig)
I don't know how to do this. I can provide some sample code to demonstrate what I think is being asked. This is a relatively new (therefore unused) Matlab feature:
hh = handle(gca);
lsnr = addlistener(hh,'XLim','PreGet',#(~,~)disp('<<<Getting XLIM values>>>'))
To see the listener in action
>> get(hh,'XLim')
<<<Getting XLIM values>>>
ans =
0 1
I think the question is how to get lsnr from gca if the value was not stored.
I can't find a way.