matlab plot different colors for different change - matlab

In https://www.amcharts.com/demos/line-different-colors-ups-downs/,
it describes plotting different colors for up and downs. How can I do the same for matlab? I attach an example
plot([1 2 3 4 5 6 7 8 9 10], [5 5 7 5 2 5 5 8 9 2])
which involves no change as well. I want to have yellow for ups and blue for downs, and red for no change.

In the figure two different colors are chosen. You may follow something like this:
x = [1 2 3 4 5 6 7 8 9 10] ;
y = [5 5 7 5 2 5 5 8 9 2] ;
figure
hold on
for i = 1:length(x)-1
m = (y(i)-y(i+1))/(x(i)-x(i+1)) ;
if sign(m)==0
plot(x(i:i+1),y(i:i+1),'r') ;
elseif sign(m)==-1
plot(x(i:i+1),y(i:i+1),'b') ;
elseif sign(m)==1
plot(x(i:i+1),y(i:i+1),'y') ;
end
end

Related

Extend the borders of a matrix and replicate the border elements in MATLAB

I am given the following matrix B:
B =
1 4 7
2 5 8
3 6 9
I would like to pad this matrix so that there is a 1 element border that surrounds it with the border elements replicated. Essentially, I would like this result:
B =
1 1 4 7 7
1 1 4 7 7
2 2 5 8 8
3 3 6 9 9
3 3 6 9 9
How can I do this in MATLAB?
If you have the Image Processing Toolbox, use padarray, specifically the replicate flag. If you don't have it, there's an implementation that someone made here on Github: https://github.com/gpeyre/matlab-toolboxes/blob/master/toolbox_nlmeans/toolbox/ordfilt2/padarray.m . You can download it and use the function for your own use.
padarray creates a larger matrix with the source matrix centred within this larger matrix. You have several options on what you can do with the extra border elements. The default behaviour is to set these equal to 0. However, we can specify the replicate flag, which copies values along the original border of the matrix and places them along the extra border elements with this new matrix. Because you want to go from 3 x 3 to 5 x 5, you just need a 1 element border along both dimensions. You specify this with the second parameter to padarray. The replicate flag is the third parameter:
>> B = reshape(1:9, 3, 3);
>> B2 = padarray(B, [1 1], 'replicate')
B2 =
1 1 4 7 7
1 1 4 7 7
2 2 5 8 8
3 3 6 9 9
3 3 6 9 9
Edit
If you don't want to use padarray, you can use the scatteredInterpolant class instead, with nearest as the interpolation flag. You would build a 3 x 3 2D spatial grid of coordinates that map to each value in B, then we'd specify a 5 x 5 spatial grid of coordinates where the border elements are outside of the range of the original 3 x 3 grid. Something like this:
>> [X,Y] = meshgrid(1:3,1:3);
>> [X2,Y2] = meshgrid(0:4,0:4);
>> F = scatteredInterpolant(X(:),Y(:),B(:),'nearest');
>> B2 = F(X2, Y2)
B2 =
1 1 4 7 7
1 1 4 7 7
2 2 5 8 8
3 3 6 9 9
3 3 6 9 9
The question was explicitly to add a single element as border, so try this (no toolbox needed):
B = [1 4 7; 2 5 8; 3 6 9] % or use B=rand(3,4), etc. to try something else.
B2 = B([1 1:end end],[1 1:end end])
This is the result (as desired):
B =
1 4 7
2 5 8
3 6 9
B2 =
1 1 4 7 7
1 1 4 7 7
2 2 5 8 8
3 3 6 9 9
3 3 6 9 9

Quiver from a single matrix

I have a matrix (In Matlab) which I need to plot with a quiver plot but I don't know how to turn it into a "quiver plot-able form". Are there any commands to change it? I saw some example on MathWorks Homepage using the peaks function but I couldn't get it to work.
The matrix I have is pretty huge with lots of NaN's so I created an smaller version of it.
Temperature = [ 1 2 2 2 3 4 6 7 ;
1 2 3 4 4 5 6 7 ;
2 3 4 NaN NaN 6 8 9 ;
3 4 5 NaN NaN 7 8 9 ;
4 4 6 6 7 8 10 11;
4 5 7 7 8 9 11 12];
contour(Temperature)
%quiver(Temperature)
In the comments you find the example code from the documentation which I used. Besides knowing that the dimensions are ordered [Y,X,Z] to get a matching meshgrid it's mostly copy&paste
% figure
figure
% [X,Y] = meshgrid(-2:.2:2);
Temperature = [ 1 2 2 2 3 4 6 7 ;
1 2 3 4 4 5 6 7 ;
2 3 4 NaN NaN 6 8 9 ;
3 4 5 NaN NaN 7 8 9 ;
4 4 6 6 7 8 10 11;
4 5 7 7 8 9 11 12];
[X,Y] = meshgrid(1:size(Temperature,2),1:size(Temperature,1));
% Z = X.*exp(-X.^2 - Y.^2);
Z=Temperature;
% [DX,DY] = gradient(Z,.2,.2);
[DX,DY] = gradient(Z,1,1);
% contour(X,Y,Z)
contour(X,Y,Z)
% hold on
hold on
% quiver(X,Y,DX,DY)
quiverscaling=3;
quiver(X,Y,DX,DY,quiverscaling)
% colormap hsv
colormap hsv
% hold off
hold off

plot two histograms (using the same y-axis) and a line plot (using a different y-axis) on the same figure

