How to refer the figure name in matlab - matlab

I would like to define a figure and then for that specific figure do some things. Foe example: I would like to vreat a digure say:
h1 = figure('units','normalized','outerposition',[0 0 1 1]);
and then I want for h1 to do for example:
subplot(1,3,1)
plot(N_vec,1./Err(N_vec),sprintf('*%c',colconds(loop)),'LineWidth',5)
hold on
plot(N_vec,1./ErrPV(N_vec),sprintf('*%c',colconds(loop+2)),'LineWidth',5)
hold on
xlabel('Population size','fontsize',20)
ylabel('Error^-2 ','fontsize',20)
legend('OLE','PV','OLE shuffled','PV shuffled','Location','northwest')
The thing is that from loop reasons, h1 is defined far from the above lines. and is not the current figure handel. So I want the above lines to refer specifically for h1. somethong like:
subplot('h1',1,3,1)
plot('h1',N_vec,1./Err(N_vec),sprintf('*%c',colconds(loop)),'LineWidth',5)
hold on
plot('h1',N_vec,1./ErrPV(N_vec),sprintf('*%c',colconds(loop+2)),'LineWidth',5)
hold on
xlabel('h1','Population size','fontsize',20)
ylabel('h1','Error^-2 ','fontsize',20)
legend('h1','OLE','PV','OLE shuffled','PV shuffled','Location','northwest')
But matlab gives error whenever i try to add the name h1 in the specific commands for the figure...
how do I refer the figure handel when I actully want to use it?
Thanks!!

You could assign a 'Name' or 'Tag' to the h1 figure and then use that as a reference to get it before plotting.
% Create a figure with tag 'MyFig'
figure('Tag', 'MyFig');
% ... later in the code ...
% Get the figure with the Tag "MyFig"
h1 = findobj('Type', 'Figure' ,'Tag', 'MyFig')
Tag is for this purpose better than Name as the later is shown after the figure number. The Type-Figure argument could be skipped, but narrows down the objects to search.
Now you can use h1 as a regular handle.
subplot(h1,1,3,1)
plot(h1, ...)
You could also set h1 figure to the current figure
set(groot, 'CurrentFigure', h1);
% ... or for older versions
set(0, 'CurrentFigure', h1)
Then you could omit the handle in the plot commands
subplot(1,3,1)
plot(...)

Related

Delete object handle and keep variable in MATLAB

Using the delete function, I can delete the object handle but it also removes the object properties from the variable.
Is there a way to delete the object handle without touching to the variable properties?
For example, I have two plots like below and I delete the first one.
figure;
h1 = plot( 1:10, '*' );
hold on
h2 = plot( 2:5, '.' );
delete( h1 );
h1.XData % returns an error, handle has been removed
The h1 object handle has been removed from the figure as expected but all the h1 properties (XData, YData) also have been removed. Is there a way to keep the h1 properties? Do I necessarily need to back up the properties before using delete?
Instead of deleting h1, simply hide it:
h1.Visible = 'off';
And you can see the data is still there:
>> h1.XData
ans =
1 2 3 4 5 6 7 8 9 10

plot automatically titled with plot object in matlab

