How can I plot two polygons in one graph in maple?
I currently have:
display(polygon([[0, 0], [2, 0], [1,1]],
color = red),
scaling = constrained);
But this only plots one polygon, in this case it is a triangle, but i want to have two triangles next to each other?
You could define the polygons first and then display them:
g1 := polygon([[0, 0], [2, 0], [1,1]], color = red);
g2 := polygon([[0, 0], [4, 0], [1,1]], color = blue);
display(g1, g2);
Related
I have the following simple MATLAB code:
figure()
x = [0, 0, 0];
y = [0, 0, 0];
z = [-10, 0, 10];
plot3(x, y, z, 'ro');
xlim([-20 20])
ylim([-20 20])
zlim([-20 20])
xlabel('x-axis')
ylabel('y-axis')
zlabel('z-axis')
With a certain camera view the resulting figure looks like this:
Now I want to know the resulting image coordinates of the three 3D points if I save the axes to an image:
img = frame2im(getframe(gca));
E.g. Point [0 0 -10] corresponds to pixel (x = ?, y = ?) in img
Is there any straightforward way to compute this mapping?
I would like to plot/draw exactly this shape in MATLAB or OCTAVE. Of course I do know how to plot, and how to create rectangles, using either the plot, the line or the rectangle functions. But I have not yet managed to add this "hole" on the top side of the rectangle. I figure, it's a (half-)circle of radius 0.5 and center point (1.5|2). In OCTAVE, there is a drawCircleArc function, but I don't want to only draw that thing, but also to have the necessary coordinates defining the whole shape for further manipulation.
Here is one way (matlab/octave compatible):
% Specify all polygon points, excluding the semi-circle outline
X = [1, 0, 0, 3, 3, 2];
Y = [2, 2, 0, 0, 2, 2];
% Add semi-circle outline to array of polygon points
t = 0 : -0.01 : -pi;
X = [X, 1.5 + 0.5 * cos(t)];
Y = [Y, 2 + 0.5 * sin(t)];
% Use fill to plot the filled polygon, with desired settings
fill( X, Y, [0.8, 0.8, 0.8], 'linewidth', 1.5 );
axis( [-2, 4, -2, 4] ); axis equal;
As of 2017b you can also use polyshapes and boolean operators.
rect = polyshape([0 3 3 0], [0 0 2 2]);
t = linspace(0, 2*pi, 32);
circ = polyshape(1.5+.5*cos(t), 2+.5*sin(t));
subplot 121, hold on
plot(rect)
plot(circ)
axis equal
shape = subtract(rect, circ);
subplot 122
plot(shape)
axis equal
I have two arrays say X and Y with same dimension. I can plot each points (x,y) by plot(X,Y). But how can I color them according to their given labels?
Say X = [3, 4, 2, 5, 6], Y = [2, 2, 1, 5, 6] and label = [1, 2, 2, [1,2], 2]. Here I all have to do is to color points with label=1 with blue and points in label=2 by red. How can I do this?
There are several ways to optimize this code and even get away without using the loop but this should get you started
for i=1:length(X)
xdot=X(i)
ydot=Y(i)
Ldot=label(i)
col=[1 0 0;0 0 1];
plot(xdot,ydot,'color',col(Ldot,:),'marker','o');
hold on
end
I would like to draw four circles of two colors. I'm using circle function to draw a circle. I'm facing problem with legend(). It colors the two data with the same color.
function main
clear all
clc
circle([ 10, 0], 3, 'b')
circle([-10, 0], 3, 'b')
circle([ 10, 10], 3, 'r')
circle([-10, 10], 3, 'r')
% Nested function to draw a circle
function circle(center,radius, color)
axis([-20, 20, -20 20])
hold on;
angle = 0:0.1:2*pi;
grid on
x = center(1) + radius*cos(angle);
y = center(2) + radius*sin(angle);
plot(x,y, color, 'LineWidth', 2);
xlabel('x-axis');
ylabel('y-axis');
title('Est vs Tr')
legend('true','estimated');
end
end
The following picture shows the problem. Both colored as blue instead one of them is red.
Any suggestions?
You can make your function circle() return the plot handles. Store the handles in a vector. In the end, you only call legend() once, after plotting all circles. The first argument in legend are then the function handles which you want to appear in the legend. Something like this:
function main
% clear all % functions have their own workspace, this should always be empty anyway
clc
handles = NaN(1,2);
handles(1,1) = circle([ 10, 0], 3, 'b'); % handle of a blue circle
circle([-10, 0], 3, 'b')
handles(1,2) = circle([ 10, 10], 3, 'r'); % handle of a red circle
circle([-10, 10], 3, 'r')
% Nested function to draw a circle
function h = circle(center,radius, color) % now returns plot handle
axis([-20, 20, -20 20])
hold on;
angle = 0:0.1:2*pi;
grid on
x = center(1) + radius*cos(angle);
y = center(2) + radius*sin(angle);
h = plot(x,y, color, 'LineWidth', 2);
xlabel('x-axis');
ylabel('y-axis');
title('Est vs Tr')
end
% legend outside of the function
legend(handles, 'true','estimated'); % legend for a blue and a red circle handle
end
The result looks like this:
The thing is that you draw 4 things and only have 2 entries in the legend.
As such it will pick the color of the first four things to color the legend.
Not in the opportunity to try it myself now, but I guess that the easiest 'solution' would be to draw your third circle first and then the second one.
circle([ 10, 0], 3, 'b')
circle([ 10, 10], 3, 'r')
circle([-10, 0], 3, 'b')
circle([-10, 10], 3, 'r')
I have to plot 5 lines that overlap in some regions, and I need to be able to see all the lines.
I can think of shifting the lines a bit to allow them to be displayed, but this doesn't seem a very elegante solution. Even so, how could I code such a thing?
Is there any other way to plot multiple overlapping lines while being able to distinguish them at every point?
For exemple, here is one exemple with 3 overlapping lines:
Thank you in advance!
Another way is to use transparency.
Unfortunatelly, line objects do not obey
transparency commands :(
A workaround is to:
1. download patchline (<-- link to Matlab Central)
2. use it to plot patchline with transparency
Once you have patchline, you can try something like:
% create some lines:
l1 = [1, 1, 1, 0, 0, 0.25, 1, 1, 0, 0, 0, 0, 1 1];
l2 = [0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1];
l3 = [1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0];
% plot with patchline (notice the use of 'EdgeAlpha'):
figure;
patchline(1:length(l1), l1, [], 'EdgeColor', [0.8, 0.2, 0.35],...
'LineWidth', 5, 'EdgeAlpha', 0.5 );
hold on;
patchline(1:length(l1), l2, 'EdgeColor', [0.2, 0.7, 0.55],...
'LineWidth', 5, 'EdgeAlpha', 0.5 );
patchline(1:length(l1), l3, 'EdgeColor', [0.1, 0.2, 0.95],...
'LineWidth', 5, 'EdgeAlpha', 0.5);
% change y limits to see line overlap clearly
set(gca, 'YLim', [-0.5, 1.5]);
Not an ideal way to do it - the rough 'cracks' will stay this way,
but you can experiment with different line widths or moving the
lines in y axis by a value that would correspond to an image with each
line covering only half of it closest neighbour...
You may play with EraseMode property of the plot line. The following code example shows how to shift the lines and EraseMode effect:
% First we generate some data
NLines = 2;
NPoints = 50;
LineWidth = 3;
ShiftStep = 1.1;
XData = linspace(0,1,NPoints);
YData = rand(NPoints,NLines);
for k=1:NLines
YData(:,k) = YData(:,k) > (k/(NLines+1));
end
% Then we create plot
figure('color','w');
subplot(3,1,1); plot(XData,YData, 'LineWidth',LineWidth);
ylim([-0.1 1.1]);
title('simple')
subplot(3,1,2); plot(XData,YData+repmat((0:NLines-1)*ShiftStep,NPoints,1), 'LineWidth',LineWidth, 'EraseMode','xor');
ylim([-0.1 1.1+ShiftStep*(NLines-1)]);
title('Shifted vertically')
subplot(3,1,3); plot(XData,YData, 'LineWidth',LineWidth, 'EraseMode','xor');
ylim([-0.1 1.1]);
title('EraseMode = xor')
In my opinion if you have more than three lines similar to your plot, shifting is visually more attractive. Also you may create several axes (Like I did) and plot each line in its own axes, so they will have y-labels set accordingly, but their X-labels will be essentially the same.
You can use plot3 and assign different Z values to different overlapping lines. However, it'll look more like you expect (Z being the "up" direction) if you swap the Y and Z axes:
Example:
Y1 = randn(1,100);
Y2 = randn(1,100);
X = 1:100;
Z1 = 1*ones(size(X));
Z2 = 2*ones(size(X));
plot3(X,Z1,Y1);
hold on;
plot3(X,Z2,Y2);