Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X for plots and slicing char arrays #53

Merged
merged 3 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions code/02-arrays.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,19 @@

M(1:4, :)
M(:, 6:end)
N = M(:)
size(N)

% ! Challenge:
% ## Master indexing
% !! Solution:
M(2:3:end, :)



% ! Challenge:
% ## Slicing character arrays
element = 'oxygen';
disp("first three characters: " + element(1:3))
disp("last three characters: " + element(4:6))
% !! Solution:


element(1:2:end)


30 changes: 18 additions & 12 deletions code/04-plotting.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@


% ## Plotting
plot(1:40,per_day_mean)
day_of_trial = 1:40;
plot(day_of_trial, per_day_mean)




title("Daily average inflammation")
xlabel("Day of trial")
ylabel("Inflammation")
plot(per_day_max)
plot(day_of_trial, per_day_max)
title("Maximum inflammation per day")
ylabel("Inflammation")
xlabel("Day of trial")
Expand All @@ -20,57 +21,62 @@
edit src/single_plot.m
addpath("src")

plot(per_day_min)
day_of_trial = 1:40;
plot(day_of_trial, per_day_min)
title("Minimum inflammation per day")
ylabel("Inflammation")
xlabel("Day of trial")
% ## Multiple lines in a plot
copyfile("src/single_plot.m","src/multiline_plot.m")
plot(per_day_mean,DisplayName="Mean")
day_of_trial = 1:40;
plot(day_of_trial, per_day_mean, DisplayName="Mean")
legend
title("Daily average inflammation")
xlabel("Day of trial")
ylabel("Inflammation")
hold on
plot(patient_5,DisplayName="Patient 5")
plot(day_of_trial, patient_5, DisplayName="Patient 5")
hold off

% ! Challenge:
% ## Patients 3 & 4
% !! Solution:
plot(per_day_mean,DisplayName="Mean")
day_of_trial = 1:40;
plot(day_of_trial, per_day_mean, DisplayName="Mean")
legend
title("Daily average inflammation")
xlabel("Day of trial")
ylabel("Inflammation")
hold on
plot(patient_data(3,:),DisplayName="Patient 3")
plot(patient_data(4,:),DisplayName="Patient 4")
plot(day_of_trial, patient_data(3,:), DisplayName="Patient 3")
plot(day_of_trial, patient_data(4,:), DisplayName="Patient 4")
hold off


% ## Multiple plots in a figure
edit src/tiled_plot.m
day_of_trial = 1:40;
tiledlayout(1, 2)
nexttile
plot(per_day_max)
plot(day_of_trial, per_day_max)
title("Max")
xlabel("Day of trial")
ylabel("Inflamation")
nexttile
plot(per_day_min)
plot(day_of_trial, per_day_min)
title("Min")
xlabel("Day of trial")
ylabel("Inflamation")
day_of_trial = 1:40;
tlo=tiledlayout(1, 2);
title(tlo,"Per day data")
xlabel(tlo,"Day of trial")
ylabel(tlo,"Inflamation")
nexttile
plot(per_day_max)
plot(day_of_trial, per_day_max)
title("Max")
nexttile
plot(per_day_min)
plot(day_of_trial, per_day_min)
title("Min")

% ## Where is the `nexttile`?
Expand Down
5 changes: 5 additions & 0 deletions code/extract_episodes_code.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ function extract_episodes_code(episode_names,q)
% Otherwise, it will iterate through the "*.md" files in "episodes/"
%
% The extracted code blocks are saved in the "code" folder.
%
% Usage:
% - Add the 'code' and 'episodes' directories to MATLAB's path.
% - To extract the code from all episodes, run on the console:
% >> extract_episodes_code()