I would like to know if some of you know of a way to automatically title plots with the name of the object plotted
so that for intance when I plot supermatrix(5:10,:,2:3)
the title (or the legend ..) on the plot says "supermatrix(5:10,:,2:3)"
thanks
Is this for debugging purposes? If not then I suggest you tell us your overall motivation because someone might be able to suggest a more robust method, but this might get you started:
vname = #(x)inputname(1); %//from here: https://www.mathworks.com/matlabcentral/newsreader/view_thread/251347
plot(supermatrix(5:10,:,2:3))
title(vname(supermatrix))
Although to be honest I cannot imagine why this would ever be useful
I think this does what you want and remains pretty flexible:
function h = plotwithtitle( plotstring, varargin )
argstoplot = evalin('caller', ['{', plotstring, '}']);
h = plot( argstoplot{:}, varargin{:} );
title(plotstring);
end
The following examples all work for me:
supermatrix=rand(10,10);
x=1:10;
y=rand(1,10);
plotwithtitle('supermatrix');
plotwithtitle('supermatrix(5:10,:)');
plotwithtitle('x, y');
plotwithtitle('x, y', '--r');
plotwithtitle('1:10', 'r');
plotwithtitle('rand(1,10)');
I've modified the function dfig originally created by F.Moisy for creating docked figures in order to have the command used for plotting show up in the figure name.
The idea is to read the last command in the command history and use that to generate the figure title.
function hh = dfig(varargin)
%DFIG Create docked figure window
% DFIG, by itself, creates a new docked figure window, and returns its
% handle.
%
% DFIG(H) makes H the current figure and docks it. If Figure H does not
% exist, and H is an integer, a new figure is created with handle H.
%
% DFIG(H, name, value,...) reads additional name-value pairs. See
% doc(figure) for available otions.
%
% DFIG will parse the command line input and use the text following dfig
% as figure name. E.g. calling dfig,plot(x(1:3),y(2:2:end)) results in
% the name "plot(x(1:3),y(2:2:end))"
% F. Moisy, moisy_at_fast.u-psud.fr
% Revision: 1.00, Date: 2007/09/11
% Modified (a lot) by Jonas
if nargin==0
h=figure; % create a new figure
else
% call figure with varargin
figure(varargin{:})
h = gcf;
end
if ~any(strcmp('name',varargin(1:2:end)))
% if no name has been supplied: try to use function call
javaHistory=com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
if ~isempty(javaHistory)
lastCommand = javaHistory(end).toCharArray';
funCall = regexp(lastCommand,'dfig\s*[,;]\s*(.*)$','tokens','once');
else
funCall = [];
end
if ~isempty(funCall)
if isnumeric(h)
set(h,'Name',[num2str(h),': ',funCall{1}],'NumberTitle','off')
else % HG2
h.Name = sprintf('%i: %s',h.Number,funCall{1});
h.NumberTitle = 'off';
end
end
end
set(h,'WindowStyle','docked'); % dock the figure
if nargout~=0 % returns the handle if requested
hh=h;
end

How in Matlab do changes on figure 1 with slider on figure 2?

