Matlab figure problems: half scatter points, black lines inside a red region - matlab

Consider the following figure in Matlab (matrices here)
load matrices
%Rb, vertices_deg, vertices_comp
close all
patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal
axis([0 1 0 1 0 1])
view(120,30)
hold on
T = delaunayTriangulation(Rb.');
K = convexHull(T);
patch('Faces',K,'Vertices',T.Points,'FaceColor','k','edgecolor','k');
hold on
scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3),100,'o','filled','b')
hold on
patch(vertices_comp(:,1), vertices_comp(:,2) , vertices_comp(:,3),'red')
hold off
xlim([0 1])
ylim([0 1])
zlim([0,1])
box on
set(gca, 'ytick',0:0.2:1,'xtick',0:0.2:1,'ztick',0:0.2:1,'FontSize',13)
I would like to save this figure in a way such that:
within the red region, I do not get the black lines that I can see in the Matlab output
the blu scatter point is a full circle (and not half circle, as it appears in the Matlab output)
I tried two ways of saving the figure
saveas(gcf,'3.jpg')
print(gcf, '3.jpg', '-dpng', '-r300', '-painters')
None of these two gives me what I want. Could you help?
This is what I get with PRINT
This is what I get with SAVEAS
And here a screenshot of the Matlab window

The problem you are seeing is that the patches are plotted at the exact same plane, which causes this render effect. This is called Z-fighting.
An easy fix is to add some small offset to some of the planes that are drawn in front of the others. You can tweak this value till the effect is gone, and the error from the indented place is minimal.
load matrices
close all
patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal
axis([0 1 0 1 0 1])
view(120,30)
hold on
T = delaunayTriangulation(Rb.');
K = convexHull(T);
d_patch = 0.001;
d_z = 0.01;
patch('Faces',K,'Vertices',T.Points + d_patch,'FaceColor','k','edgecolor','k');
patch(vertices_comp(:,1), vertices_comp(:,2) , vertices_comp(:,3)+d_z,'red')
scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3),100,'o','filled','r')
scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3)+2*d_z,100,'o','filled','b')
xlim([0 1])
ylim([0 1])
zlim([0,1])
box on
set(gca, 'ytick',0:0.2:1,'xtick',0:0.2:1,'ztick',0:0.2:1,'FontSize',13)
saveas(gcf,'3saveas.png')
print(gcf, '3print.png', '-dpng', '-r300', '-painters')
You can do the same for the blue dot, which is partially drawn into the plane. Just give it a little offset, and it appears as a full dot again. I plotted the dot in red and blue, so you can see the offset in location.

Related

How to plot point and vectors in Matlab