quiet=false;
if ~exist("episode_names","var")
Expand Down
100 changes: 35 additions & 65 deletions episodes/02-arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,29 @@ ans =
62 63 1
```

or even the whole matrix. Try for example:

```matlab
>> N = M(:)
```
and you'll see that it returns all the elements of M.
The result, however, is a column vector, not a matrix.
We can make sure that the result of `M(:)` has 8x8=64 elements
by using the function [size](https://uk.mathworks.com/help/matlab/ref/size.html),
which returns the dimensions of the array given as an input:
```matlab
>> size(N)
```
```output
ans =
64 1
```
So it has 64 rows and 1 column.
Effectively, then, `M(:)` 'flattens' the array into a column vector.
The order of the elements in the resulting vector comes from appending each column of the original array in turn.
This is the result of something called [linear indexing](https://uk.mathworks.com/company/technical-articles/matrix-indexing-in-matlab.html),
which is a way of accessing elements of an array by a single index.

::::::::::::::::::::::::::::::::::::::: challenge

## Master indexing
Expand All @@ -371,8 +394,6 @@ ans =

::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::::::::: challenge

## Slicing character arrays

A subsection of an array is called a [slice]({{ page.root }}/reference.html#slice).
Expand All @@ -389,71 +410,20 @@ first three characters: oxy
last three characters: gen
```

1. Use slicing to:
- Select all elements from the 3rd to the last one.
- Find out what is the value of `element(1:2:end)`?
- Figure out how would you get all characters except the first and last?

2. We used the single colon operator `:` in the indices to get all the available column or row numbers,
but we can also use it like this: `M(:)`. What do you think will happen?
How many elements does `M(:)` have?
What would happen if we use it for the element variable? Compare the result from `element` and `element(:)`.
Are there any differences?

::::::::::::::: solution


1) Exercises using slicing

- To select all elements from 3rd to last we can use start our range at `3` and use the keyword `end`:
```matlab
>> element(3:end)
```
```output
ans =
'ygen'
```

- The command `element(1:2:end)` starts at the first character, selects every other element (notice the interval is 2),
and goes all the way until the last element, so:
```matlab
>> element(1:2:end)
```
```output
ans =
'oye'
```

- To select each character starting with the second we set the start at `2`,
and to not include the last one we can finish at `end-1`:
```matlab
>> element(2:end-1)
```
```output
ans =
'xyge'
```

