Setting Column and Row Names from Cell in uitable - MATLAB - matlab

I am using GUIDE to build my first GUI interface in MATLAB.
I have several matrices I want to display using the uitable. For now let's focus on one matrix, say myMatrix [10x5]
Now I have two cells of strings, columnNames (1x5), and another, rowNames (10x1). I would like to set these cells to the row and column names of the table, but I cant yet figure out how to do this.
The MATLAB help page says you can use a cell of strings to do this, however in the property inspector, and under ColumnName, the only non-numeric option is to enter the names manually.
Any help would be appreciated (or suggestions to go about this in a different way).

In order to have custom Row/Column Names you have to pass a cell of strings (using {<names>}) into the ColumnName and RowName properties of the uitable. Here is an example directly from MatLab's uitable documentation:
f = figure('Position',[200 200 400 150]);
dat = rand(3);
cnames = {'X-Data','Y-Data','Z-Data'}; % These are your column names
rnames = {'First','Second','Third'}; % These are your row names
t = uitable('Parent',f,'Data',dat,'ColumnName',cnames,...
'RowName',rnames,'Position',[20 20 360 100]);
When parsing you're file, be sure to create the lists as a cell of strings.

Related

Converting cells within cells to single cells

I have a 1X100 cell which contains exclusivly 1X24 cells. I need to extract these 100 cells and join them together to form a 100X24 cell, how can this be done?
I have been playing around with the 'cellfun' function and also using for loops to try an perform the operations required but without success. I understand I could just join these cells one by one but would prefer a more efficient approach. Any help would be appreciated.
The cell is generated from raw data using the following:
for i = 1:100
band{i} = prctile(e-data,i);
end
where e_data is a 62X24 double
The second input to prctile can be an array of percentages so your code can be replaced with
band = prctile(e - data, 1:100).';
This will create a 100 x 24 numeric array which is going to be more performant than a cell array.
In general though, if you need to concatenate the contents of multiple cells together, you can use {:} indexing to yield a comma separated list which can then be passed to cat
result = cat(1, band{:});
If I understood your purpose correctly, you need to use iscell() and retrieve what you want subsequently:
R=cellfun(#iscell, YourCell);
Demanded_Cell=YourCell(R);

Filter on words in Matlab tables (as in Excel)

In Excel you can use the "filter" function to find certain words in your columns. I want to do this in Matlab over the entire table.
Using the Matlab example-table "patients.dat" as example; my first idea was to use:
patients.Gender=={'Female'}
which does not work.
strcmp(patients.Gender,{'Female'})
workd only in one column ("Gender").
My problem: I have a table with different words say 'A','B','bananas','apples',.... spread out in an arbitrary manner in the columns of the table. I only want the rows that contain, say, 'A' and 'B'.
It is strange I did not find this in matlab "help" because it seems basic. I looked in stackedO but did not find an answer there either.
A table in Matlab can be seen as an extended cell array. For example it additionally allows to name columns.
However in your case you want to search in the whole cell array and do not care for any extra functionality of a table. Therefore convert it with table2cell.
Then you want to search for certain words. You could use a regexp but in the examples you mention strcmp also is sufficient. Both work right away on cell arrays.
Finally you only need to find the rows of the logical search matrix.
Here the example that gets you the rows of all patients that are 'Male' and in 'Excellent' conditions from the Matlab example data set:
patients = readtable('patients.dat');
patients_as_cellarray = table2cell(patients);
rows_male = any(strcmp(patients_as_cellarray, 'Male'), 2); % is 'Male' on any column for a specific row
rows_excellent = any(strcmp(patients_as_cellarray, 'Excellent'), 2); % is 'Excellent' on any column for a specific row
rows = rows_male & rows_excellent; % logical combination
patients(rows, :)
which indeed prints out only male patients in excellent condition.
Here is a simpler, more elegant syntax for you:
matches = ((patients.Gender =='Female') & (patients.Age > 26));
subtable_of_matches = patients(matches,:);
% alternatively, you can select only the columns you want to appear,
% and their order, in the new subtable.
subtable_of_matches = patients(matches,{'Name','Age','Special_Data'});
Please note that in this example, you need to make sure that patients.Gender is a categorical type. You can use categorical(variable) to convert the variable to a categorical, and reassign it to the table variable like so:
patients.Gender = categorical(patiens.Gender);
Here is a reference for you: https://www.mathworks.com/matlabcentral/answers/339274-how-to-filter-data-from-table-using-multiple-strings

Indexing data in matlab

I have imported a lot of data from an excel spreadsheet so that I have a 1x27 matrix.
I have imported data from excel using this
filename = 'for_matlab.xlsx';
sheet = 27;
xlRange = 'A1:G6';
all_data = {};
for i=1:sheet,
all_data{i} = xlsread(filename, i, xlRange);
end
However each element of this all_data matrix (which is 1x27) contains my data but I'm having trouble accessing individual elements.
i.e.
all_data{1}
Will give me the entire matrix but I need to perform multiplications on individual elements of this data
also
all_data(1)
just gives '5x6 double', i.e. the matrix dimensions.
Does anybody know how I can divide all elements of each row by the third element in each row and do this for all of my 'sub-matrices' (for want of a better word)
Assuming that all_data is a cell array and that each cell contains a matrix (with at least three columns):
result = cellfun(#(x) bsxfun(#rdivide, x, x(:,3)), all_data, 'uniformoutput', 0);
You are mixing terminology in matlab. what you have is 1x27 CELLS each of them containing a matrix.
If you access all_data{1} it will give you the whole matrix stored in the first cell.
If you want to access the elemets of that matrix then you need to do: all_data{1}(2,4). This example access the 2,4 element of the matrix in the first cell.
Definitely Luis Mendo has solved you problem, but be aware of the differences of Cells and matrixes in Matlab!
Okay I have found the answer now.
Basically you have to use both types of brackets because the data types are different
i.e. all_data{1}(1:4) or something like that anyway.
Cheers

Drag pattern in uitable matlab

I want to know if it is possible to drag pattern values in matlab uitable. In a spreadsheet, to enter values from 1 to 50, you need to enter 1,2,3 and select the cells and drag. Please can this be done in matlab uitable? Regards.
It can be done. But not as far as comfortable as with excel.
Play around a bit with the following code, you can try to improve it or change it to your needs. I think it is a good starting point for you.
function fancyTable
defaultData = randi(99,25,2);
h = figure('Position',[300 100 402 455],'numbertitle','off','MenuBar','none');
uitable(h,'Units','normalized','Position',[0 0 1 1],...
'Data', defaultData,...
'Tag','myTable',...
'ColumnName', [],'RowName',[],...
'ColumnWidth', {200 200},...
'CellSelectionCallback',#cellSelect);
end
function cellSelect(src,evt)
try
index = evt.Indices;
data = get(src,'Data');
L = size(index,1);
rows = index(:,1);
column = index(1,2);
start = data(rows(1),column);
newdata = start:(start+L-1);
data(rows,column) = newdata';
set(src,'Data',data);
end
end
It creates a table with two columns:
You can select data and your desired drag pattern is applied immediately according to the first value.
The code is just to insert an increasing series of values at the first point of selection based on the according value. The hardest part will be to detect the pattern! I just evaluated the first data value start = data(rows(1),column); you could also require a minimal selection of 3: start = data(rows(1:3),column);. You probably need to work with a lot of try/catch structures to skip all unexplained cases. Or you use switch/case structures from the beginning to evaluate the length of the selection and evaluate the pattern.
All in all it is a heavy task, I'm not sure if it's worth it. But it can be done.
In uitable you insert data (usually a matrix) to be displayed in a table. So unlike Excel the uitable function is merely a form of displaying your data instead of a tool to manipulate it. See for more information here. However, if you want to set up a row for instance running from 1 until 10 you could use the following steps:
So say one would like to display a matrix of size 10x10, e.g.
A=magic(10);
You can now set up a table t to display this matrix by
t=uitable('Data',A);
In your case if you want a row to be, e.g., 1 till 10, just change the matrix A containing your data to hold this row using
A(1,1:10)=1:10;
And re-execute the former command to bring up your table t.

Matlab boxplot for multiple fields

I have this matlab file which has a field called "data". In "data" I have lots of fields for different bonds (x5Q12... etc).
I am trying to produce ONE box plot that contains ONE column from each of the fields (i.e. a box diagram with 36 boxes in it). I tried this code (e.g. to plot a box for column 2 in all of the bonds) but it does't work for me:
boxplot(gilts_withoutdates.data.:(:,2));figure(gcf);
I know my understanding of calling different levels in a structure is a problem here. Any suggestions, please? Many thanks.
You can use STRUCTFUN to extract the data from a particular column of all fields of a structure.
col2plot = 2; %# this is the column you want to plot
%# return, for each field in the structure, the specified
%# column in a cell array
data2plot = structfun(#(x){x(:,col2plot)},gilts_withoutdates.data);
%# convert the cell array into a vector plus group indices
groupIdx = arrayfun(#(x)x*ones(size(data2plot{x})),1:length(data2plot),'uni',0);
groupIdx = cat(1,groupIdx{:});
data2plot = cat(1,data2plot{:});
%# create a compact boxplot
boxplot(data2plot,groupIdx,'plotStyle','compact','labels',labels)
If you're interested in the distribution of the data, I can recommend my function distributionPlot.
B=gilts_withoutdates.data;
b=fieldnames(B);
for a=1:numel(b)
boxplot(B.(b{a})); fig;
end
To plot a boxplot for each of the 5 columns of data for each field you could do this:
pos=1;
for i = 1:numel(b)
for ii=1:5
subplot(numel(b),5,pos);boxplot(B.(b{i})(:,ii));pos=pos+1;
end
end