Choose and plot lines in a structure - matlab

Im having an issue specifying particular lines in a structure and plotting them.
I use tblread to take data from a file:
table_data = tdfread(table,',');
The table has both numerical and text data, looks a bit like this:
protocol,num_nodes,scale_physical,density,trace,reliability
etx,50,4.7045454546,4.94,heavy,72.7
nh,50,3.8275862069,4.96,heavy,64.27
rtt,50,4.5454545455,5.12,heavy,50.44
etx,50,3.8275862069,4.88,light,93.33
nh,50,4.7272727273,4.94,light,82.45
The resultant data type is a scalar structure called table_data. I can plot each column against each other using:
scatter(table_data.scale, table_data.reliability)
What I would like to achieve is to plot specific elements in the columns defined by a value in another column. Eg. plot the scale vs reliability where protocol = "nh".
Essentially I would like to achieve this end result like:
scatter(table_data.scale(table_data.protocol='nh'), table_data.reliability(table_data.protocol='nh'),'r')
hold on
scatter(table_data.scale(table_data.protocol='rtt'),table_data.reliability(table_data.protocol='rtt'),'b')
To differentiate the two types of points on the plot.
Is there any way of achieving this in a manor alluded to above.
Thanks.
EDIT:
solution is as follows:
scatter(table_data.scale(table_data.protocol=='n'),table_data.reliability(table_data.protocol=='n'), 'r')
hold on
scatter(table_data.scale(table_data.protocol=='e'),table_data.reliability(table_data.protocol=='e'), 'b')
In the structure The text is held as array or characters rather than a cell. table_data.protocol then points only references the first character in the array.

I think you want to replace the single equals in:
scatter(table_data.scale(table_data.protocol='nh'), table_data.reliability(table_data.protocol='nh'),'r')
to be a double equals like:
scatter(table_data.scale(table_data.protocol=='nh'), table_data.reliability(table_data.protocol=='nh'),'r')
i.e. you want a comparison operation instead of an assignment operation.

Related

Populating Matlab legend using for loop

I am attempting to populate a legend of a bar graph for the corresponding number of quantities being plotted, which is variable. I have included a typical legend's plotting scheme below, though I am attempting to replicate this for a variable number of elements in the vector 'test'. I understand that this is relatively simple procedure, but my experience is limited and any help would be appreciated.
test=[1,2,3,4,5]
bar(diag(test), 'stacked')
legend('label1','label2','label3','label4','label5');
xlabel('labels')
title('Title')
You can combine the labels in one array. That way you would be able to work with a dynamic number of labels.
This does the same thing with your code, but the legend function is called with an array:
test=[1,2,3,4,5]
bar(diag(test), 'stacked')
legend(["label1", "label2", "label3", "label4", "label5"]);
xlabel('labels')
title('Title')
Note that I used strings (") instead of chars (') because char arrays are harder to operate as arrays.
You can also automate the names completely,
test=[1,2,3,4,5]
bar(diag(test), 'stacked')
legendNames = "label" + test;
legend(legendNames);
xlabel('labels')
title('Title')

Display all predictions and their percentages in the title of a figure

Im working on a project in deep learning. I have two variables for storing predictions and their percentages.
This is done using a for loop for every image in a cell array C. Both predictions and percentages are stored in separate column vectors which Ill need for later use
for i=1:size(C)
img=im2uint8(C{i});
img2=imresize(img,[224 224]);
[prediction,pred_val] = classify(n_net,img2)
predictions(i,:)=prediction;
pred_vals(i,:)=pred_val;
figure
imshow(img2)
title(sprintf("%s %s",[labels,num2str(100*pravdepodobnost_predikciesnimky(i,:))]));
end
Now, I want to display all of the predictions and percentages, so lets say the network predicts that image consists of 80%ocean and 20% people, so the title in the figure displays both predictions not just the dominant one. Which is the best way to do this?
Edit: here is a sample for clarification (the titles and labels are in my native language):
labels=string(categories(scenes_training.Labels)') %creates 1x2 string array
labels =
"Pobrežie" "Ulica"
After one iteration from the for loop above I get this:
prediction = categorical
Ulica
pred_vals = 1×2 single row vector
0.0046 0.9954
And (after modification) a figure
So my goal is to write the title like this:
Pobrežie 0.45644 %; Ulica 99.5436 %
Given the variables described above then you can use sprintf to do what you want.
% Use the dummy data from above
labels = ["Pobrežie", "Ulica"];
pred_vals = [0.0046, 0.9954];
% now format a string to use as a title
img_title=sprintf("%s %s%%; ", [labels', num2str(100*pred_vals')]');
%img_title now equals "Pobrežie 0.46%; Ulica 99.54%; "
Basically sprintf will cycle through all values it is supplied with, repeating the string format until it is done. You can use this to list the contents of a matrix of data. Putting the data in a matrix and transposing it is just a way of interleaving the names and the values.
The nested transposing in the sprintf input arguments is just to persuade matlab to deal correctly with the different value types - it is a little hacky but then MATLAB often is. If I can find a nicer way then I'll update the answer.
If you don't want the final "; " at the end of the string, then you can trim that off with a subsiquent step.

MATLAB for loop through columns to plot multiple lines

I need your help again :). I'm trying to plot multiple lines for a very large dataset. To start easier, I divided the dataset to get a TABLE in Matlab that contains 6 columns, with the first column representing the date that I want on my x-axis. Now I want to plot the other columns (and in the original file are a lot more than 6 columns) on the y axis, using a for loop. I tried the following, with no success:
hold on
for i=2:1:6
plot(Doldenstock(:,1), Doldenstock(:,i));
end
hold off
As I understand this, this code would do exactly what I want for columns 2,3,4,5,6. However, I always get the same error code:
Error using tabular/plot
Too many input arguments.
Error in Plotting_bogeo (line 6)
plot(Doldenstock(:,1), Doldenstock(:,i));
Now, I don't know if maybe for loops like this don't work for tabes but only for arrays?
Thanks for your help in advance!
Cheers,
Tamara
The function plot(x) expect x to be a scalar, a vector, or a matrix. But in your case the input is a table, because accessing a table with parentheses return a table, which is not supported.
If you read the doc "how to access data in a table" you will figure out that you need to use curly brace {} to extract the raw data (in your case a 1D matrix).
So use:
plot(T{:,1},T{:,2})

Retrieve Gradient of Reference Line Generated by probplot

I am generating probability plots for a number of data sets in matlab.
I am plotting them using probplot with a weibull distribution reference line
data = [1,1,1,1,2,2,2,3,4,5,3,3,2,2,1,3,5,7,2,4,2] ;
h = probplot('weibull',data) ;
This function as per the matlab documentation returns a graphic array object. This appears to only contain the original data and not the reference line.
Is there any way of retreiving information about about this reference line without plotting it and indiviually extracting it using the figure tools (very much not an option I'd like to go down as there are potentionally hundreds of plots to go through).
I can see there is wblplot that returns a line array of 3 lines, one of which is the original data and one of the others is likely the reference the line however I will have to try different distributions to fit further down the road and would prefer to keep a generic approach.
You are wrong!
data = [1,1,1,1,2,2,2,3,4,5,3,3,2,2,1,3,5,7,2,4,2] ;
h = probplot('weibull',data) ;
b=h(2);
figure
plot(b.XData,b.YData)
h is a graphic array object, so its an array. The first element contains the original data, but the second h(2) contains the reference line.

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