Create a plot with a 2D colourmap depending on two variables - matlab

I want to display an image (e.g.imshow) and use a colormap to represent the values of my data points.
However, colormap only gives the option to be dependent on a single variable, but I want a "2D colormap" which depends on two variables.
For example I have a simple image 2x2 pixels:
img = [
1 1 5 6;
1 2 8 7;
2 1 4 3;
2 2 15 3]
Here the first two values of each row are the coordinates, the other two are the values describing the pixel (call them x and y).
When displaying the image I want to use a 2D colormap. For example something like this, which picks a colour depending on both variables (x and y):
Is there an option in MATLAB do to this, possibly in one of the extra toolboxes?
If not can this be done manually? I was thinking by overlaying a grey scale image given from the first value over a colormap image given by the second value a similar effect could be achieved.

In your 2D colormap you are actually using the HSV color space.
Basically, your x axis is Hue, and Y axis is Saturation. You can convert any value into this space if its properly scaled. If you make sure that you scale your 3rd and 4rd column in the [0-1] interval you can easily do
colorRGB=hsv2rgb([val3,val4,0.5]);
If you perform this operation for each pixel, you'll get the image you want.
I gave a extended explanation of how HSV works here

Related

How to get color gradient for Newton Method basin of attraction fractal

I am using MATLAB to go through a NxN grid in the complex plane, the x's are the real component and the y's are the imaginary component. For each point on this grid I am using it as a starting point for Newton's Method. Depending on which root it converges to it is assigned a number. This number is used with pcolor to plot the fractal.
It plots nicely, however, I want to also plot the color darkness depending on how long it takes to converge to the root. I am having trouble with pcolor. I was able to get the 3 colors for the 3 roots but I am not quite sure how to add more colors so that it is more descriptive.
Here is the code to get the plot after I have
xp - array of x points
yp - array of y points
col - NxN matrix that has either 1, 2, 3 (corresponds to which root)
% thresholds for color
caxis([1 3]);
% sets colors Red, Green, Blue
mycolors = [1 0 0; 0 1 0; 0 0 1];
colormap(mycolors);
% real component on x and imaginary component on y
h=pcolor(xp, yp, col');
set(h, 'LineStyle', 'none' );
So, how can I get there to be a gradient in pcolor, it seems that pcolor just kind of figures out all the colors itself. And caxis only allows boundaries for 2 colors.
Let me know if you want to see the full code of this program.
Thank you
Add the number of iterations it took to get to convergence as a color. Define the colors in HSV, and make the number of iterations map to the value S of HSV. That will give you a nice and meaningful color gradient without really changing the colors.
The pseudocode is:
For that, generate your 3 colors mycolors as you do. Change their color space as mycolorshsv=rgb2hsv(mycolors);
What you want now is to generate a bunch (your choice) of colors per color.
mycolorshsv=repelem(mycolorshsv,N,1);
Now lets generate N gradients per color.
mycolorshsv( 1: N,2)=linspace(0,1,N);
mycolorshsv( N+1:2*N,2)=linspace(0,1,N);
mycolorshsv(2*N+1:3*N,2)=linspace(0,1,N);
You want e.g. the longest iteration you obtained maxiter to be the brightest. We need to transform your col matrix from [1,2,3] to our current range now. For that, just
col=(col-1)*N+1; % make 1=>1, 2=>N, 3=>2*N;
col=col+iteration_matrix; %max(iteration_matrix) must be maxiter. You may want to normalize so min(iteration_matrix) is 0
Now simply set the colormap(mycolors);, and I would use imagesc instead of pcolor, but its less important.
Play with the range, and limits of the colro values for nicer maps. Often non-linear maps are also used, where a function f is applied to the iteration values, such as the sigmoid.
This is the technique used for the newton fractals you can find in wikipedia, such as:

How to create a mask to segment a color image by activecontour?

I want to use the function activecontour in matlab to segment a color image, but I don't know how to create the mask.
The documentation says:
For color and multi-channel images, mask must be a 2-D logical array where the first two dimensions match the first two dimensions of the image A.
But I don't understand what has to be done. Any suggestions?
Let's consider that the size of your image is NxM pixels, N is the number of rows, M the number of columns.
If it is a color image, each pixel is probably composed of 3 values, one for intensity of red (R), one intensity of blue (B) and one for intensity of green (G). These are called the color channels. So the real shape of the matrix representing your image is NxMx3.
What the documentation says is that the mask should be 2-D, and the dimensions should match the first two dimension of your image. It means the mask should have the same number of rows and cols than your image, but each pixel of the mask is not composed of 3 values anymore. It is composed of 1 value (a logical value : 0 or 1).
So what you need to do is to give the function a matrix NxM with only 0 and 1 as possible values. The doc says that the mask is the :
Initial contour at which the evolution of the segmentation begins, specified as a binary image the same size as A.
So the mask needs to represent an initial guess of the contour. If you already know that what you want to see is in the upper left corner of the image, you can set the initial contour as a square located in the upper left corner for example.
Now to represent the contour by a matrix of logicals, you simply set all the elements of the matrix to 0 and just the elements representing the contour to 1 I guess.
Lets me know if there is something you don't understand, I'd be glad to answer you.

How to turn a pair of X, Y points in decimal into an image more accurately?

Normally this table is around 600 points but I didn't want to type it all, let's say I have points like this:
240.021000000000 291.414100000000
250.985100000000 297.566300000000
260.143500000000 310.125800000000
270.605100000000 315.355400000000
279.775500000000 327.352000000000
288.302300000000 335.765900000000
301.487400000000 348.374900000000
313.892100000000 340.501400000000
323.391400000000 328.044800000000
334.615100000000 322.182400000000
Where number on the left is X and number on the right is Y of a coordinate where there is a "thing" or let's say where the color is white and rest is black.
And I want to turn this into an image, what I did so far is this:
% Added 50 more pixels to not stick to edge of image
image = uint8(zeros(max(table(:, 1))+50, max(table(:, 2)+50))
for i = size(table(:))
image(round(table(i, 1)), round(table(i, 2))) = 256;
end
imshow(image);
I am wondering how accurate this is and how I can improve it or if I can improve it?
Reason here is I will do this for two tables and need to compare the similarity of two images that belong to these tables, but I don't even have an image and rounding didn't feel like the best way since 270.49999999 and 270.5000001 are similar, yet 270 and 271 are different. There can also be points that overlap each other if all is just rounded up or just rounded down.
I see two approaches, you can increase the resolution by binning your image to be N*600 by N*600 point instead of 600x600, for example 6000x6000, then each 0.1 value will be in a different pixel. Or, you can convolve your 1 pixel with a distribution like a 5x5 Gaussian of signa=1 that will capture the spread around that point position. For example using exp(- ((x-xn).^2+(x-yn).^2)/2) where xn and yn are the n-th point coordinate in your question, and x and y are obtained via [x y]=meshgrid(1:600) or whatever your image size is....

MATLAB: Matrix with binary info (1 and 0) and image command show nothing

After processing an input I finally have a matrix of N x M x L representing a volume. The values on that matrix are only 0 or 1. When I try to display a "slice" from this volume using image like this:
image(volume(:,:,80))
the displayed figure is all blue. Now if I use imagesc, the image is displayed ok (in blue and red tones). I think this is related to colormap but can't really figure out how to display the images with the image command.
My final goal is to display 3 or 4 slices in one 3d plot, somthing similar to what is shown here: http://www.mathworks.com/help/matlab/visualize/techniques-for-visualizing-scalar-volume-data.html#f5-4457
You are right, your problem is related to colormap. Try
image(volume(:,:,80))
colorbar
You will see that your current colormap ranges from 0 to 64. If you use this command instead:
image(volume(:,:,80),'CDataMapping','scaled')
colorbar
you should get the image you want, and your colormap is now scaled to the range of your data (of course, you don't need to show the colorbar to get the right scaling, I just added it to make things more clear).

Relative Markersize in Matlab plots

I am trying to plot a matrix where each element is in one out of two states. (ising model..)
Now, I would like to have one state colored and the other one white. That works using
[i,j] = find(S);
figure(gcf);
plothandle = scatter(i,j);
axis([0 nNodes+1 0 nNodes+1]);
when S holds the Spins and one state is equal to 0. (find returns a matrix of only non-zero elements)
To have a useful plot, the sizes of the markers should be 1x1 in RELATIVE coordinates. So if the whole matrix S would be in a state non-zero, everything would be colored.
However, it seems like Matlab only allows MarkerSizes in points or inches. How could I solve this?
One idea I had was, that I find out the point-size of the axes and then can easily calculate how big my markers should be. Then I would have to create a callback function if I want to zoom in and so on. Also, I have not yet found a way (without the image acq. toolbox) to find out the absolute size of my axes.
To clarify what I want: How could I plot a chessboard using a matrix with 1 for black and 0 for white fields?
For displaying data of this sort I generally prefer IMAGE or IMAGESC to PCOLOR since PCOLOR won't display the last row and column of the matrix when using faceted shading (the default). Also, IMAGE and IMAGESC flip the y axis so the image more intuitively matches what you think of when looking at a matrix (i.e. rows start from 1 at the top). You can visualize your matrix like this:
S = round(rand(20)); %# Sample 20-by-20 matrix of ones and zeroes
imagesc(S); %# Plot the image
colormap([1 1 1; 0 0 0]); %# Set the colormap to show white (zero elements) and
%# black (non-zero elements)
And here's a sample image:
Just as a suggestion, you can try using pcolor instead of `scatter' Example:
pcolor(hadamard(20))
colormap(gray(2))
axis ij
axis square