I have some sliders on figure 1, and I have some images on figure 2. I want to do the callbacks for the sliders in a way that, when I change the sliders in figure 1 , the threshold changes and images update automatically in figure 2.
I'm using addlistener to send values for callback function. The problem is when you move slider the active figure is figure 1, and you want to do changes on figure 2.
adding some code for clarification:
M.rgbImage = imread('euhedral-mag-on-po-edge-pseudo-sub-ophitic-rl-fov-4-8mm.jpg');
[rows, columns, numberOfColorBands] = size(M.rgbImage);
F.f = figure; % This is the figure which has the axes to be controlled.
% Now create the other GUI
S.fh = figure('units','pixels',...
'position',[400 400 500 100],...
'menubar','none',...
'name','Image control',...
'numbertitle','off',...
'resize','off');
S.sl = uicontrol('style','slide',...
'unit','pix',...
'position',[60 10 270 20],...
'min',0,'max',255,'val',100,...
'callback',{#sl_call2,S},'deletefcn',{#delete,F.f});
....
lis = addlistener(S.sl,'Value','PostSet',#(e,h) sl_call3(S,F,M));
function sl_call3(S,F,M)
v = get(S.sl,'value');
figure(F.f), subplot(4, 4, 13);
M.redMask = (M.redPlane > v);
imshow(M.redObjectsMask, []);
set(S.ed(2),'string',v);
Create reference to both your figures:
f1=figure(1);
f2=figure(2);
And then when doing the callback pass f2 as a parameter.
In the callback, you'll have get the handle to the second figure.
There's various ways to do that.
You can specify the handle to the second figure at the time of callback-definition:
figure2 = ...;
addlistener(hSlider, ..., #(a,b) changeStuffOn(figure2));
Or during the callback:
function callbackFunction(hObject, evt)
% get the handle to the second figure, e.g. by a tag, or its name
fig2 = findobj(0, 'type', 'figure', 'tag', 'figure2'); %
% do whatever you want with fig2
end
The latter might be somewhat worse in performance, but e.g. has the benefit of working reliably even if figure2 was deleted and recreated and some point.
To avoid the change of focus you'll have to get rid of this line your callback:
figure(F.f)
This explicitly moves the focus to the second figure.
You'll have to use e.g. the imshow(axes_handle, ...) syntax, in order to show the image not in the "current axes".

Removing Particular Objects From a Legend

I need your guys help in solving a small problem Im facing. When I want to depict f1 and f2 using bar function, I need to exclude f2 annotation objects in the legend tab of the figure, but the set syntax written below seems to give the error mentioned.
The code is as below:
f1= bar([SN, SN, SN], [Class_Work, Final_Exam, Shift_Grade'-Grade], K, 'stacked');
f2= bar([SN(idx), SN(idx), SN(idx)], [Class_Work(idx), Final_Exam(idx), SG(idx)-Grade(idx)], K*dy/dx, 'stacked', 'LineWidth', 2.5);
set(f1,{'DisplayName'},{'Mid-Term','Final-Exam','Shift'}')
legend('location','NorthEast','Orientation','horizontal');
% in order to Exclude f2 indices from legend: (BUT SEEMS NOT WORKING based on error!)
set(get(get(f2,'Annotation'),'LegendInformation'),...
'IconDisplayStyle','off');
After running it gives this error in command-window including the correct figure, but with all annotation objects:
??? Error using ==> get
Conversion to double from cell is not possible.
Error in ==> set(get(get(f2,'Annotation'),'LegendInformation'),...
The Figure, which I need is that: data4, data5, and data6 graphic objects (related to f2) in the legend tab NOT to appear, when drawing f2.
I appreciate your helps in advance.
There is a special syntax to call legend which should help in your case. From Matlab documentation:
legend(h, 'string1', 'string2', ...);
displays a legend on the plot containing the objects identified by the handles in the vector h and uses the specified strings to label the corresponding graphics object (line, barseries, etc.).
So, in your case you just should do:
legend(f1, 'Mid-Term', 'Final-Exam', 'Shift');
and then modify other properties of a legend (location, orientation, etc.) accordingly.
UPDATE:
Alternatively, to make your initial code work, you should do:
annots = get(h,'Annotation');
for i=1:length(annots)
set(get(annots{i},'LegendInformation'),'IconDisplayStyle','off');
end
annots = get(h,'Annotation') returns cell array and then you just operate on each cell (i.e. annots{i}) of this array.

How to change the line properties of a plot in switch environment within a for-loop in Matlab

I have data from simulations in one single .dat file. Depending on certain criteria ('bu') that is contained in one column of the file (#13 here), I want to plot the data with different markers, while also defining the markersize and markerface properties.
What I have is a switch environment for the different cases - defining which markers and properties I want, and all this in a for-loop, to go through all simulation data.
I've tried the following:
for i=1:s1(1)
bu = data1(i,13);
switch bu
case 1
set(h,'kd','MarkerSize',14,'MarkerFaceColor','k');
case 2
set(h,'kd','MarkerSize',14);
case 3
set(h,'k>','MarkerSize',14,'MarkerFaceColor','k');
case 4
set(h,'ks','MarkerSize',14,'MarkerFaceColor','k');
case 5
set(h,'ks','MarkerSize',14);
case 6
set(h,'ko','markersize',14);
case 7
set(findobj(gca,'k^','MarkerSize',14,'MarkerFaceColor','k'));
end
figure(1);
h=plot(Re1(i),A1(i)); hold on
end
First I tried to use a handle 'h', but it said it was undefined, I guess since the h=plot comes later. Then I tried findobj in the last case (which is the case for the first simulation, so this gives the error in the first round), didn't work either ("Incomplete property-value pair" - not sure what it means here).
I also tried putting all these properties in a string like
str=['kd','MarkerSize',14,'MarkerFaceColor','k']
then plot with
h=plot(Re1(i),A1(i),str); hold on
but it doesn't work with/without brackets either.
Now I don't have any further ideas, thankful for any suggestions!
I think the easiest change for you is to put the plot options in a cell array in the switch block. For example:
options = {'kd', 'MarkerSize', 14, 'MarkerFaceColor', 'k'};
Later, when you plot:
plot(x, y, options{:})
Another way I've done it is to set variables and use them in the plot command:
style = 'kd';
markerSize = 14;
markerFaceColor = 'k';
plot(x, y, style, 'MarkerSize', markerSize, 'MarkerFaceColor', markerFaceColor);
There are few different ways to do that, one of them - create all plot objects before hand and then fill them with both data and formatting:
figureHandle = figure;
for i=1:s1(1)
plotHandle(i) = plot(0,0); %just creating valid handle for future here
end;
code above before your for loop with bu switch, and then in your switch
set(ph(i),'kd','MarkerSize',14,'MarkerFaceColor','k', 'Xdata', Re(1), 'Ydata', A1(i));
Approach with str would work too, except you would need two cell arrays - option nad value like that:
firstoption = 'kd';
option = {'MarkerSize','MarkerFaceColor'};
value = {14,'k'};
h=plot(Re1(i),A1(i),firstoption);
for i=1:length(option)
set(h,option{i},value{i});
end;