matlab: variable horizontal alignment of text - matlab

Text objects in MATLAB contain a horizontal alignment property, which can be assigned a value of left, center, or right. Attempts to assign this property by a vector of alignments of equal length to the vectors of strings and coordinates fails to give the intended behavior.
For instance, a statement of the form :
text([1,1,1]/4,[1,2,3]/4,{'ABC';'BCD';'CDE'})
displays the contents of a length-3 cell array of char objects at the X- and Y-coordinates specified by length-3 double arrays. However, attempting to introduce a length-3 cell array of char objects for independent specification of the horizontal alignment of each text element is syntactically invalid;
e.g.,
text([1,1,1]/4,[1,2,3]/4,{'ABC';'BCD';'CDE'},'HorizontalAlignment',{'left';'center';'right'})
My question concerns whether it is possible to specify the HorizontalAlignment property of MATLAB text objects in a variable manner without resorting to constructs explicitly involving loops and conditionals.

You can't assign multiple property values upon creation, but once you have a vector of handles, you can use the many-to-many form of set() like so:
h = text([1,1,1]/4, [1,2,3]/4, {'ABC';'BCD';'CDE'});
set(h, {'HorizontalAlignment'}, {'left';'center';'right'});
The value array has one row per object, one column per property.

Related

Vectorizing multidimensional cell arrays in matlab with colon

If I have a cell array that is:
example=cell(dim1,dim2,dim3);
I would like to access values in the shape of:
example1{:}{:}{1} = rand(20,1);
How can I do so? It is important to know that I would like to conserve the shape of such cell array, namely, to modify the values but having the same type of multidimensional cell array.
I think now I understood your question.
mymatrix(:,:,:,1)=num2cell(rand(size(mymatrix(:,:,:,1))));
Easiest way to use () indexing which returns a cell, not a comma separated list of the individual elements. On the right side using rand(size(x)) with the same indexing expressions makes sure you get the right amount of elements generated. The left side is a cell, so you have to convert the right side to a cell as well.

Controlling the color of text in an array based on a predefined condition

I am trying to display a matrix M of size 50x8 with a plot using text([x,y],M). All the entries in matrix are at present of the same color. I would like more control on the display, and would like that all matrix entries satisfying a particular condition should be of different color.
One of the possible ways to do is to specify the position for each of the elements of the matrix M individually in text(x,y,M_ij). But I am only specifying the position for the first element, and other positions are being assigned automatically. How can I get those positions, or control them? This will allow me to control the colors as well.
The resulting text graphics object is only one object, so you can't adjust the color through handle graphics without affecting all of the rows. But if it's possible for you, you can specify the color directly in the strings. To do this, you'll probably need to represent your strings as a cell array instead, so they can have different colors.
M = {'\color{red}Line 1';'\color{blue}Line 2';'\color[rgb]{.6 .8 .2}Line 3'};
text(1, 1, M);
The reference for other inline string markup is found on this doc page, in the 'String' property: http://www.mathworks.com/help/matlab/ref/text_props.html

Using handles returned with findobj [duplicate]