How can I plot two histograms (using the same y-axis) and a line plot (using a different y-axis) on the same figure? I am using Matlab 2014b. I am aware of this but it seems to only work for bar plots?
This is my histogram code:
A = [1 2 2 2 3 4 5 5 5 5 5 5 5 5 5 6 6 6 7 7];
B = [6 6 6 7 7 7 7 7 7 7 8 8 8 9 9 10 10];
hist(A,7);
hold on
hist(B,7);
h = findobj(gca,'Type','patch');
set(h(1),'FaceColor','b','EdgeColor','b','facealpha',0.2)
set(h(2),'FaceColor','r','EdgeColor','r','facealpha',0.2)
xlabel('Day','fontsize',14)
ylabel('Frequency','fontsize',14)
xlim([1 10])
Now say I have these data:
Day = [1 2 3 4 5 6 7 8 9 10];
Prevalence = [3 2 4 8 5 6 7 8 9 5];
I want to plot these data (plot(Day,Prevalence)) using the right y-axis.
Thanks.
I think this workaround will do what you want.
Basically create a new axes at the same position than the one in which the histograms are plot, however set its color property to 'none' and the YAxisLocation to the right. You can then assign the new axes the properties you want.
Code:
clear
clc
%// ====================
%// Your code
A = [1 2 2 2 3 4 5 5 5 5 5 5 5 5 5 6 6 6 7 7];
B = [6 6 6 7 7 7 7 7 7 7 8 8 8 9 9 10 10];
hist(A,7);
hold on
hist(B,7);
h = findobj(gca,'Type','patch');
set(h(1),'FaceColor','b','EdgeColor','b','facealpha',0.2)
set(h(2),'FaceColor','r','EdgeColor','r','facealpha',0.2)
xlabel('Day','fontsize',14)
ylabel('Frequency','fontsize',14)
xlim([1 10])
%// ====================
Day = [1 2 3 4 5 6 7 8 9 10];
Prevalence = [3 2 4 8 5 6 7 8 9 5];
%// Get the current axes position to place the new one.
AxesPos = get(gca,'Position');
hold on
hax2 = axes('Position',AxesPos);
%// Plot the data
plot(Day,Prevalence,'--k','LineWidth',4,'Parent',hax2)
%// Set properties of the axes.
set(hax2,'Color','none','YAxisLocation','right','XTick',[],'XTickLabel','','YLim',[0 15])
ylabel('Prevalence','FontSize',16)
%// Rotate the label to correct orientation
LabelPos = get(get(hax2,'YLabel'),'Position');
set(get(hax2,'YLabel'),'Position',[LabelPos(1)+.2 LabelPos(2) LabelPos(3)],'Rotation',-90)
Output:
Note that it's far from perfect ...for example the left border of the first axes is not visible...that could be fixed by playing around with the position of the new axes. Hopefully it does the job for you!

Markertype of scatter points in Matlab based on condition

Suppose I have the following data:
xData = [4 7 2 1 2 8 7 1 1 3];
yData = [1 2 3 4 5 6 7 8 9 10];
P = [5 10 4 2 7 3 8 1 9 3];
I want to use a different markertype based on P. If the corresponding element in P<5 then 'o' and if P>5 then '^'. I know how to do this based on colour (although I don't actually know how to specify what colours to use?) but can this be done with markertype?
scatter(xData,yData,70,P>5)
Any ideas? Thanks!
You will need to do 2 scatter plots with less and more:
xData = [4 7 2 1 2 8 7 1 1 3];
yData = [1 2 3 4 5 6 7 8 9 10];
P = [5 10 4 2 7 3 8 1 9 3];
x_less = xData(P < 5);
x_more = xData(P >= 5);
y_less = yData(P < 5);
y_more = yData(P >= 5);
figure;
scatter(x_less, y_less, 20, 'r', 'o')
hold on
scatter(x_more, y_more, 20, 'b', '^')
This will give you an example like this:
Hope this helps.

Plot 3d surface plot in matlab/freemat

I would like to ask about 3d surface plotting. As I am new to it, I was just trying out. Basically, I have 3 parameters, x, y ,z which I have the values from experimental datas and I would like to plot them out. As such, i tried,
x= [6 7 8 9 10 11 12 1]
x =
6 7 8 9 10 11 12 1
--> y=[2 3 4 5 6 1 6 8]
y =
2 3 4 5 6 1 6 8
--> z= [3 4 5 6 7 8 9 10]
z =
3 4 5 6 7 8 9 10
meshgrid(x,y,z)
surf(x,y,z)
The plot window did come out but there was no graph. Is my method wrong?
Thanks!
It sounds like you need to start with plot3, as you're just describing a set of points in 3D, rather than points on a mesh or surface. See if that does what you want.
x = [6 7 8 9 10 11 12 1];
y = [2 3 4 5 6 1 6 8];
z = [3 4 5 6 7 8 9 10];
plot3(x, y, z, '.');
This is how I would plot a surface :
%define the data
x=[6 7 8 9 10 11 12 1 6 7 8 9 10 11 12 1];
y=[2 3 4 5 6 1 6 8 2 3 4 5 6 1 6 8];
z=[3 4 5 6 7 8 9 10 3 4 5 6 7 8 9 10];
%Create 3D surface
[X,Y]=meshgrid(x,y);
Z=griddata(x,y,z,X,Y);
%Plot the surface
surface(X,Y,Z);
shading interp %makes it look sexy
%xlim([])
%ylim([])
Sometimes I use axis limets to make the plot look nicer (eliminates the unneeded white area's); for this set of data I could use xlim([6 11]) and ylim([2 6]).