I have 11 1x50 matrices that contain densities. The first looks like [20, 20, 20... 20] and represents time=0. The second looks like [20, 19, 22,..], etc. and represents time=100. These continue to vary until t=1000.
What I'm hoping to do is to create a plot with the elements' position on the x-axis (50 positions for the 50 pieces of data in each) and time (0-1000) on the y-axis. Ideally, I'd like the plot to be completely filled in with color densities, and a colorbar on the side that shows what densities the color range represents.
Any help would be greatly appreciated!
Sort of inspired by: http://www.chrisstucchio.com/blog/2012/dont_use_scatterplots.html
Assuming you have (or can arrange to have) all those vectors as columns of a 11x50 matrix:
A = randi(100, 11,50); %//example data
you can just use
imagesc(1:50, 0:100:1000, A)
colorbar
axis xy %// y axis increasing, not decreasing
Example:
Looking at the comments, it will be easier to stack these vectors into a 2D matrix. You have 11 individually named vectors. Assuming that your vectors are named vec1, vec2, vec3, etc., create a 2D matrix A that stacks these vectors on top of each other. Also, you'll need to include an extra row and column at the end of this matrix that contains the minimum over all of your vectors. The reason why this is will be apparent later, but for now take my word for it as this is what you need.
In other words:
A = [vec1; vec2; vec3; vec4; vec5; vec6; vec7; vec8; ...
vec9; vec10; vec11];
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
As such, the first row contains the information at time 0, the next row contains information at time 100, etc. up to time 1000.
Now that we have that finished, we can use the pcolor function to plot this data for you. pcolor stands for pseudo-coloured checkerboard plot. You call this by doing:
pcolor(A);
This will take a matrix stored in A and produce a checkerboard plot of your data. Each point in your matrix gets assigned a colour. The colours get automatically mapped so that the least value gets mapped to the lowest colour while the highest value gets mapped to the highest colour. pcolor does not plot the last row and last column of the matrix, but pcolor does use all of the data in the matrix. In order to ensure that the colours get properly mapped, we need to pad your matrix so that the last row and last column get assigned to the smallest value over all of your vectors. As you want to plot all values in the matrix, that's why we did what we did above.
Once we do this, we'll need to modify the X and Y ticks so that it conforms to your data. As such:
pcolor(A);
set(gca, 'XTick', 0.5:5:51.5);
set(gca, 'XTickLabel', 0:5:50);
set(gca, 'YTick', 1.5:11.5);
set(gca, 'YTickLabel', 0:100:1000);
xlabel('Sample Number');
ylabel('Time');
colorbar;
What the code does above is that it generates a checkerboard pattern like what we talked about. This labels the Sample Number on the x axis while time is on the y axis. You'll see with the two set commands that I did, this is a bit of a hack. The y axis by default labeled the ticks going from 1 - 12. What I did was that I changed these labels so that they go from 0 to 1000 in steps of 100 instead and I also removed the tick of 12. In addition, I have made sure that these labels go in the middle of each row. I do this by setting the YTick property so that I add 0.5 to each value going from 1 - 11. Once I do this, I then change the labels so that they go from 0 - 1000 in steps of 100. I also do the same for the x axis in a similar fashion to the y axis. I then add a colorbar to the side as per your request.
Following the above code, and generating random integer data that is between 13 and 27 as per your comments:
A = randi([13,27], 11, 50);
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
We get:
Obviously, the limits of the colour bar will change depending on the dynamic range of your data. I used randi and generated random integers within the range of 13 to 27. When you use this code for your purposes, the range of the colour bar will change depending on the dynamic range of your data, but the colours will be adjusted accordingly.
Good luck!
Related
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:
I am plotting data which is polynomial but I would like to show it on a straight line so that it is clearer.
I want the x-axis tick marks to show N^2 where N is the tick location. I also want the actual ticks on the graph to be evenly spaced even though the numbers aren't.
I tried to change the ticks using
xtick_squared = (0:10:100).^2
set(gca,'xTick',xtick_squared,'xTickLabel',xtick_squared)
but it gives this
How can I display them each being even spaced while reatining their values as well as adjusting the data?
This should work fine:
x = 0:10:100;
y = (x .^ 2) + 5;
labs = sprintfc('%d',x.^2);
plot(x,y);
set(gca,'XTickLabel',labs);
Actually, it's all about changing the tick labels without changing the ticks themselves. Here is the final output:
You can specify the location of x-ticks and then rename them.
Here is the code example:
x=[0,10,20,30,40,50].^2;
plot(x,x)
set(gca,'XTick',linspace(0,2500,6),'XTickLabels',num2cell(x))
P.S.: Note, that your actual data is plotted on evenly spaced grid. I've just renamed the ticks' names.
Edit: if you want to plot your actual data, you need to scale x-axis correspondingly. If you want to plot(x,x) you need to call plot(sqrt(x),x) instead:
x=[0,10,20,30,40,50].^2;
plot(sqrt(x),x)
set(gca,'XTick',linspace(0,2500,6),'XTickLabels',num2cell(x))
I want to plot a text file with 4 columns that first column in longitude,second in latitude, third is depth and forth is amount of displacement in each point.(it's related to a fualt)
-114.903874 41.207504 1.446784 2.323745
I want a plot to show the amount of displacement in each point (like images that we plot with imagesc),unfortunately "imagesc" command doesn't work for it.
how can I plot it?
Thanks for your attention
A simple way would be to use scatter3 and assign your displacements to be the colours. Note that you have to supply a size for this to work - I'm using [] (empty matrix) which will set it to default. If your four sets of values are four vectors of the same size, then it's just something like:
scatter3(lat,lon,depth,[],displacement, 'filled')
Values in displacement will be linearly mapped to the current colormap. 'filled' gives you filled markers rather than open ones (default marker is a circle but can be changed).
You can plot each point using plot3(longitude,latitude,depth). You can color each point according to the displacement in a for loop. The easiest way to do this is create a colormap, e.g. using jet and chosing the color according to the displacement.
figure;
hold on;
cmap = jet(256);
dispRange = [min(displacement),max(displacement)];
for k=1:size(longitude,2)
c = cmap(1+round(size(cmap,1)*(displacement(k)-dispRange(1))/dispRange(2)),:);
plot3(longitude(k),latitude(k),depth(k),'o', ...
'MarkerEdgeColor',c,'MarkerFaceColor',c);
end
I'm working with some signal. The signal has some length (time) and I devided it into 200 pieces and made some operations over them. The results are saved in matrix, so the matrix has one of the dimensions 200 and if I use imagesc() on it, to make results visualy readable, the x axis is from 0 to 200. But that does not correspond to time. The time is function of the values in x axis.
t = 640 * x
I need to make values in x axis to correspond to time. Is there any way, how to do this?
Use set and set the XTick and the XTickLabel properties accordingly. Assuming your image is already open, do this:
set(gca, 'XTick', 0:20:200);
set(gca, 'XTickLabel', 640*(0:20:200));
I used increments of 20 so that you don't clutter the x-axis. Modify the 20 to suit your tastes.
So i have this code to obtain radial gravity on Earth in function of the latitude:
G=6.6e-11;
M=5.976e24;
N=1000;
r=6371000;
w=2*pi/(24*3600);
for i=1:1:360
Theta=i*pi/180;
x(i)=i;
Vi(i)=-G*M/(r*r);
Phii(i)=r*w*w*sin(Theta)*sin(Theta);
gr(i)=Vi(i)+Phii(i);
end
plot(x,gr)
And it runs well. I want to make a graph of a circle made of a border of points (representing angle (i)) that change colour according to the value of gr(I want to set ranges of values of gr so that if the value obtained falls in a specific category, the point will have a specific colour).
I'm really new to MATLAB. Is there any possible way to make this?
Thanks in advance.
Here is the basic algorithm that I would do:
Determine how many colours you want to represent in your plot.
Create a colour map that has this many points for what you want to compute.
Determine a linearly increasing vector that varies from the minimum value of gr to the maximum value of gr with as many points as you have determined in Step #2
For each point in gr:
a. Determine which point yields the closest distance of this point to the vector in Step #3
b. Use this to index which colour you want.
c. Convert your angle into Cartesian co-ordinates, then plot this point with the colour found in Step 4b.
Let's tackle each point in detail.
Step #1 - Determine how many colours you want
This is pretty simple. Just determine how many colours you want. For now, let's assume that you want 20 colours, so:
num_colours = 20;
Step #2 - Create a colour map
What we can do is create a 20 x 3 matrix where each row determines a RGB tuple that denotes the amount of red, green and blue that each colour will occupy. MATLAB has built-in colour maps that will help you facilitate this. Here are all of the available colour maps that MATLAB has:
Each colour map has a special variable where you can provide it an integer number, and it'll return this 2D matrix of as many rows as the number you have provided. Each row gives you an RGB triplet which denotes the proportion of red, green and blue respectively. This matrix varies from the beginning of the colour map (top row) to the end (bottom row). All you have to do is use any name seen in the figure I've shown you above to create a colour map of that type. For example, if you wanted to get a bones colour map of 15 points, simply do:
colour_map = bones(15);
If you wanted to get a jet colour map of 25 points, simply do:
colour_map = jet(25);
.... you get the idea right? I like hsv so let's use the HSV colour map. You can use any colour map you want, but let's just stick with HSV for the sake of this example.
As such:
colour_map = hsv(num_colours);
Step #3 - Get that linearly increasing vector
You want certain colours to map into certain ranges, which is why this step is important. Given a value in gr, we want to figure out which colour we want to choose, and all you have to do is determine which value in gr is the closest to a value in this vector in Step #3. Therefore, you can use linspace to do this for you:
bin_vector = linspace(min(gr), max(gr), num_colours);
This will create a num_colours 1D array where the beginning of this array starts at the minimum value of gr and varies up to the maximum value of gr and each value is equally spaced such that we generate a num_colours array.
Step #4 - Bring it all home
Now, for each point in gr, we need to figure out which point is the closest to that vector in Step #3, we then use this to figure out the colour we want, then we need to convert our angle into Cartesian co-ordinates, then plot this point.
For illustration purposes, I'm going to assume your radius is 1. You can figure out how to get the x and y co-ordinates by simply doing cos(theta) and sin(theta), where theta is the angle you are examining. Since your gr array has 360 slots, I'm going to assume a resolution of 1 degree per slot. Therefore, you can easily do this in a for loop. Make sure you use hold on because we are going to call plot multiple times, and we don't want to overwrite the plot each time we call plot. You want all of the points to stay in the plot.
Without further ado:
figure; %// Create blank figure
hold on; %// Remember all points
%// For each point in our array...
for idx = 1 : 360
%// Find the closest slot between gr and our vector in Step #3
[~,min_idx] = min(abs(gr(idx) - bin_vector));
%// Grab this colour
clr = colour_map(min_idx,:);
%// Plot the point with this colour
plot(cosd(idx), sind(idx), '.', 'Color', clr, 'MarkerSize', 10);
end
Take notice that cosd and sind take in degrees as the input argument while cos and sin take in radians. Also, take note that I also changed the size of the point so that it's bigger. With the above logic, and your array in gr, this is what I get:
If you want the radius to get larger, all you have to do is multiply each cosd and sind term with your radius. Therefore, you can do something like this:
radius = 2;
for idx = 1 : 360
... %// Insert colour code here
...
...
%// Now plot
plot(radius*cosd(idx), radius*sind(idx), '.', 'Color', clr, 'MarkerSize', 10);
end
Just leave the code the same, but for the plot command, just multiply each x and y value by the radius.
Minor note in efficiency
The way you're calculating your gr array is using an inefficient for loop. There are some situations (like mine above) where you need to use a for loop, but for simple computations there is no need. It's better if you vectorize its creation. Therefore, you can get rid of the for loop to calculate your gr array like so:
x = 1 : 360;
Theta = x*pi/180;
Phii = r*w*w*sin(Theta).*sin(Theta);
Vi = -G*M/(r*r);
gr = Vi + Phii;
x is simply a vector going from 1 to 360, and that's done in the first line. Also, Vi is just an array which contains a single value and if you know how operations work between a scalar and an array, you can just do an addition with this single value and it'll add every value in your array by this much. As such, there's no need to create an array for Vi. Also, take a look at how I calculated Phii. I'm using element-by-element operations as Theta is now an array. You want to create an array Phii that takes corresponding values of Theta, and applies that formula to each value in Theta to produce Phii.
Hope this helps. Good luck!