How to store fig in .mat file? - matlab

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);

Related

To load .m matrix

I want to read data from a .m MATLAB file which is saved in my directory. However, when I used load('filename.m'), I get is a structure of size 1*1 and the 3320*9 matrix is within that structure file. How can I read it directly as a 3320*9 matrix?
You can get the desired behavior, if you're allowed to modify your save function.
Z = rand(10)
save('test.dat','Z','-ascii')
The ascii format is key, because Matlab allows a load directly to a variable:
test = load('test.dat','Z')

pixelLabelDatastore from loaded image in workspace

I have multiple small *.mat files, each containing 4 input images (template{1:4} and a second channel template2{1:4}) and 4 output images (region_of_interests{1:4}), a binarized ('mask') image to train a deep neural network.
I basically followed an example on Mathworks and it suggests to use a function (in this example #matreader) to read in custom file formats.
However ...
It seems impossible to load multiple images from one *.mat file using any load function as it only allows one output, and imageDatastore doen't seem to allow loading data from workspace. How could this be achieved?
Similarly, it seems impossible to load a pixelLabelDatastore from a workspace variable. As a workaround I ended up saving the contents of my *.mat file to an image (using imwrite, saving to save_dir), and re-loading it from there (in this case, the function doesn't even allow to load *.mat files.). (How) can this be achieved without re-saving the file as image?
Here my failed attempt to do so:
%main script
image_dir = pwd; %location of *.mat files
save_dir = [pwd '/a/']; %location of saved output masks
imds = imageDatastore(image_dir,'FileExtensions','.mat','ReadFcn',#matreader); %load template (input) images
pxds = pixelLabelDatastore(save_dir,{'nothing','something'},[0 255]);%load region_of_interests (output) image
%etc, etc, go on to train network
%matreader function, save as separate file
function data=matreader(filename)
in=1; %give up the 3 other images stored in template{1:4}
load(filename); %loads template and template2, containing 4x input images each
data=cat(3,template{in},template2{in}); %concatinate 2 template input images in 3rd dimension
end
%generate example data for this question, will save into a file 'example.mat' in workspace
for ind=1:4
template{ind}=rand([200,400]);
template2{ind}=rand([200,400]);
region_of_interests{ind}=rand([200,400])>.5;
end
save('example','template','template2','output')
You should be able to achieve this using the standard load and save function. Have a look at this code:
image_dir = pwd;
save_dir = pwd;
imds = imageDatastore(image_dir,'FileExtensions',{'.jpg','.tif'});
pxds = pixelLabelDatastore(save_dir,{'nothing','something'},[0 255]);
save('images.mat','imds', 'pxds')
clear
load('images.mat') % gives you the variable "imds" and "pxds" directly -> might override previous variables
tmp = load('images.mat'); % saves all variables in a struct, access it via tmp.imds and tmp.pxds
If you only want to select the variables you want to load use:
load('images.mat','imds') % loads "imds" variable
load('images.mat','pxds') % loads "pxds" variable
load('images.mat','imds','pxds') % loads both variables
EDIT
Now I get the problem, but I fear this is not how it is going to work. The Idea behind the Datastore objects is, that it is used if the data is too big to fit in memory as a whole, but every little piece is small enough to fit in memory. You can use the Datastore object than to easily process and read multiple files on a disk.
This means for you: Simply save your images not as one big *mat file but as multiple small *.mat files that only contain one image.
EDIT 2
Is it strictly necessary to use an imageDatastore for this task? If not you can use something like the following:
image_dir = pwd;
matFiles = dir([image_dir '*.mat']);
for i=1:length(matFiles)
data = load(matFiles(i).name);
img = convertMatToImage(data); % write custom function which converts the mat input to your image
% or something like this:
% for j=1:4
% img(:,:,j) = cat(3,template{j},template2{j});
% end
% process image
end
another alternative would be to create a "image" in your 'matreader' which does not only have 2 bands but to simply put all bands (all templates) on top of each other providing a "datacube" and then in an second step after iterating over all small mat files and reading them splitting the single images out of the one bigger datacube.
would look something like this:
function data=matreader(filename)
load(filename);
for in=1:4
data=cat(3,template{in},template2{in});
end
end
and in your main file, you have to simply split the data into 4 pieces.
I have never tested it but maybe it is possible to return a cell instead of a matrix?
function data=matreader(filename)
load(filename);
data = cell(1,4)
for in=1:4
data{in}=cat(3,template{in},template2{in});
end
end
Not sure if this would work.
However, the right way to go forward from here really depends on how you plan to use the images from imds and if it is really necessary to use a imageDatastore.

MATLAB: making a histogram plot from csv files read and put into cells?

Unfortunately I am not too tech proficient and only have a basic MATLAB/programming background...
I have several csv data files in a folder, and would like to make a histogram plot of all of them simultaneously in order to compare them. I am not sure how to go about doing this. Some digging online gave a script:
d=dir('*.csv'); % return the list of csv files
for i=1:length(d)
m{i}=csvread(d(i).name); % put into cell array
end
The problem is I cannot now simply write histogram(m(i)) command, because m(i) is a cell type not a csv file type (I'm not sure I'm using this terminology correctly, but MATLAB definitely isn't accepting the former).
I am not quite sure how to proceed. In fact, I am not sure what exactly is the nature of the elements m(i) and what I can/cannot do with them. The histogram command wants a matrix input, so presumably I would need a 'vector of matrices' and a command which plots each of the vector elements (i.e. matrices) on a separate plot. I would have about 14 altogether, which is quite a lot and would take a long time to load, but I am not sure how to proceed more efficiently.
Generalizing the question:
I will later be writing a script to reduce the noise and smooth out the data in the csv file, and binarise it (the csv files are for noisy images with vague shapes, and I want to distinguish these shapes by setting a cut off for the pixel intensity/value in the csv matrix, such as to create a binary image showing these shapes). Ideally, I would like to apply this to all of the images in my folder at once so I can shift out which images are best for analysis. So my question is, how can I run a script with all of the csv files in my folder so that I can compare them all at once? I presume whatever technique I use for the histogram plots can apply to this too, but I am not sure.
It should probably be better to write a script which:
-makes a histogram plot and/or runs the binarising script for each csv file in the folder
-and puts all of the images into a new, designated folder, so I can sift through these.
I would greatly appreciate pointers on how to do this. As I mentioned, I am quite new to programming and am getting overwhelmed when looking at suggestions, seeing various different commands used to apparently achieve the same thing- reading several files at once.
The function csvread returns natively a matrix. I am not sure but it is possible that if some elements inside the csv file are not numbers, Matlab automatically makes a cell array out of the output. Since I don't know the structure of your csv-files I will recommend you trying out some similar functions(readtable, xlsread):
M = readtable(d(i).name) % Reads table like data, most recommended
M = xlsread(d(i).name) % Excel like structures, but works also on similar data
Try them out and let me know if it worked. If not please upload a file sample.
The function csvread(filename)
always return the matrix M that is numerical matrix and will never give the cell as return.
If you have textual data inside the .csv file, it will give you an error for not having the numerical data only. The only reason I can see for using the cell array when reading the files is if the dimensions of individual matrices read from each file are different, for example first .csv file contains data organised as 3xA, and second .csv file contains data organised as 2xB, so you can place them all into a single structure.
However, it is still possible to use histogram on cell array, by extracting the element as an array instead of extracting it as cell element.
If M is a cell matrix, there are two options for extracting the data:
M(i) and M{i}. M(i) will give you the cell element, and cannot be used for histogram, however M{i} returns element in its initial form which is numerical matrix.
TL;DR use histogram(M{i}) instead of histogram(M(i)).

Avoid saving of graphics in Matlab

Starting R2014b Matlab has changed the way how variables are saved using save command; Matlab has also changed the way graphic handles are saved, they are saved as structures now. If you have graphic handles in workspace Matlab takes it longer to save the mat file, size of mat file is large and when you load the file all the saved figures are popped-up, which is irritating to me. It also produces a warning:
Warning: Figure is saved in Oakley_19_PDEparameterEstimation.mat. Saving graphics handle variables can cause the creation
of very large files. To save graphics figures, use savefig.
I have a simple and straightforward question:
How can I avoid saving of all graphic handles?
Please do not suggest that I can clearvars figure handles before saving them.
Thanks
You can get information about the current workspace variables using whos and save only those variables whose class is not a graphics handle object (i.e. the class name string does not include 'matlab.graphics' or 'matlab.ui'):
varData = whos;
saveIndex = cellfun(#isempty, regexp({varData.class}, 'matlab.(graphics|ui)'));
saveVars = {varData(saveIndex).name};
save('no_handles.mat', saveVars{:});
You can select which variables you save.
Example:
save('data.mat', 'var_name1', 'var_name2', 'var_name3');
where var_name1 etc... are the names of the variables you want to save.

Inputting/Accessing data for GUI MATLAB

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?