I already have the functions required to drag and drop a single box in a figure in MATLAB. The code I wrote fills the figure with several boxes. With another loop I filled the figure with more boxes (which hold different information in string form).
These two sets of boxes are related by the numbers I placed in their UserData (corresponding numbers; for each box, there's another with the same UserData content). By finding boxes containing the same UserData (and thus relating them) I want to be able to relocate a member of the first set of boxes to the same position relative to the corresponding member of the second set of boxes, by means of right clicking on the box I just dragged (uicontextmenu).
function recallfcn(hObject,eventdata)
for ydx=1:2
diag_detail=get(gco,'UserData'); % This line should be in the drag fcn
diag_pos=get(gco,'Position'); % So should this one (for current objects)
xvar=diag_pos(1,1);
yvar=diag_pos(1,2);
detail=[diag_detail ydx];
set(findobj('UserData',detail),'Position',[xvar+(ydx-1.5) yvar+0.5 0.8 0.8]);
end
end
% ydx is only there to add another level of detail as I'm actually looking to move
% two boxes of the 'first kind', each of which have 2 numbers in user data, the first
% number being the same, and the second number distinguishing the first box from the
% second. The premise is the same.
I usually use findall instead of findobj, in case the handles of the objects are not visible from the outside. Other than that I don't see why your code wouldn't work.
Here's an example:
%# make a figure with two buttons, same userData
fh=figure,
uicontrol('userdata',[2 3],'parent',fh)
uicontrol('userData',[2 3],'units','normalized','position',[0.5 0.5,0.1 0.1],'parent',fh)
%# change color to red
set(findall(fh,'userData',[2 3]),'backgroundcolor','r')
%# move to the same position
set(findall(fh,'userData',[2 3]),'position',[0.3,0.3,0.1,0.1])
As Jonas alludes to, the 'HandleVisibility' property of an object will determine if the object shows up in its parent's list of children, and thus if it will be returned by functions like FINDOBJ. The standard fix is to use the function FINDALL instead.
However, the 'HandleVisibility' property also comes into play in determining whether or not an object can become the current object (i.e. returnable by the function GCO). If it is set to 'off', then that object can't become the current object. Additionally, if the 'HandleVisibility' property of the parent figure of an object is set to 'off' then none of its children (including said object) can become the current object.
If 'HandleVisibility' is set to 'on' or 'callback' for all your objects and figures, then I think everything should work fine.
you should inverse the ordre of x and y vector, and you can use just one loop, the changment in your code is :
x2=x(end:-1:1); % invers the ordre
y2=y(end:-1:1);
for i=1:length(x)
set(hLine,'xdata',x(i),'ydata',y(i)); % move the point using set
% to change the cooridinates.
set(hLine2,'xdata',x2(i),'ydata',y2(i));
M(i)=getframe(gcf);
end

Moving multiple boxes in figure?

I already have the functions required to drag and drop a single box in a figure in MATLAB. The code I wrote fills the figure with several boxes. With another loop I filled the figure with more boxes (which hold different information in string form).
These two sets of boxes are related by the numbers I placed in their UserData (corresponding numbers; for each box, there's another with the same UserData content). By finding boxes containing the same UserData (and thus relating them) I want to be able to relocate a member of the first set of boxes to the same position relative to the corresponding member of the second set of boxes, by means of right clicking on the box I just dragged (uicontextmenu).
function recallfcn(hObject,eventdata)
for ydx=1:2
diag_detail=get(gco,'UserData'); % This line should be in the drag fcn
diag_pos=get(gco,'Position'); % So should this one (for current objects)
xvar=diag_pos(1,1);
yvar=diag_pos(1,2);
detail=[diag_detail ydx];
set(findobj('UserData',detail),'Position',[xvar+(ydx-1.5) yvar+0.5 0.8 0.8]);
end
end
% ydx is only there to add another level of detail as I'm actually looking to move
% two boxes of the 'first kind', each of which have 2 numbers in user data, the first
% number being the same, and the second number distinguishing the first box from the
% second. The premise is the same.
I usually use findall instead of findobj, in case the handles of the objects are not visible from the outside. Other than that I don't see why your code wouldn't work.
Here's an example:
%# make a figure with two buttons, same userData
fh=figure,
uicontrol('userdata',[2 3],'parent',fh)
uicontrol('userData',[2 3],'units','normalized','position',[0.5 0.5,0.1 0.1],'parent',fh)
%# change color to red
set(findall(fh,'userData',[2 3]),'backgroundcolor','r')
%# move to the same position
set(findall(fh,'userData',[2 3]),'position',[0.3,0.3,0.1,0.1])
As Jonas alludes to, the 'HandleVisibility' property of an object will determine if the object shows up in its parent's list of children, and thus if it will be returned by functions like FINDOBJ. The standard fix is to use the function FINDALL instead.
However, the 'HandleVisibility' property also comes into play in determining whether or not an object can become the current object (i.e. returnable by the function GCO). If it is set to 'off', then that object can't become the current object. Additionally, if the 'HandleVisibility' property of the parent figure of an object is set to 'off' then none of its children (including said object) can become the current object.
If 'HandleVisibility' is set to 'on' or 'callback' for all your objects and figures, then I think everything should work fine.
you should inverse the ordre of x and y vector, and you can use just one loop, the changment in your code is :
x2=x(end:-1:1); % invers the ordre
y2=y(end:-1:1);
for i=1:length(x)
set(hLine,'xdata',x(i),'ydata',y(i)); % move the point using set
% to change the cooridinates.
set(hLine2,'xdata',x2(i),'ydata',y2(i));
M(i)=getframe(gcf);
end

annotation() and text() in Matlab

I wonder what is the difference between annotation() and text() functions in Matlab? In what cases are one of them preferred over the other?
TEXT positions text in relation to axes. In contrast, ANNOTATION position is figure-related. ANNOTATION can put on figure not only text, but lines, shapes, arrows, etc.
Consequently, TEXT takes axes handles as an argument (or gca for current axes), and ANNOTATION takes figure handles (or gcf for current figure).
Also, notice that they create different objects with different properties.
So for example, while TEXT objects can be rotated with the ROTATION property, ANNOTATION objects lack this property and cannot be rotated.