Changing the xticks for x axis in scatterplot - matlab

I'm plotting a scatter plot and would like to have the a-axis as entry named than index. My data is from MASS in R and looks like this
animals={'Mountain beaver';'Cow';'Grey wolf';'Goat';'Guinea pig';'Dipliodocus';'Asian elephant';'Donkey';'Horse';'Potar monkey';'Cat';'Giraffe';'Gorilla';'Human';'African elephant';'Triceratops';'Rhesus monkey';'Kangaroo';'Golden hamster';'Mouse';'Rabbit';'Sheep';'Jaguar';'Chimpanzee';'Rat';'Brachiosaurus';'Mole';'Pig'};
body=[1.35 465 36.33 27.66 1.04 11700 2547 187.1 521 10 3.3 529 207 62 6654 9400 6.8 35 0.12 0.023 2.5 55.5 100 52.16 0.28 87000 0.122 192];
brain=[8.1 423 119.5 115 5.5 50 4603 419 655 115 25.6 680 406 1320 5712 70 179 56 1 0.4 12.1 175 157 440 1.9 154.5 3 180];
% Plot
x=1:length(body);
scatter(x,body,'filled','d')
hold
scatter(x,brain,'filled')
legend('body', 'brain','location','east');
How could I amend the program so my scatterplot display animals in xticks with 45 degrees?

I think this is what you want:
% add these lines at the end of your code
set(gca,'XTickLabel',animals)
set(gca,'XTick',1:numel(animals));
xlim([0 numel(animals)+1]);
set(gca, 'XTickLabelRotation', 45);
which gives this:

Related

How can I plot heatmap of Wi-Fi signal strength in a 2-D surface?

I've my dataset as follows (for instance):
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]
Here, strength is the received signal strength in dBm, X and Y are 2-D coordinates. I want to plot the heatmap of the signal strength at all the coordinate points.
My situation is similar to this question. However, I want to plot the received signal strength and in Matlab, as shown in the attached figure (because of picture quality). A solution in Matlab is found here, however, the code given in the link does not work. The Command Window of Matlab displays HeatMap object with 0 rows and 0 columns. The available code in Matlab is as follows:
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]';
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]';
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]';
strengthPercent = 2*(strength+100)/100;
picture = imread('https://www.mathworks.com/help/examples/thingspeak/win64/CreateHeatmapOverlayImageTSExample_02.png');
[height,width,depth] = size(picture);
OverlayImage=[];
F = scatteredInterpolant(Y, X, strengthPercent,'linear');
for i = 1:height-1
for j = 1:width-1
OverlayImage(i,j) = F(i,j);
end
end
alpha = (~isnan(OverlayImage))*0.6;
imshow(picture);
hold on
OverlayImage = imshow( OverlayImage );
caxis auto
colormap( OverlayImage.Parent, jet );
colorbar( OverlayImage.Parent );
set( OverlayImage, 'AlphaData', alpha );
Any suggestions, please!
Thank you.
You can use scatteredInterpolant as in the code you showed, just pair it with surf
F = scatteredInterpolant(X(:), Y(:), strength(:));
[XD, Yd] = meshgrid( 0:10:410, 0:10:550 );
Zd = F( XD, Yd );
surf( XD, Yd, Zd, 'EdgeColor', 'interp' );
view([0,90]); % view 3D plot from above
You can change the colormap to customise the appearance.
colormap( 'hot' );
colorbar();
You should be able to reduce the FaceAlpha of the surface to lay it over an image.

How to calculate a triangular interpolation from values in coordinates in Matlab?

