I want to do a classification on RGB image using sparse recovery and for now, I want to create some dummy random samples. Thus, I have found the following code and since I am very new in the octave I do not understand the code properly.
Would be nice if someone can give a command for the sections after reshaping the image.
here is the code:
A = imread('demo2.jpg');
B = (A(301:800, 1:400,:));
figure(1)
image(B); axis on; axis equal
%3dim plot
D1 = B(1:50,1:50,:);
D2 = B(1:50,151:200,:);
D3 = B(151:200,351:400,:);
figure(2); %Pflanze
image(D1); axis on; axis equal
figure(3); %Haar
image(D2); axis off; axis equal
figure(4); %Haut
image(D3); axis off; axis equal
%sampling at random N per class
N = 50;
idx2d_D1 = ceil(rand(N,2)*50);
idx2d_D2 = ceil(rand(N,2)*50);
idx2d_D3 = ceil(rand(N,2)*50);
test_vec_D1 = zeros(N,3);
for k=1:N
test_vec_D1(k,1) = D1(idx2d_D1(k,1),idx2d_D1(k,2),1);
test_vec_D1(k,2) = D1(idx2d_D1(k,1),idx2d_D1(k,2),2);
test_vec_D1(k,3) = D1(idx2d_D1(k,1),idx2d_D1(k,2),3);
end
test_vec_D2 = zeros(N,3);
for k=1:N
test_vec_D2(k,1) = D2(idx2d_D2(k,1),idx2d_D2(k,2),1);
test_vec_D2(k,2) = D2(idx2d_D2(k,1),idx2d_D2(k,2),2);
test_vec_D2(k,3) = D2(idx2d_D2(k,1),idx2d_D2(k,2),3);
end
test_vec_D3 = zeros(N,3);
for k=1:N
test_vec_D3(k,1) = D3(idx2d_D3(k,1),idx2d_D3(k,2),1);
test_vec_D3(k,2) = D3(idx2d_D3(k,1),idx2d_D3(k,2),2);
test_vec_D3(k,3) = D3(idx2d_D3(k,1),idx2d_D3(k,2),3);
end
figure(5)
%pointset
X1 = [test_vec_D1'];
X2 = [test_vec_D2'];
X3 = [test_vec_D3'];
plot3(X1(1,:), X1(2,:), X1(3,:),'bo'); axis on; grid on; hold on
plot3(X2(1,:), X2(2,:), X2(3,:),'go');
plot3(X3(1,:), X3(2,:), X3(3,:),'ro'); hold off;
title('blau-Pflanze, grün-Haar, rot-Haut')
I made a drawing of the process and finally understood how does this code work.
Related
I'm using three axes-Objects to scale my data on the x-axis.
My problem is that i do not know how to get a nice legend for the three plots.
I have to do this cause my real data is sampled with different sample rates.
I edited my m-file for the diagram slightly cause normally I'm reading the data out of some txt files.
In this example i used example_data 1 to 3 for my data.
In this example I'm scaling the example_data1 so it looks like the same frequency as example_data2.
I do the 'scaling' ax1.XLim = [0 length(x2)].
That's why this solution doesn't work for me: Plot with multiple axes but only one legend.
It uses set(l3,'Parent',ax2); which somehow ruins my approache to scale my data. The scaling is the only solution to my problem cause i don't know the exact relation between the two sampling rates.
my code:
example_data1 = repmat(1:100,1,10);
example_data2 = 2 * repmat(1:0.5:100.5,1,5);
example_data3 = [1:500 500:-1:1];
whole_length_data1 = length(example_data1);
% 1. step
start_of_data = 1;
end_of_data = 1000;
% data2
y2 = example_data2(start_of_data:end_of_data);
x2 = 0:length(y2)-1;
% data3
y3 = example_data3(start_of_data:end_of_data);
x3 = 0:length(y3)-1;
% data1
y1 = example_data1(1:length(example_data1));
x1 = 0:length(y1)-1;
% 2. step
start_one = 1;
y1 = example_data1(start_one:length(example_data1));
x1 = 0:length(y1)-1;
% 3.step
end_one = whole_length_data1 - 500;
y1 = example_data1(start_one:end_one);
x1 = 0:length(y1)-1;
Farbe1 = [0,1,0]*0.6; % Dunkelgrün
Farbe2 = [1,0,0]*0.8; % Dunkelrot
Farbe3 = get(groot,'DefaultAxesColorOrder') % default values
Farbe3 = Farbe3(1,:); % 1. Zeile der defaultvalues
figure(1)
% 3 axes
clf
%------------------------------------------------------------------
%-------------------------- plot1: ---------------------------
%------------------------------------------------------------------
plot(x2,y2,'green','LineWidth',2,'Color',Farbe1,...
'DisplayName','name of the first plot')
ax1 = gca;
ax1.XLim = [0 length(x2)]
ax1.YLim = [min(y2) max(y2)]
ax1.YTick = [0:25:300]
ax1.FontSize = 12;
legend('show')
%----------------------------------------------------------------
%-------------------------- plot2: --------------------------
%----------------------------------------------------------------
ax2 = axes('Position',ax1.Position);
plot(x3,y3,'blue','LineWidth',2,'Color',Farbe3,...
'DisplayName','plot2')
ax2.Color = 'none';
ax2.XTick = [];
ax2.XLim = [0 length(x3)];
ax2.YAxisLocation = 'right';
ax2.FontSize = 12;
legend('show')
%----------------------------------------------------------------
%-------------------------- plot3: -------------------------
%----------------------------------------------------------------
ax3 = axes('Position',ax1.Position);
plot(x1,y1,'red','LineWidth',2,'Color',Farbe2,...
'DisplayName','3')
ax3.XTick = [];
ax3.YTick = [];
ax3.Color = 'none';
ax3.XAxisLocation = 'top';
ax3.YAxisLocation = 'right';
ax3.XLim = [0 length(x1)];
ax3.YLim = [min(y1) max(y1)*2];
legend('show')
This results in a very bad looking legend:
I really hope somebody can help me.
Thank very much.
You can get better results by storing handles for each of your plot lines, then passing those to a single legend call:
...
h1 = plot(x2,y2,'green','LineWidth',2,'Color',Farbe1,...
'DisplayName','name of the first plot');
...
h2 = plot(x3,y3,'blue','LineWidth',2,'Color',Farbe3,...
'DisplayName','plot2');
...
h3 = plot(x1,y1,'red','LineWidth',2,'Color',Farbe2,...
'DisplayName','3');
...
hl = legend(ax3, [h1 h2 h3]); % Place legend in top-most axes
And here's the result:
Just use the real timestamps as x values:
fig = figure;
plot(x1/length(y1)*end_of_data, y1, 'LineWidth',2, 'Color',Farbe1, 'DisplayName','First plot')
hold on
plot(x2/length(y2)*end_of_data, y2, 'LineWidth',2, 'Color',Farbe2, 'DisplayName','Second plot')
plot(x3/length(y3)*end_of_data, y3, 'LineWidth',2, 'Color',Farbe3, 'DisplayName','Third plot')
legend
I have the following plot:
As you can see, the plot has some data on the left (blue) and on the right (red). However, I want them to be closer together. For example by cutting the box area, because there is no data, such that the 'red area' is more shifted to the left (and thus closer to the 'blue area').
How to proceed further?
MWE:
x = 0:0.05:1.3
y = x;
plot(x,y,'color','k','Linewidth',1);
hold on;
x1 = [0.1:0.05:x(end)];
y1 = [0:0.05:y(end)-0.1];
plot(x1,y1,'--k','Linewidth',1);
x2 = [0:0.05:x(end)];
y2 = [0.10:0.05:y(end)+0.1];
plot(x2,y2,'--k','Linewidth',1);
xlim([0 x(end)]);
ylim([0 y(end)]);
hold on
for i = 1:9;
a = plot(P(i).mHlfA1,P(i).sHlfA1, 'bx');
hold on
b = plot(P(i).mHlfA1,P(i).sLFA1, 'bo');
hold on
c = plot(P(i).mHlfA2,P(i).sHlfA2, 'rd');
hold on
d = plot(P(i).mHlfA2,P(i).sLFA2, 'r*');
hold on;
end
Here is an alternative tweak (to that suggested in the comments), using the XtickLable:
x = [1:10 200:2:230];
y = 3.*x-9;
% define the parts of he x-axis:
xgap = 11;
% pasting together the two parts:
new_x = [x(1:xgap-1) x(xgap-1)+(x(xgap:end)-x(xgap))+(x(xgap+2)-x(xgap+1))];
ax = axes;
plot(ax,new_x,y,'o');
% get the ticks to change:
left_x_tick = ax.XTick(ax.XTick<=x(xgap-1));
right_x_tick = ax.XTick(ax.XTick>x(xgap-1));
slash = left_x_tick(end)+floor((right_x_tick(1)-left_x_tick(end))/2);
ax.XTick = [left_x_tick slash right_x_tick];
% get the spacing between ticks
inc = right_x_tick - min(right_x_tick);
% create new tick labels:
new_tick = cellstr(num2str(inc.' + min(x(xgap:end))+(right_x_tick(1)-new_x(xgap))));
% replace the tick labels in the plot
ax.XTickLabel(ax.XTick>new_x(xgap)) = new_tick;
% put a // where there is a gap:
slash_loc = find(ax.XTick==slash,1,'first');
ax.XTickLabel(slash_loc) = {'//'};
ax.FontSize = 14;
This is before:
and after:
This is just an idea for workaround, it could be further adjusted to the specific needs.
I'm doing Gaussian processes and I calculated a regression per year from a given matrix where each row represents a year , so the code is:
M1 = MainMatrix; %This is the given Matrix
ker =#(x,y) exp(-1013*(x-y)'*(x-y));
[ns, ms] = size(M1);
for N = 1:ns
x = M1(N,:);
C = zeros(ms,ms);
for i = 1:ms
for j = 1:ms
C(i,j)= ker(x(i),x(j));
end
end
u = randn(ms,1);
[A,S, B] = svd(C);
z = A*sqrt(S)*u; % z = A S^.5 u
And I wanna plotting each regression in a Graph 3D as the below:
I know that plot is a ribbon, but I have not idea how can I do that
The desired plot can be generated without the use of ribbon. Just use a surf-plot for all the prices and a fill3-plot for the plane at z=0. The boundaries of the plane are calculated from the actual limits of the figure. Therefore we need to set the limits before plotting the plane. Then just some adjustments are needed to generate almost the same appearance.
Here is the code:
% generate some data
days = (1:100)';
price = days*[0.18,-0.08,0.07,-0.10,0.12,-0.08,0.05];
price = price + 0.5*randn(size(price));
years = 2002+(1:size(price,2));
% prepare plot
width = 0.6;
X = ones(size(price,1),1)*0.5;
X = [-X,X]*width;
figure; hold on;
% plot all 'ribbons'
for i = 1:size(price,2)
h = surf([days,days],X+years(i),[price(:,i),price(:,i)]);
set(h,'MeshStyle','column');
end
% set axis limits
set(gca,'ZLim',[-20,20]);
% plot plane at z=0
limx = get(gca,'XLim');
limy = get(gca,'YLim');
fill3(reshape([limx;limx],1,[]),[flip(limy),limy],zeros(1,4),'g','FaceAlpha',0.2)
% set labels
xlabel('Day of trading')
ylabel('Year')
zlabel('Normalized Price')
% tweak appearance
set(gca,'YTick',years);
set(gca,'YDir','reverse');
view([-38,50])
colormap jet;
grid on;
%box on;
This is the result:
That's a ribbon plot with an additional surface at y=0 which can be drawn with fill3
I am currently working on a project simulating the movement of two spacecraft and a moon (Phobos) around Mars. A MATLAB tool called SPICE gives me an array with the x, y and z distances and I have used these to plot the orbit which works fine. Now I want to get markers for each of the spacecraft and Phobos to see when they flyby each other. I got the markers working but not at the same time, they run after each other. I found an example on youtube so it must be possible but he has not released the code how to do it (https://www.youtube.com/watch?v=nArR2P0o4r4).
This is the code I have:
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans = makehgtform('translate',[x(i) y(i) z(i)]);
set(ht,'Matrix',trans);
pause(0.001);
end
This will run a nice animated plot of the trajectory of Phobos in time but only Phobos and not simultaneous with MEX and MAVEN (spacecraft from ESA and NASA).
I tried this but does not work:
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans1 = makehgtform('translate',[x(i) y(i) z(i)]);
set(ht,'Matrix',trans1);
trans2 = makehgtform('translate',[a(i) b(i) c(i)]);
set(ht,'Matrix',trans2);
pause(0.001);
end
I also tried merging the arrays so that it plots them each one step after each other but that makes the animation not smooth and is not satisfying for the project.
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
tempx = [position_MEX_Mars(1,:); position_Phobos_Mars(1,:); position_MAVEN_Mars(1,:)];
xt = tempx(:);
tempy = [position_MEX_Mars(2,:); position_Phobos_Mars(2,:); position_MAVEN_Mars(2,:)];
yt = tempy(:);
tempz = [position_MEX_Mars(3,:); position_Phobos_Mars(3,:); position_MAVEN_Mars(3,:)];
zt = tempz(:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans = makehgtform('translate',[xt(i) yt(i) zt(i)]);
set(ht,'Matrix',trans);
pause(0.001);
end
I think I am close but I seem to be missing something and my knowledge of MATLAB is not that great yet. I hope you can help me out.
Cheers Jeroen
Here's a simplified (and not physically correct) example that could perhaps be useful:
t = linspace(0,2,1000); %// time parameter
x1 = 10*cos(2*pi*t+1);
y1 = 5*sin(2*pi*t+1); %// trajectory of object 1
x2 = 2*cos(6*pi*t-2);
y2 = 3*sin(6*pi*t-2); %// trajectory of object 1
plot(x1,y1,'color',[.5 .5 .5]); %// plot trajectory of object 1
hold on
plot(x2,y2,'color',[.5 .5 .5]); %// plot trajectory of object 2
h1 = plot(x1(1),y1(1),'ro'); %// plot initial position of object 1
h2 = plot(x2(1),y2(1),'b*'); %// plot initial position of object 2
axis([-12 12 -12 12]) %// freeze axis size
grid on
for n = 1:numel(t)
set(h1, 'XData', x1(n), 'YData', y1(n)); %// update position of object 2
set(h2, 'XData', x2(n), 'YData', y2(n)); %// update position of object 2
drawnow %// refresh figure
end
The thing that you tries to do is not really as easy as you think. The main issue is that you need to update everything at the same time. This have been implemented in several ways during the years. One way to do this is by using a so called a double buffer.
This means that you have two "surfaces" to paint on. In matlab this is translated to 2 axes (or 2 figures maybe). However, you do only have one axes visible at the same time. This means that you will have time to paint everything on the "hidden surface" before displaying the content. When you are done with everything you need you just switch which surface being visible.
It is possible that this can be done in a simpler way, but I am not familiar with the hgtransfrom functions in matlab.
EDIT
This is an example how it can be done
function test()
fig = figure;
ax1 = axes;
plot(1:10);
ax2 = axes;
plot(1:10,'r');
setVisibility(ax2,'off');
pause(1);
for k = 1:5
setVisibility(ax2,'on');
setVisibility(ax1,'off');
pause(1);
setVisibility(ax1,'on');
setVisibility(ax2,'off');
pause(1);
end
function setVisibility(ax, visibility)
set(ax, 'visible', visibility)
set(findall(ax), 'visible', visibility)
This is a continuation from the question already posted here. I used the method that #Andrey suggested. But there seems to be a limitation. the set(handle, 'XData', x) command seems to work as long as x is a vector. what if x is a matrix?
Let me explain with an example.
Say we want to draw 3 rectangles whose vertices are given by the matrices x_vals (5,3 matrix) and y_vals (5,3 matrix). The command that will be used to plot is simply plot(x,y).
Now, we want to update the above plot. This time we want to draw 4 rectangles. whose vertices are present in the matrices x_new(5,4 matrix) and y_new (5,4 matrix) that we obtain after some calculations. Now using the command set(handle, 'XData', x, 'YData', y) after updating x and y with new values results in an error that states
Error using set
Value must be a column or row vector
Any way to solve this problem?
function [] = visualizeXYZ_struct_v3(super_struct, start_frame, end_frame)
% create first instance
no_objs = length(super_struct(1).result);
x = zeros(1,3000);
y = zeros(1,3000);
box_x = zeros(5, no_objs);
box_y = zeros(5, no_objs);
fp = 1;
% cascade values across structures in a frame so it can be plot at once;
for i = 1:1:no_objs
XYZ = super_struct(1).result(i).point_xyz;
[r,~] = size(XYZ);
x(fp:fp+r-1) = XYZ(:,1);
y(fp:fp+r-1) = XYZ(:,2);
% z(fp:fp+r-1) = xyz):,3);
fp = fp + r;
c = super_struct(1).result(i).box;
box_x(:,i) = c(:,1);
box_y(:,i) = c(:,2);
end
x(fp:end) = [];
y(fp:end) = [];
fig = figure('position', [50 50 1280 720]);
hScatter = scatter(x,y,1);
hold all
hPlot = plot(box_x,box_y,'r');
axis([-10000, 10000, -10000, 10000])
xlabel('X axis');
ylabel('Y axis');
hold off
grid off
title('Filtered Frame');
tic
for num = start_frame:1:end_frame
no_objs = length(super_struct(num).result);
x = zeros(1,3000);
y = zeros(1,3000);
box_x = zeros(5, no_objs);
box_y = zeros(5, no_objs);
fp = 1;
% cascade values accross structures in a frame so it can be plot at once;
for i = 1:1:no_objs
XYZ = super_struct(num).result(i).point_xyz;
[r,~] = size(XYZ);
x(fp:fp+r-1) = XYZ(:,1);
y(fp:fp+r-1) = XYZ(:,2);
fp = fp + r;
c = super_struct(num).result(i).box;
box_x(:,i) = c(:,1);
box_y(:,i) = c(:,2);
end
x(fp:end) = [];
y(fp:end) = [];
set(hScatter, 'XData', x, 'YData', y);
set(hPlot, 'XData', box_x, 'YData', box_y); % This is where the error occurs
end
toc
end
Each line on the plot has its own XData and YData properties, and each can be set to a vector individually. See the reference. I am not at a Matlab console right now, but as I recall...
kidnum = 1
h_axis = gca % current axis - lines are children of the axis
kids = get(h_axis,'Children')
for kid = kids
kid_type = get(kid,'type')
if kid_type == 'line'
set(kid,'XData',x_new(:,kidnum))
set(kid,'YData',y_new(:,kidnum))
kidnum = kidnum+1
end
end
Hope that helps! See also the overall reference to graphics objects and properties.
To add a series, say
hold on % so each "plot" won't touch the lines that are already there
plot(x_new(:,end), y_new(:,end)) % or whatever parameters you want to plot
After that, the new series will be a child of h_axis and can be modified.