2) The colon operator gets all the elements that it can find, and so using it as `M(:)` returns all the elements of M.
We can make sure that the result of `M(:)` has 8x8=64 elements
by using the function [size](https://uk.mathworks.com/help/matlab/ref/size.html),
which returns the dimensions of the array given as an input:
```matlab
>> size(M(:))
```
```output
ans =
64 1
```
So it has 64 rows and 1 column. Efectively, then, `M(:)` 'flattens' the array into a column vector.
The order of the elements in the resulting vector comes from appending each column of the original array in turn.
Therefore, the last 8 elements we see if we evaluate `M(:)` correspond to the last column of `M`, for example.

The difference between evaluating `element` and `element(:)` is that the former is a row vector, and the latter a column vector.
And we can use all the tricks we have learned to select the data we want.
For example, to select every other character we can use the colon operator with an increment of 2:
```matlab
>> element(1:2:end)
```
```output
ans =
'oye'
```

:::::::::::::::::::::::::
We can also use the colon operator to access all the elements of the array,
but you'll notice that the only difference between evaluating `element` and `element(:)`
is that the former is a row vector, and the latter a column vector.

::::::::::::::::::::::::::::::::::::::::::::::::::



Expand Down
40 changes: 24 additions & 16 deletions episodes/04-plotting.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ We will start by exploring the function `plot`.
The most common usage is to provide two vectors, like `plot(X,Y)`.
Lets start by plotting the average inflammation across patients over time.
For the `Y` vector we can provide `per_day_mean`,
and for the `X` vector we can simply use the day number,
which we can generate as a range with `1:40`.
and for the `X` vector we want to use the number of the day in the trial,
which we can generate as a range with:
```matlab
>> day_of_trial = 1:40;
```
Then our plot can be generated with:
```matlab
>> plot(1:40,per_day_mean)
>> plot(day_of_trial, per_day_mean)
```

::::::::::::::::::::::::::::::::::::::::: callout
Expand All @@ -53,7 +56,7 @@ In most cases, however, using the indices on the x axis is not desireable.
::::::::::::::::::::::::::::::::::::::::: callout

**Note:** We do not even need to have the vector saved as a variable.
We would obtain the same plot with the command `plot(mean(patient_data, 1))`.
We would obtain the same plot with the command `plot(1:40, mean(patient_data, 1))`, or `plot(mean(patient_data, 1))`.

::::::::::::::::::::::::::::::::::::::::::::::::::

Expand All @@ -75,7 +78,7 @@ As we expected, this figure tells us way more than the numbers we had seen in th
Let's have a look at two other statistics: the maximum and minimum
inflammation per day across all patients.
```matlab
>> plot(per_day_max)
>> plot(day_of_trial, per_day_max)
>> title("Maximum inflammation per day")
>> ylabel("Inflammation")
>> xlabel("Day of trial")
Expand Down Expand Up @@ -116,7 +119,8 @@ Try copying and pasting the plot commands for the max inflammation on the script
Because we now have a script, it should be much easier to change the plot to the minimum inflammation:

```matlab
>> plot(per_day_min)
>> day_of_trial = 1:40;
>> plot(day_of_trial, per_day_min)
>> title("Minimum inflammation per day")
>> ylabel("Inflammation")
>> xlabel("Day of trial")
Expand Down Expand Up @@ -145,7 +149,8 @@ We can specify the legend names by adding `,DisplayName="legend name here"`
inside the plot function. We then need to activate the legend by running `legend`.
So, to plot the mean values we first do:
```matlab
>> plot(per_day_mean,DisplayName="Mean")
>> day_of_trial = 1:40;
>> plot(day_of_trial, per_day_mean, DisplayName="Mean")
>> legend
>> title("Daily average inflammation")
>> xlabel("Day of trial")
Expand All @@ -157,7 +162,7 @@ So, to plot the mean values we first do:
Then, we can use the instruction `hold on` to add a plot for patient_5.
```matlab
>> hold on
>> plot(patient_5,DisplayName="Patient 5")
>> plot(day_of_trial, patient_5, DisplayName="Patient 5")
>> hold off
```

Expand All @@ -178,7 +183,8 @@ Try to plot the mean across all patients and the inflammation data for patients
The first part for the mean remains unchanged:

```matlab
>> plot(per_day_mean,DisplayName="Mean")
>> day_of_trial = 1:40;
>> plot(day_of_trial, per_day_mean, DisplayName="Mean")
>> legend
>> title("Daily average inflammation")
>> xlabel("Day of trial")
Expand All @@ -191,14 +197,14 @@ Now we can either save that data in a variable, or we use it directly in the plo

```matlab
>> hold on
>> plot(patient_data(3,:),DisplayName="Patient 3")
>> plot(patient_data(4,:),DisplayName="Patient 4")
>> plot(day_of_trial, patient_data(3,:), DisplayName="Patient 3")
>> plot(day_of_trial, patient_data(4,:), DisplayName="Patient 4")
>> hold off
```

The result looks like this:

![](fig/plotting_patients-3-4.svg){alt='Average inflamation and Patients 3 & 4'}
![](fig/plotting_patients-3-4.svg){alt='Average inflammation and Patients 3 & 4'}

Patient 4 seems also quite average, but patient's 3 measurements are quite noisy!

Expand All @@ -223,14 +229,15 @@ Lets start a new script for this topic:
```
We can show the average daily min and max plots together with:
```matlab
>> day_of_trial = 1:40;
>> tiledlayout(1, 2)
>> nexttile
>> plot(per_day_max)
>> plot(day_of_trial, per_day_max)
>> title("Max")
>> xlabel("Day of trial")
>> ylabel("Inflamation")
>> nexttile
>> plot(per_day_min)
>> plot(day_of_trial, per_day_min)
>> title("Min")
>> xlabel("Day of trial")
>> ylabel("Inflamation")
Expand All @@ -240,15 +247,16 @@ We can show the average daily min and max plots together with:
We can also specify titles and labels for the whole tiled layout if we assign the tiled layout to a variable
and pass it as a first argument to `title`, `xlabel` or `ylabel`, for example:
```matlab
>> day_of_trial = 1:40;
>> tlo=tiledlayout(1, 2);
>> title(tlo,"Per day data")
>> xlabel(tlo,"Day of trial")
>> ylabel(tlo,"Inflamation")
>> nexttile
>> plot(per_day_max)
>> plot(day_of_trial, per_day_max)
>> title("Max")
>> nexttile
>> plot(per_day_min)
>> plot(day_of_trial, per_day_min)
>> title("Min")
```

Expand Down
Loading