If I have a matrix with first and second columns related to coordinates and third one related to a value, how could I interpolate third column values creating iscurves and colorbar ranges?
M=[
342854 657145 309
342996 657287 73
343137 657428 84
342006 657145 1122
342147 657287 777
342289 657428 426
342430 657570 638
342571 657711 200
342713 657852 787
341723 657711 1141
341864 657852 555
342006 657994 1157
342147 658135 355
342289 658277 374
341299 658135 467
341440 658277 672
341582 658418 459
341723 658560 735
341864 658701 781
341016 658701 1233
341157 658842 218
341299 658984 539
341370 659054 1351];
and obtain something like the attached image
As your data is not in an uniform grid, you need to use griddata for interpolation.
[xq,yq]=meshgrid(linspace(min(M(:,1)),max(M(:,1)),100),linspace(min(M(:,2)),max(M(:,2)),100));
zq=griddata(M(:,1),M(:,2),M(:,3),xq(:),yq(:),'cubic'); %cubic for smoother results
[c,h]=contourf(xq,yq,reshape(zq,100,100));
clabel(c,h);

How to improve the distance calculation on two separated datasets in matlab?

How to improve the distance calculation on the 2 separated datasets?
This is the code:
X = [ 3.6 79
1.8 54
3.333 74
2.283 62
4.533 85
2.883 55
4.7 88
3.6 85
1.95 51
4.35 85
1.833 54
3.917 84
4.2 78
1.75 47
4.7 83
2.167 52
1.75 62
4.8 84
1.6 52
4.25 79
1.8 51
1.75 47
3.45 78
3.067 69
4.533 74
3.6 83
1.967 55
4.083 76
3.85 78
4.433 79
4.3 73
4.467 77
3.367 66
4.033 80
3.833 74
2.017 52
1.867 48
4.833 80
1.833 59
4.783 90 ]
clc;
close all;
figure;
h(1) = plot(X(:,1),X(:,2),'bx');
hold on;
X1 = X(1:3,:);
X2 = X(4:40,:);
h(2) = plot(X1(1:3,1), X1(1:3,2),'rs','MarkerSize',10);
k=5;
[D2 ind] = sort(squeeze(sqrt(sum(bsxfun(#minus,X2,permute(X1,[3 2 1])).^2,2))))
ind_closest = ind(1:k,:)
x_closest = X(ind_closest,:)
for j = 1:length(x_closest);
h(3) =plot(x_closest(j,1),x_closest(j,2),'ko','MarkerSize',10);
end
The output is shown as in the picture below:
The problem is, the code does not pick the closest data points of red squared data points. I also tried to use pdist2 function from statistical toolbox,the result yields similar with the bsxfun function that i applied in my code.
I'm not sure which part in the code need to improve so that i can pick the data points that closest to the target.
Really appreciate if anyone can help me to improve my code
If the closest point means closest to X, line 19 & line 20 should be replaced as
[D2 ind] = sort(squeeze(sqrt(sum(bsxfun(#minus,X,permute(X1,[3 2 1])).^2,2))))
ind_closest = ind(2:k+1,:)
If the closest point means closest to X2, then try this:
x_closest = X2(ind_closest,:)
In the meanwhile, I modified your code a little bit, since your h(3) could be optimized.
clc; clear; close all;
%load fisheriris
%X=meas(:,3:4);
load X
X=unique(X,'rows');
figure;
h(1) = plot(X(:,1),X(:,2),'bx');
hold on;
X1 = X([5 15 30],:);
h(2) = plot(X1(:,1), X1(:,2),'rs','MarkerSize',10);
[D2,ind] = sort(squeeze(sqrt(sum(bsxfun(#minus,X,permute(X1,[3 2 1])).^2,2))));
k=3;
ind_closest = unique(ind(2:k+1,:));
x_closest = X(ind_closest,:);
h(3) =plot(x_closest(:,1),x_closest(:,2),'ko','MarkerSize',10);
axis equal
It seems to be working fine.

Why doesn't the contourf function in Matlab use the highest value of the plotted data?

does anybody know why the function countourf doesn't use the color corresponding to the maximum value anywhere in the plot area?
if you try the code below, and then the command
get(h_colorbar,'YLim')
Matlab returns an upper limit which is not the highest element of the matrix (500), but a smaller number (475.9091).
As you can see from the commented lines in the code, I was able to change the upper/lower limits of the colorbar, but of course this doesn't solve the problem.
I'd like Matlab to actually use the highest values in my matrix of data; for instance, I'd like to see the point corresponding to (200,300) colored in the darkest red.
Xdata=[7 11 15 19 23 27 31 39 50 75 100 200];
Ydata=[50 100 140 150 200 300];
dataZ=[...
500 500 438 310 269 253 245 238 235 237 241 500 ...
500 414 291 259 248 244 241 239 239 250 274 500 ...
500 335 268 251 246 243 241 240 242 261 308 500 ...
500 323 264 250 245 243 241 241 243 265 319 500 ...
500 289 256 248 244 243 242 243 248 287 500 500 ...
360 264 250 245 244 243 244 247 261 376 500 500 ...
]';
% % % In matrix form
mdataZ=vec2mat(dataZ,length(Xdata));
[mXdata,mYdata]=meshgrid(Xdata,Ydata);
figure_5=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
% % % set(gca,'CLim',[min(dataZ) max(dataZ)])
contourf(mXdata,mYdata,mdataZ,10)
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
% % % set(h_colorbar,'YLim',[200 500],'YTick',[0:50:500])
% % % caxis([200 500])
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)
Any idea?
Thanks in advance!
contourf splits your data into n (10 for your case) levels. Unless you specify the levels they are chosen automatically by the function.
The highest level must be lower than the highest point in your data. Maybe it could be the same, I'm not sure how matlab treats values equal to a contour in this case. But if you leave it to automatic contour levels it will definitely be lower.
The individual data points are not plotted by the function, only the contour heights. Therefore, the value 500 is not in the colormap and the max is the height of the highest contour.
To solve this you can put a vector of contour values rather than n. Put the highest value close or equal to 500.
Following your suggestion, I replaced the line calling the countourf function.
Instead of the number of elements (10), I put linspace(min(dataZ),max(dataZ),10).
Interestingly, the minimum value used by contourf seems always to be the lowest element of the input matrix.
If you're curious, compare the previous code and the following:
new_figure=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
contourf(mXdata,mYdata,mdataZ,linspace(min(dataZ),max(dataZ),10))
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)

plot a stacked bar chart in matlab that shows all the values

Hi I have the following code in Matlab
CC_monthly_thermal_demand = [495 500 500 195 210 100 70 65 85 265 320 430]';
AD_monthly_thermal_generation_250 = [193 193 193 193 193 193 193 193 193 193 193 193]';
figure;
bar(1:12,AD_monthly_thermal_generation_250)
hold on
bar(1:12,CC_monthly_thermal_demand,'r')
set(gca,'XTickLabel',{'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',' Sep', 'Oct', 'Nov',' Dec'},'FontSize',18)
title('Seasonal Anaerobic Digestion (250kWe) Thermal Energy Supply to Demand - 2012','FontSize',22)
ylabel('Thermal Energy (MWhe)')
legend('250 kWth Supply','Thermal Energy Demand')
grid on
axis([0 13 0 600])
I am trying to plot a stacked bar chart that shows the colour of each variable for every bar. However, for the bars where the "AD_monthly_thermal_generation_250" is a lower value than the "CC_monthly_thermal_demand" the "AD_monthly_thermal_generation_250" colour is completely covered by the "CC_monthly_thermal_demand" and so I can't see these values. Is it possible to be able to see them?
Thank you
Combine the inputs together such that each series is a column, then use the option 'stack':
A = [495 500 500 195 210 100 70 65 85 265 320 430]';
B = [193 193 193 193 20 193 193 193 193 193 193 193]';
bar([B,A],'stacked')
EDIT addressing comment:
% Create random data and filler
A = randi(100,10,1);
B = randi(100,10,1);
mxA = max(A);
filler = mxA-A;
% Plot stacked bar chart
h = bar([A,filler,B],'stacked');
% Set the filler to transparent
set(h(2),'Face','none','Edge','none')
% Set y-labels
yticks = linspace(0,max(B),5) + mxA;
set(gca,'Ytick', [linspace(0,mxA,5) yticks(2:end)],'YtickL', [linspace(0,mxA,5) yticks(2:end)-mxA])