Conditional Formatting: Highlight cells of a range if cell equal to any values of an array - visualization

I would like to streamline the visualization of scales in the guitar fretboard.
However, I can't overcome the current problem
From the range B3:S8 (the entire fretboard) I would like to highlight the cells which match with the values of the range W3:W9 (the C major scale)
I've found some intermediate solutions, where I would need to repeat it for each line of the range of the fret.
Seeking now a way where the whole fret range would match an one dimension array of values.

Related

How to change pixel values of an RGB image in MATLAB?

So what I need to do is to apply an operation like
(x(i,j)-min(x)) / max(x(i,j)-min(x))
which basically converts each pixel value such that the values range between 0 and 1.
First of all, I realised that Matlab saves our image(rows * col * colour) in a 3D matrix on using imread,
Image = imread('image.jpg')
So, a simple max operation on image doesn't give me the max value of pixel and I'm not quite sure what it returns(another multidimensional array?). So I tried using something like
max_pixel = max(max(max(Image)))
I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.
After performing the above scaling operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?
image = imread('cat.jpg')
maxI = max(max(max(image)))
minI = min(min(min(image)))
new_image = ((I-minI)./max(I-minI))
This gives output of only 1s and 0s which doesn't seem correct.
The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?
I could also loop through all pixels but I'm assuming that will be time taking. Very new to this, any help will be great.
If you are not sure what a matlab functions returns or why, you should always do one of the following first:
Type help >functionName< or doc >functionName< in the command window, in your case: doc max. This will show you the essential must-know information of that specific function, such as what needs to be put in, and what will be output.
In the case of the max function, this yields the following results:
M = max(A) returns the maximum elements of an array.
If A is a vector, then max(A) returns the maximum of A.
If A is a matrix, then max(A) is a row vector containing the maximum
value of each column.
If A is a multidimensional array, then max(A) operates along the first
array dimension whose size does not equal 1, treating the elements as
vectors. The size of this dimension becomes 1 while the sizes of all
other dimensions remain the same. If A is an empty array whose first
dimension has zero length, then max(A) returns an empty array with the
same size as A
In other words, if you use max() on a matrix, it will output a vector that contains the maximum value of each column (the first non-singleton dimension). If you use max() on a matrix A of size m x n x 3, it will result in a matrix of maximum values of size 1 x n x 3. So this answers your question:
I'm not quite sure what it returns(another multidimensional array?)
Moving on:
I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.
This is correct. Alternatively, you can use max(A(:)) and min(A(:)), which is equivalent if you are just looking for the value.
And after performing the above operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?
There is no way for us to know why this happens if you do not post a minimal, complete and verifiable example of your code. It could be that it is because your variables are of a certain type, or it could be because of an error in your calculations.
The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?
This depends on what the intended end result is. Normalizing each colour (red, green, blue) seperately will result in a different result as compared to normalizing the values all at once (in 99% of cases, anyway).
You have a uint8 RGB image.
Just convert it to a double image by
I=imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Cat_poster_1.jpg/1920px-Cat_poster_1.jpg')
I=double(I)./255;
alternatively
I=im2double(I); %does the scaling if needed
Read about image data types
What are you doing wrong?
If what you want todo is convert a RGB image to [0-1] range, you are approaching the problem badly, regardless of the correctness of your MATLAB code. Let me give you an example of why:
Say you have an image with 2 colors.
A dark red (20,0,0):
A medium blue (0,0,128)
Now you want this changed to [0-1]. How do you scale it? Your suggested approach is to make the value 128->1 and either 20->20/128 or 20->1 (not relevant). However when you do this, you are changing the color! you are making the medium blue to be intense blue (maximum B channel, ) and making R way way more intense (instead of 20/255, 20/128, double brightness! ). This is bad, as this is with simple colors, but with combined RGB values you may even change the color itsef, not only the intensity. Therefore, the only correct way to convert to [0-1] range is to assume your min and max are [0, 255].

In emacs, how to colorize a row in a CSV based on value in a column?

I have created a major-mode for emacs that I use for data analysis. This mode works great for me but it's drab and I don't take advantage of color the way I should. The data being analyzed is in a CSV format and I'd like to colorize the rows within based on values in the columns.
Let's say I have the following file in CSV format:
one,1,2,3
two,4,5,6
three,7,8,9
The rows in this CSV should be colored with red based on the value in the 4th column and the intensity of the red should increase with that same value. So in this case the last column should be the most intense red and the first should be the least red.
I've read over Search Based Fontification and I'm a bit confused as to how I would write a (matcher . facespec) that sets the facespec properly. facespec is an expression that evaluates to
(face face prop1 val1 prop2 val2…)
but how do I make this depend on the values in the fourth column of my CSV? I guess the value in the fourth column is what gets matched but how do I tie the face used to the magnitude of the value matched? I suppose I need to generate a face on the fly based on the value matched but not sure how to do so.
Any ideas? A simple example would be best.