A = [239920.240412166 1.31193313030682;
243577.444235102 1.38185205485119;
241899.250050298 1.51264147493485;
244659.326936560 1.50845243215867;
239862.361809342 1.50810833389632;
238395.616682194 1.37125000688350;
244558.389789124 1.27212093329482;
244290.890880318 1.35116080948488;
240303.711239396 1.36064181572699;
237464.430450140 1.48857869573721;
244415.381196104 1.51252425335623;
239855.328594799 1.29178640586301;
239304.806448742 1.31075813783171;
244827.243024016 1.32080934043223;
241465.885648910 1.53667019314427;
241139.254464482 1.40424079027764;
242300.037630214 1.27160249886092;
243330.396959248 1.61411410292679;
237530.389940994 1.21846939260826];
B = [0.6 0.18; 0.15 0.46]; % green circles
for i=1:2
plot(A(:,1),A(:,2),'r*');
hold on
plot(B(i,1),B(i,2), '-ko',...
'LineWidth',1,...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',9);
end
When I ploted A and B, I got this:
B(1,1) = 0.6, but it appears in 0 (X-axis). Same with B(2,1) = 0.15
How to correct this?
A logarithmic scale on the xaxis will help with the view
set(gca, 'XScale', 'log')
However, it will lead to the fact, that now the values of A appear to populate one vertical line.
If you cannot live with this, you may want to try a broken x-axis. MATLAB doesn't support this with build-in functions, but there is a solution in the MATLAB file exchange
https://de.mathworks.com/matlabcentral/fileexchange/3683-breakxaxis
Btw: There is no need for the loop in your code. In fact you plot A twice on top of each other. Just
% Plot A and B without loop
plot(A(:,1), A(:,2),'r*')
hold on
plot(B(:,1), B(:,2), '-ko', 'LineWidth', 1, ...
'MarkerFaceColor', [.49 1 .63], 'MarkerSize',9)
% Set x axis to logarithmic scale
set(gca, 'XScale', 'log')
is sufficient to display your plot
Your x-axis goes from 0 to 250000. On that range, 0.6 and 0.15 are practically 0.
If you want you can use logarithmic scale in x-axis using semilogx

How do I customize the picture in matlab legends?

I want to draw a contour plot of a plane and a surface with legends. Plotting two surfaces in the same figure create the same legends. I want to change the resulting ellipses in the legend. Can I draw parallel lines instead of ellipses on the legend chart?
This is a sample source code:
[X,Y] = meshgrid(-3:.1:3);
Z1 = peaks(X,Y);
Z2 = 2*X+3*Y+4;
contour(X,Y,Z1)
colormap jet
shading interp
axis([-3 3 -3 3])
hold on
contour(X,Y,Z2)
legend('surface','plane')
Honestly there's no good way to get an image in front.
There are a few work arounds that I could show you, but you'll have to be specific.
The easiest things are, getting a colorbar or a rectangular box (1 color) infront of text. These are standard options for datatypes/legend entries.
I suggest you start off with giving your surfaces/countours handles.
h1=surf(....);
h2=plot(....);
lgd=legend([h1, h2, ....],[entries']);
For text with white in front you can do
h_separator1 = plot(NaN,NaN,'.','Color',[1 1 1]);
lgd=legend([h_separator1],['text']);
Here's an example you can run that let's you do the things I just said
clear all; % just for ease of quickly plotting this
close all; %closing all figures
myc=[1 1 1; 0 0 0; 1 1 1; 0 0 0; 1 1 1]; %this is want we will use to draw the paralel lines, can be of any color, just replace the zeros, with the respective values of the colors you want, 0 0 0 is black
x = [0 0 0 0]; %making it have 0 area and thus invisible
y = [0 0 0 0];
c = [0 0.33 0.66 1]; %lets you add a colorbar
figure
colormap(myc); %update the figure to use your colormap
hold on
h3 = plot(NaN,NaN,'Color','none'); %blank entry
h4 = plot(NaN,NaN,':'); % entry with dotted line, color "pseudo random"
h1=patch(x,y,'red','EdgeColor','none'); %For a rectangular color entry in legend
h2=patch(x,y,c,'EdgeColor','none'); %lets you add the colorbar, later use to place inside the legend as paralel lines
[lgd,OBJH,OUTH,OUTM]=legend([h1,h3,h2,h4],{'HI your text here','Nothing','paralel lines','line'}); %the lgd handle let's you later modify properties of the legend
hcb=colorbar; %the colorbar can still be modified, to have no number or a different scale, color, etc.
hcm=OBJH(5)
xlim([0 1])
ylim([0 1])
lpos=lgd.Position; % get position legend
lnr=numel(OUTH); %legend entries is useful
lhstp=lpos(4)/(lnr+1); %heigth step
hax=gca;
axpos=hax.Position; %to shift position because the colorbar is placed in the figure and not within the axes in comparison to the legend
% placing at by example 3rd entry
wdentry=0.04; %at the moment trial and error depends on width on legend box which is based on amount of characters and text size.
p1=axpos(1)+lpos(1)+0.01;
p2=lpos(2)+3/2*lhstp;
p3=wdentry;
p4=lhstp-0.01;
hcb.TickLabels=[]; %remove tick labels
hcb.Ticks=[]; %remove ticks
hcb.Color=[1 1 1]; %white border around it to make it "semi-invisible"
hcb.Position=[p1 p2 p3 p4];

MATLAB plotting error arc on cirular rose plot

I used the answer on Plot vector (or arc) onto a rose plot. MATLAB to plot my rose diagram but my plot looks like this:
My code:
circ_plot(BB,'hist',[],20,true,true,'linewidth',2,'color','r')
hold on
plot([0 cos(mean)*a], [0 sin(mean)*a], 'r')
%// Plot error as many shaded triangles that compose a circular wedge
t = linspace(-Var/2+mean,Var/2+mean,100); %// increase "100" if needed
for k = 1:numel(t)-1
h = patch([0 cos(t(k))*a cos(t(k+1))*a 0], ...
[0 sin(t(k))*a sin(t(k+1))*a 0], [.5 0 0], 'edgecolor', 'none');
%// change color [.5 0 0] to something else if desired. Note also alpha
set(h,'Facealpha',.3) %// make transparent
end
%// Place rose on top by rearranging order of axis children
ch = get(gca,'children');
set(gca,'children',[ch(2:end); ch(1)]);
Any ideas how I get my error shaded area do follow the circumference of the circle rather than being a triangle?
Thanks
I don't know why, but today its works fine. I didn't change anything. Thanks for your reply and offer of help. unfortunately due to the sensitive nature of my data I am unable to post.
thanks again.

Rotate and Move an half-circle Matlab

I plot an half-circle and I rotate it with :
t=linspace(0,pi,1000);
x=r*cos(t);
y=r*sin(t);
h=plot(-2+x,y);
rotate(h,[0 0 -1],1,[0.5 3.71 0]);
now, I would like to move/shif the half-circle from the center , such that the half-circle changes position but I want that it maintains also the rotation done.
Who can help me?
To shift for example 10 units in the x direction and 5 in the y direction:
set(h,'XData',get(h,'XData')+10)
set(h,'YData',get(h,'YData')+5)
As you see, it's done by modifying the properties of the h object
Disregard my above comments, you can actually shift data around after it has been plotted. You can modify the XData and YData values as long as you have a handle to the plot that you created
Do something like this
clc; close all; clear all;
t=linspace(0,pi,1000);
r = 5
x=r*cos(t);
y=r*sin(t);
h=plot(-2+x,y);
rotate(h,[0 0 -1],1,[0.5 3.71 0]);
xShift = 5;
yShift = 5;
set(h,'XData',get(h,'XData')+xShift)
set(h,'YData',get(h,'YData')+yShift)
Just an additional answer to demonstrate hgtransform, the others will work well too.
t=linspace(0,pi,1000);
x=r*cos(t);
y=r*sin(t);
h=plot(-2+x,y);
rotate(h,[0 0 -1],1,[0.5 3.71 0]);
hgt=hgtransform('parent',gca);
set(h,'parent',hgt);
Tx = makehgtform('translate',[10 -5 0]); % translate +10 x, -5 y, 0 z
set(hgt,'Matrix',Tx);
drawnow;
You could also potentially use the hgtranform to do the rotation at the same time, but it might take a bit of fiddling around to get the axis origin to work as you have above:
RxTx = makehgtform(xrotate',0.5,'yrotate',3.71,'translate',[10 -5 0]);
set(hgt,'Matrix',RxTx);
drawnow;

How to plot/save only the colorbar in Matlab?

How can I plot only a color bar, e.g. jet from -1 to 1, in Matlab? I need to save it as an image.
Running colorbar also plots an empty axis next to the color bar.
what about this:
colorbar
axis off
EDIT :
If you want to fully control the width and position of the colorbar then you can do something like:
fig1=figure;
left=100; bottom=100 ; width=20 ; height=500;
pos=[left bottom width height];
axis off
colorbar([0.1 0.1 0.7 0.8]);
set(fig1,'OuterPosition',pos)
As MATLAB can only print (= save as an image) figures and colorbar doesn't return a figure handle, one way is to install http://www.mathworks.com/matlabcentral/fileexchange/23629-exportfig, then use:
colormap('jet');
cbar_handle = colorbar;
export_fig(cbar_handle, 'colorbar.png');
colorbar.png:
Inspired by bla, here is an answer with more adjusting possibilities. (Rep<50 means no comments possible. sry!)
fig1=figure;
axis off
colormap(gray(100));
caxis([-1 1]);
h = colorbar([0.1 0.1 0.8 0.7],...
'location','Southoutside',...
'XTick',[-1 -0.5 0 0.5 1]);
set(h,'OuterPosition',[0.1 0.1 0.8 0.8]);