Plotting a graph using matlab - matlab

I'm having problem with plotting a graph using data of a .dat file. Can someone help me out here?
The file is saved as /My Documents/filename.dat and has three columns of numbers representing variables X, Y and Z.
(X is from 45 to 90 with variation of .5
Z is from .4 to .95 with variation of .05
Y is the result of these 2 variables.)
Example: (a part of data in .dat file)
48.000000 -0.000010 0.400000
48.500000 -0.000004 0.400000
49.000000 0.000003 0.400000
49.500000 0.000010 0.400000
50.000000 0.000016 0.400000
I want to plot a 2d graph of X and Y, and color should change according to the Z variable.

Use textscan to read your data:
fid = fopen('/My Documents/filename.dat');
data = textscan(fid, '%f %f %f');
fclose(fid);
X=data{1};
Y=data{2};
Z=data{3};
Plot method #1
Then if you plot with
plot(X,Y)
you'll get an ordinary plot consisting of lines. However these all have the same color. Varying them is not possible unless you split them up in separate lines.
Luckily, there is also the scatter function which allows you to do this:
scatter(X,Y,[],Z)
This plots the points, with color based on Z.
Plot method #2
If you want the points to be connected with lines also having varying color, you'll have to plot them as separate lines, and providing color to each line separately:
plot([X(1:end-1)' ; X(2:end)'], [Y(1:end-1)' ; Y(2:end)']);
The lines now have default coloring, it becomes a bit a hussle to get the right colors in however, next up is an example. Unfortunately I don't now of any way to input the colors also in such a one-liner, so we'll have to loop.
Ncolors=10;
zmin=min(Z);zmax=max(Z);
dz=max((zmax-zmin)/Ncolors,eps);
clr_map=jet(Ncolors);
clr_ids=min(floor((Z(1:end-1)-zmin)/dz)+1,Ncolors);
figure;hold on;
for ii=1:numel(X)-1
plot([X(ii) X(ii+1)], [Y(ii) Y(ii+1)],'color',clr_map(clr_ids(ii),:))
end
All lines now have colors based on one of their end points.
To add a colorbar, use colorbar, weird huh? But of course, the labels of that bar are referring to the colororder. Luckily, we can change them:
colormap(clr_map);
h_cb=colorbar;
set(h_cb,'yticklabel',arrayfun(#num2str,linspace(zmin,zmax,numel(get(h_cb,'ytick'))),'uni',false));
Change Ncolors to use more/less resolution in coloring the lines.
Probably overkill: you can also change the number of labels on the colorbar, the following changes it to 10:
colormap(clr_map);
h_cb=colorbar;
set(h_cb,'ytick',linspace(1,Ncolors,10));
set(h_cb,'yticklabel',arrayfun(#num2str,linspace(zmin,zmax,10),'uni',false));
or now with the labels having only 2 decimals:
set(h_cb,'yticklabel',arrayfun(#(yi) sprintf('%.2g',yi),linspace(zmin,zmax,10),'uni',false));
Plot method #3
Another last method is to use patches (which are slower), which is explained for the 3d case here, so you can get started there if you want.

Related

Best way to plot marks on a line in Matlab

This question is quite basic, but I am looking for the best way to do this.
For a plotted line in matlab, how can a few points on the line be marked. I know it is possible to plot directly using marks. But, in case the line has been plotted and the marks are just to differentiate the plots. Instead of selecting a few points and plotting the second time. An example is shown in this figure below
Right after creating the initial plot you can use the command 'hold on' to keep that plot 'live' and then replot the points as markers. For example:
x=1:10;
y=2*x+4;
plot(x,y)
hold on
plot(x,y,'+')
You can use '*', '.' or any other marker instead of '+'.
If you want the markers to be evenly spaced (and your data is not ,originally) you may create an evenly spaced x vector and then, assuming your plot is not too extreme, interpolate the y values and add just the points. For example:
x=[1,1.5,2,2.3,3,4,4.8,5,6.1,6,7,8,9,10];
y=2*x.^2+4;
plot(x,y)
hold on
x_lin=linspace(min(x),max(x),20);
y_lin=interp1(x,y,x_lin,'linear');
plot(x_lin,y_lin,'+')
hold off
With the following result:
If 'linear' doesn't give a good enough result you can try other interpolation methods like 'cubic', 'spline'...
If you don't want to "add" the marked points in a second moment (but I don't think you will have some advantage), consider to
A) use two plot instructions, separating the array of points "to be marked" using
C = setdiff(A,B)
alternatively
B) plot every point in a for cycle with counter i under a condition
%not tested solution
c1 = '.r' %red point, if they are near they seems a line
c2 = '*b' %blue marker
if (marker_condition == true)
plot(x(i), y(i), c2)
else
plot(x(i), y(i), c1)
end

Matlab legend colors don't match lines

Not sure what is going wrong here. I created a minimal example below:
clear
steps = 1:6;
labels = cell(length(steps),1);
xvals = 1:10;
fig = figure(1);
ax = axes('parent',fig);
hold on
for ii=1:length(steps)
s=steps(ii);
yvals = zeros(length(xvals)) + ii;
labels{ii} = ['gain = ' num2str(s)];
plot(ax,xvals,yvals);
end
legend(ax, labels);
hold off
And the result on my system is:
With less lines it can even put colors in the legend that aren't even on the plot. What is happening?!
Explanation of what's happening
The problem is in the line
yvals = zeros(length(xvals)) + ii;
This creates a 10x10 square matrix, not a 1x10 vector. plot then plots each column of that matrix against xvals. That causes a mixing up of colors which is probably not what you want.
It's interesting to analyze specifically what happens. Matlab plots each column of that matrix with a different color, using the default cycle of colors, which in Matlab R2014b onwards is
But all columns of that matrix are the same, so each covers (overwrites) the preceding one, and you only see the last color.
Now, the color cycle has 7 colors and the matrix has 10 columns. So in the first iteration the last plotted column (the one you see) has color mod(10,7)==3 (yellow). In the second iteration you cycle through 10 more colors starting from 3, that is, you get color mod(3+10,7)==6 (light blue). And so on. Thus the color you see in the figure depends on the loop index ii, but not in the way you expected.
legend creates its entries by picking the color (and line spec) of each plotted line, in the order in which they were plotted. There are 10*6==60 plotted lines, each corresponding to a column of a matrix. But since you only supply six strings to legend, it just picks the first six of those lines, and uses their colors to create the legend entries. Those colors follow the default order, as explained above.
None of those first six lines that make it into the legend are actually seen in the figure, because they are covered by other lines. But legend doesn't care about that. So you get six legend entries with the default color order, which of course doesn't match the lines you actually see in the graph.
Solution
From the above, the solution is clear: replaced the referred line by
yvals = zeros(1, length(xvals)) + ii;
to create yvals as a vector (not a matrix). That way you'll get the figure you expected:

Contour plot using matlab fails

I am trying to make a contour plot using the following matlab code:
x=linspace(-10,10);
y=linspace(-10,10);
[X,Y]=meshgrid(x,y);
Z=X.^3-Y.^3;
figure
[c,h]=contour(X,Y,Z,[3]);
clabel(c,h)
This gives me the wrong picture actually:
I really don't understand what goes wrong here, because when I do [c,h]=contour(X,Y,Z,[3 0]) for example, it does give me the correct contour plots for the levels 3 and 0, I need help.
If you only give a single number to contour there, it interprets it as the number of contour lines you want and picks the levels automatically. From the docs:
contour(Z,v) draws a contour plot of matrix Z with contour lines at the data values specified in the monotonically increasing vector v. To display a single contour line at a particular value, define v as a two-element vector with both elements equal to the desired contour level. For example, to draw contour lines at level k, use contour(Z,[k k]). Specifying the vector v sets the LevelListMode property to manual.
e.g. to get a single contour at "3", you need to do it this way instead:
figure
[c,h]=contour(X,Y,Z,[3,3]);
clabel(c,h)
The fourth argument of contour can be two things.
If it is an array of numbers (more than 1) then its the contour value you want to show. Else, if its a single value, its the amount of contour lines you want to show.
Example:
x=linspace(-10,10);
y=linspace(-10,10);
[X,Y]=meshgrid(x,y);
Z=X.^3-Y.^3;
figure
subplot(121)
[c,h]=contour(X,Y,Z,[10]);
clabel(c,h)
subplot(122)
[c,h]=contour(X,Y,Z,[1000 -1000 50 -70 3 0]);
clabel(c,h)

plotting a text file with 4 columns in matlab

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

Format each line in plot(x,y) where x is a matrix

I wish to format each line in a plot so that I can choose given colours for each line. However my x values are in matrix form so I cannot use the plot(x,y,'b',x,y,'r',...) style format. Many thanks.
I would recommend doing in a for loop, but maybe there is another way of doing it.
Define your colors in a matrix
cmap = hsv(10) %generate 10 random colors
hold on
for ii=1:10
plot(x(ii,:),y(ii,:),'color',cmap(ii,:))
end
Create cmap, as you wish. It needs to be a nlines X 3 size though.
If you don't need to choose colors as long as they are different, you can plot(transpose(data)) which will plot every line of data with a different color.