changing some values according to a logical index in a specified region of a matrix

I have a matrix and I am interested in changing values that satisfy a certain condition inside that matrix differently, depending on where they are. Say I have a matrix smallPic. How do I obtain a matrix smallPicB with the same dimensions that changed all values that are above 50 in the first two columns to a 255, while those that are in the third and fourth column are changed to a 180?
I have this code which works, but it is pretty ugly and requires splitting the matrix and concatenating it again:
smallPic1=smallPic(:,1:2);smallPic1(smalllPic1>50)=255;
smallPic2=smallPic(:,3:4);smallPic2(smalllPic2>50)=180;
smallPicB = [smalllPic1 smalllPic2];
How would you combine the logical index with the scalar index in one command?
What doesn't work is this:
smallPic(:,smallPic(:,3:4)>50) = 180
Here, the second mention of smallPic inside the brackets does not allow indexing into the correct position of smallPic because it doesn't have the same dimensions as smallPic. So this command actually replaces values in the first two columns of smallPic that are in the same row as those values that are above 50 in the third and fourth column, instead of replacing the values in the third and fourth column themselves.
Any other suggestions?
It probably is not what you're looking for, but it can help if you have lots of assignments like that:
J = repmat(1:size(smallPic, 2), size(smallPic, 1), 1)
smallPic((J<3)&(smallPic>50))=255
smallPic((J>2)&(J<5)&(smallPic>50))=180
You can also call ismember function if column indices are not consecutive:
smallPic(ismember(J, [[1:2 5:6]])&(smallPic>50))=255

setting YTickLabel matlab

what is wrong that i can not figure out in my YTickLabel:
h2=bar(myData);
ylabels=['1';'1.5';'2';'2.5';'3'];
set(gca,'XTickLabel',applicationNames),'XTick',applicationNames),'YTickLabel',ylabel));
p.s: I have tried this as well with no success:
ax=gca
ax.YTickLabel=['1';'1.5';'2';'2.5';'3'];
I am getting this error:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
You are trying to create a character array. In this case, you are trying to create a 2D matrix where the number of columns should have the same number of characters and the number of rows denotes how many labels you have. For your strings, the maximum number of characters per column is three (number / dot / number). Because you have characters that are only of length 1 (i.e. just a number), you are getting an inconsistent concatenation error because it's expecting all characters to be of length 3 in the array.
What you actually need to use is a cell array to accommodate for the inconstant size of each y tick label. Therefore:
ax.YTickLabel={'1';'1.5';'2';'2.5';'3'};
Alternatively, because your labels are numbers, you can simply use a numeric array instead:
ax.YTickLabel = [1;1.5;2;2.5;3];
A cell array of characters is used if you want to label the x and/or y axis to be something other than just numbers. It's possible to label the y axis using text, such as:
ax.YTickLabel = {'John'; 'Paul'; 'George'; 'Ringo'; 'The Beatles'};

How do I find frequency of values appearing in all rows of a matrix in MATLAB?

I have a 161*32 matrix (labelled "indpic") in MATLAB and I'm trying to find the frequency of a given number appearing in a row. So I think that I need to analyse each row separately for each value, but I'm incredibly unsure about how to go about this (I'm only new to MATLAB). This also means I'm incredibly useless with loops and whatnot as well.
Any help would be greatly appreciated!
If you want to count the number of times a specific number appears in each row, you can do this:
sum(indpic == val, 2)
where indpic is your matrix (e.g image) and val is the desired value to be counted.
Explanation: checking equality of each element with the value produces a boolean matrix with "1"s at the locations of the counted value. Summing each row (i.e summing along the 2nd dimension results in the desired column vector, where each element being equal to the number of times val is repeated in the corresponding row).
If you want to count how many times each value is repeated in your image, this is called a histogram, and you can use the histc command to achieve that. For example:
histc(indpic, 1:256)
counts how many times each value from 1 to 256 appears in image indpic.
Like this,
sum(indpic(rownum,:) == 7)
obviously change 7 to whatever.
You can just write
length(find(indpic(row_num,:)==some_value))
and it will give you the number of elements equal to "some_value" in the "row_num"th row in matrix "indpic"