I wish to plot a simple graph of my data with sliders to change the coefficient of the y-axis data. I have created my GUI interface from quick start, with plot and sliders. I now wish to write the code (I believe in the simpleguide_OpeningFcn section) to import my data sets. My data sets are 5 different 300x1 vectors which I currently import into a a normal MATLAB file using an import function named importfile2.m.
Any help on how to get this data into the GUI for my simple plot(x,y) would be much appreciated. Cheers
An alternative would be to use setappdata and getappdata to fetch the data wherever you want from your GUI.
For example, at t he end of your importfile2.m you could use setappdata to store the data in some variable. The first argument tells MATLAB in what workspace to save it. You could, for example, use the GUI interface in itself or use the base workspace, accessible from everywhere. That's the most general way:
setappdata(0,'FancyName',YourData); %// The 0 is for the base workspace,i.e. the 'root'.
%//YourData is the actual data and 'FancyName' is whatever name you give them. It does not have to be the same name as the variable in your function. The important thing is to use the same name in getappdata as below.
If you wanted to associate the data only with the GUI figure, you would use something like this:
setappdata(handles.YourFigure_Tag,'FancyName',YourData);
To get the data in the GUI, use getappdata in its opening function (or in any callback you want) and you're good to go:
Data_inGUI = getappdata(0,'FancyName'):
A more robust way would be to store directly the data in the handles structure of the GUI, so that it's accessible from every callback:
handles.Data_inGUI = getappdata(0,'FancyName'):
guidata(hObject,handles); %// Update handles structure; important!
And that should do it. Hope that helps!
EDIT I think another solution would be to save a .mat file at the end of the import function and load it in the OpeningFcn of the GUI. Than might be simpler/faster.
EDIT 2 Following your comment below, here is what I would do:
1) In the OpeningFcn of the GUI, import the data.
[Date,OutAirTemp,SupAirtemp] = importfile3('AHU7Oct.csv')
Then you can store everything in the handles structure:
handles.Data = Date;
handles.OutAirTemp = OutAirTemp;
handles.SupAirtemp = SupAirtemp;
guidata(hObject,handles); %// Update handles structure.
Then elsewhere in the GUI (i.e. other callbacks) you can fetch the data as regular, i.e. using for example:
NewDate = handles.Date - 4 %// or whatever.
Is it a bit clearer?
Related
I am a nested function inside a function and I am calling variables from base workspace. Note that guiel is in base workspace.
function callback(~,~)
vars.dropheight = str2num(get(edit(2),'String'));
vars.armradius = str2num(get(edit(1),'String'));
kiddies = get(guiel.hAX(3),'Children');
delete(kiddies);
clear kiddies;
set(guiel.tfPanel,'Visible','off','Position',cnst.tfPanelpos);
set(guiel.hAX(1),'Position',cnst.axpos1);
if ishandle(guiel.hAX(2))
set(guiel.hAX(2),'Position',cnst.axpos2);
end
eval(get(guiel.hPB(4),'Callback'));
end
The best way, in my opinion, is to store guiel into guidata.
guidata(hFig, guiel); % hFig can be gcf for top figure
and access it in callback by
guiel = guidata(hFig);
One of the alternatives is to pass the variable as input to callback by defining it as
{#callback, guiel}
The callback function definition will be
function callback(~, ~, guiel)
If you really hate these methods, a simple way is to define it as global in base and your callback. But this is something one tries to avoid for both performance and code maintainability consideration.
Best practices for GUI design are that you encapsulate your GUI and its operations in such a way that it never has to depend on the base workspace to function correctly. The reason? The user and other programs can modify anything in the base workspace, and can thus easily break your GUI.
I give an example of a basic GUI setup using nested functions in this post. Here's a general skeleton for designing a GUI:
function create_GUI()
% Initialize data:
data1 = ...;
data2 = ...;
% Create GUI:
hFigure = figure;
hObject1 = uicontrol(..., 'Callback', #callback1);
hObject2 = uicontrol(..., 'Callback', #callback2);
....
function callback1(~, ~)
% Access any data or handles from above
...
end
function callback1(~, ~)
% Access any data or handles from above
...
end
end
The idea is that the main function creates all the GUI components, initializing all the needed data and object handles. The callbacks nested within the main function will have access to the data and handles as needed. I suggest designing your GUI like this, or using one of the other options listed here. This should alleviate some of your data access issues and make your GUI more robust.
I would like to save the image I generate the HeatMap() function from the bioinformatics library.
I cannot figure out to have the image without manually exporting the data.
I'd prefer to use HeatMap over Imagesc because it automatically scales the data to the mean.
I do not have the Bioinformatics Library for matlab, However you should be able to get the current figure with the function gcf. It is not the most stable way, but in most cases this will work excellent. Then you can save the figure as a figure or image with saveas.
HeatMap(...);
hFig = gcf;
saveas(hFig,'myName','png'); % You can use other image types as well and also `'fig'`
There is a second way as well. The HeatMap class also contains a plot method. This method may return the figure handle to the HeatMap plot then save the image with saveas.:
hHM = HeatMap(...);
hFig = plot(hHM);
saveas(hFig,'myName','png');
I share a part of a Matlab code that I used when I analyzed some data from TCGA
#I was considering two gene expression level taken from cancer disead tissue and
# healthy tissues comparing them with this Heatmap
labela=Gene;
labelb=Gene2;
data1=[dataN(indg,:) dataC(indg,:); dataN(indg2,:) dataC(indg2,:);];
H=HeatMap(data1,'RowLabels',
{labela,labelb},'Standardize','row','Symmetric','true','DisplayRange',2);
addTitle(H,strcat('HeatMap',project));
addXLabel(H,'patients');
addYLabel(H,'geni');
#I have allocated the plot in a variable
fig=plot(H);
# Then I saved the plot
saveas(fig,strcat('D:\Bioinformatica\Tesina...
Prova2\Risultati_lihc\',dirname,'\HM.fig'));
But if you have to run one single object I advise against waisting your time in writing code (even if it is always a good thing to explore and strengthen your knowledge), I used because each time I was running a pipeline. Otherwise you can go on
1)File ----> Export Setup
2) Export
3)Save in the format you do want!
I have two gui's one is main gui and other is sub gui. In opening function of main gui i used open('subgui.fig'); to open sub gui. Main consists of 5 edit box and one pushbutton. After pressing pushbutton the data in those 5 edit boxes should be passed to sub gui and main gui should close. Please any one help me to do this.
Let us take a simple case of one editbox and one pusbutton in main GUI and one editbox in sub GUI that will get value from the editbox in main GUI. One can easily extend this to as many editboxes as needed. The basic medium of data storage and retrieval would be a global structure data1.
For the sake of understanding the codes, let us take the following assumptions -
Main GUI is named as main_gui.m and thus has an associated
main_gui.fig from GUIDE. Main GUI's figure has the tag main_gui_figure.
Sub GUI is named as sub_gui.m and thus has an associated sub_gui.fig
from GUIDE.
Edits to be made in main_gui.m
Inside editbox's callback, add this -
global data1;
%%// Field in data1 to store the string in editbox from main GUI
data1.main_gui.edit1val = get(hObject,'String');
Inside the pushbutton's callback, add this right before it's return -
global data1;
sub_gui;
delete(handles.main_gui_figure);
Edits to be made in sub_gui.m
Inside sub_gui_OpeningFcn, add this -
global data1;
set(handles.edit1,'String',data1.main_gui.edit1val);%%// Tag of editbox in sub-gui is edit1
Hope this works out for you! Let us know!
There are probably more than one ways to achieve this. But one of the approaches is to define a function that takes two input arguments: 1) handles to the destination figure and 2) whatever data from the source figure.
The following psuedo code doesn't necessarily run in MATLAB, but it gives the basic idea:
function takeAction(uihdls, data)
set(0, 'CurrentFigure', uihdls.fig); % uihdls.fig is the handle of the destination figure.
set(gcf, 'CurrentAxes', uihdls.aexs1); % axes1 is inside fig
plot(data.x, data.y); % Do some plotting
set(uihdls.editBox, 'String', data.string); % Modify some property of a control inside fig.
key_Callback(uihdls.fig, data.keyData); % Call a callback function of the destination figure
return
This function can be called by the source figure whenever it is ready to do so.
A bit more work - but I think it's worth it.
I usually use the MVC pattern for that. Practically it means to write a controller object that will pass the messages through to the required fields.
I have a GUI(made using GUIDE) in which there is an axes on which I can draw. When I saved the gui, i have a .fig file and a .m file (whose names are start_gui.m and start_gui.fig). Now, I am trying to plot on these axes using an external M file, to which I have passed the GUI handles. This is as follows:
function cube_rotate(angle1,angle2,handles)
gcf=start_gui.fig; %this is the name of the gui.fig file in GUIDE
set(gcf,'CurrentAxes',handles.cube_axes)%this allows us to plot on the GUI
%plot something
end
handles.cube_axes is the name of the handle in the GUI created using guide. Inspite of passing the handles, it won't allow me to plot in the gui. It throws up an error saying:
??? Undefined variable "start_gui" or class "start_gui.fig".
start_gui.fig is the name of the GUI figure that was generated in GUIDE. How do i make it plot in the axes in start_gui.fig?
Thanks for all the help!
You've made a few errors. The first is referring to a file name without single quotes to denote a string. The second is trying to open an existing figure by assigning it as a variable named gcf. This will just give you a variable gcf which contains the string 'start_gui.fig'.
Instead, open the figure with this command:
fH = hgload('start_gui.fig');
% Then find/assign the axes handle (assuming you only have one axes in the figure):
aH = findobj(fH,'Type','axes');
% And finally plot to the axes:
plot(aH,0:.1:2*pi,sin(0:.1:2*pi));
On a secondary note, is there a reason you're not using the M-file generated by MATLAB to carry out this functionality? By using the auto-generated M-file, you'll be able to access the handles structure rather than using findobj.
The error you're getting is because of your second line: gcf=start_gui.fig;
It's looking for a variable named start_gui, which you don't have. (start_gui.fig is a filename, not a variable.)
To solve your plotting problem, take a look at this Mathworks support article.
Is it possible to store the matlab figure inside a mat file, where the variable are stored.
I got into a scenario where i generated some plot from the variable stored in the mat file. Currently im storing the figure as a separate file, this means, i have a 1 file for variables and another file for figure. But i would like to bundle them together in a single file.
How about selecting both files in the windows explorer and zip them? ;-)
Seriously, while I do not know of a way to do exactly what you want (what is it, exactly, anyway? Do you expect the figure to pop up once you've typed load variables.mat and pressed enter?) I see this way around it:
You could store the command(s) needed to generate the figure in an anonymous function or as a string and save it along with all other variables. Then, after loading the .mat file, you call that function or eval on the string and the figure will be regenerated.
x=sort(rand(1,100)); y=sort(randn(1,100)); %# sample data
makefig = #() plot(x,y,'g.'); %# anonymous figure-generating function
save myDataAndFigure
clear all
load myDataAndFigure
makefig()
...or, with a string (e.g. when including formatting and axis-labelling commands)
x=sort(rand(1,100)); y=sort(randn(1,100)); %# sample data
figcmd = 'plot(x,y,''g.''); xlabel(''sort(U(0,1)''); ylabel(''sort(N(1,0)'');'
save myDataAndFigure
clear all
load myDataAndFigure
eval(figcmd)
The latter should save memory when the involved data are large, since the anonymous function object contains all the data it needs, i.e. its own "copy" of x and y in the example.
There's an article here on fig file format and how it's actually a mat file in a disguise.
So you can take the fig and store its data in a structs and save them as a mat file, then load the mat file and make fig out of the structs you saved.
How about storing data and functions in instances of a class and unsing the functions later to plot the data?
Actually this is surprisingly easy to do.
Suppose you have just created the figure in question. Converting the figure handle into a struct yields the corresponding hierarchical elements (including the data, labels, everything) required to display the figure.
If desired, this struct may then be saved to a mat file just as though it was data. (It is, in fact.) To view the contents of the struct as a figure again simply reconvert it to a handle with struct2handle.
% The line below converts the current figure handle into a struct.
this_fig = handle2struct(gcf)
% The line below converts the struct "this_fig" back to a figure handle and displays it.
h = struct2handle(this_fig,0);