MATLAB: line specification marker size - matlab

When plotting multiple data series using both line specification (X,Y,linespec) triplets and (PropertyName,PropertyValue) doublets, only a single MarkerSize can be specified and this size applies to all data series. For instance,
plot(X1,Y1,'.b',X2,Y2,'-r','MarkerSize',5)
Is it possible to specify a different MarkerSize for each of the different data series without resorting to plotting the data series separately or subsequently altering plot handle properties? Neither of the following two commands is valid, but they give an idea of the desired result:
plot(X1,Y1,'.b',X2,Y2,'-r','MarkerSize',[5 10])
plot(X1,Y1,'.b','MarkerSize',5,X2,Y2,'-r','MarkerSize',10)

Try:
h = plot(X1,Y1,'.b',X2,Y2,'*r');
set(h(1),'MarkerSize',5);
set(h(2),'MarkerSize',2);

You can use scatter. It has the SizeData property which is a vector.
x = rand(10,1);
y = rand(10,1);
s = scatter(x,y);
set(s,'SizeData',linspace(1,100,10))
If you want to use line plot with markers, you can draw your plot, use hold on, and then draw scatter on top of it.

For that it is probably
plot(x1,0,'+','MarkerSize',10)
Or any other plot within the loop just
plot(x?, 0, '+', 'MarkerSize', 10, 'MarkerEdgeColor', 'r')

Related

How to plot a curved line in MATLAB using a set of points

I'm trying to draw ROC curves using an existing set of values using the following command
plot(X1,Y1,'--rs',X2,Y2,'-*g');
Where X1,Y1,X2 and Y2 are matrices that have the same size
However, the lines produced by this command are straight ones.
How can I make them curved lines.
Thanks
Aziz
MATLAB by default uses straight line approximation to draw your graph in between control points. If you want, you can interpolate in between the points to produce a more realistic graph. Try using interp1 with the 'spline' option and see how that goes. As such, figure out the minimum and maximum values of both X1 and X2, then define a grid of points in between the minimum and maximum that have finer granularity. Once you do this, throw this into interp1 and plot your curve. Something like:
%// Find dynamic range of domain for both Xs
minX1 = min(X1);
maxX1 = max(X1);
minX2 = min(X2);
maxX2 = max(X2);
%// Generate grid of points for both Xs
x1Vals = linspace(minX1, maxX1, 100);
x2Vals = linspace(minX2, maxX2, 100);
%// Interpolate the curves
y1Vals = interp1(X1, Y1, x1Vals, 'spline');
y2Vals = interp1(X2, Y2, x2Vals, 'spline');
%// Plot the results
plot(x1Vals,y1Vals,'--rs',x2Vals,y2Vals,'-*g');
linspace generates a grid of points from one end to another, and I specified 100 of these points. I then use interp1 in the way we talked about where you specify control points (X1,Y1,X2,Y2), then specify the values I want to interpolate with. I use the output values after interpolation and draw the curve.

Plotting points while plotting vectors : Matlab

I need to make a plot with only points and tried something like
plot(x,y)
where x and y are vectors: collection of points.
I do not want matlab to connect these points itself. I want to plot as if plotted with
for loop
plot;hold on;
end
I tried
plot(x,y,'.');
But this gave me too thick points.
I do not want to use forloop because it is time expensive. It takes a lot of time.
You're almost there, just change the MarkerSize property:
plot(x,y,'.','MarkerSize',1)
Try:
plot(x,y,'*');
or
plot(x,y,'+');
You can take a look to the documentation: http://www.mathworks.nl/help/matlab/creating_plots/using-high-level-plotting-functions.html
help scatter
IIRC: where S is the size of the scatter points:
scatter(x,y,S)
You may try this piece of code that avoid using loops. The plot created does not have lines but markers of different colors corresponding to each column of matrices x and y.
%some data (matrix)
x = repmat((2:10)',1,6);
y = bsxfun(#times, x, 1:6);
set(0,'DefaultAxesColorOrder', jet(6)); %set the default matlab color
figure('Color','w');
plot(x,y,'p'); %single call to plot
axis([1 11 0 70]);
box off;
legend(('a':'f')');
This gives

Connecting subplots with lines in matlab

Consider the following example code:
load sumsin;
s = sumsin+10; % example data series
time = linspace(0,5*24,1000);
figure(1);
subplot(311);
plot(time,s,'k');
subplot(312);
plot(time,s,'k');
hold on;
[s_denoised,~, ~] = wden(s,'minimaxi','s','sln',1,'db4');
plot(time,s_denoised,'r');
subplot(313);
plot(time,s,'k');
hold on;
plot(time,s_denoised,'r');
xlim([20 40]);
Resulting in
I would like to alter this plot by inserting lines between subplot 2 and 3 to show that subplot 3 is a portion of subplot2. For example:
How can this be achieved in matlab?
Edit:
I was thinking of something along the lines of generating a invisible axes over the entire figure, obtain the position of each subplot, the location of 20 and 40 will be a certain percentage of the subplot width so I could use the annotation command from here to start a line and then apply the same method to the third subplot to connect the lines with the desired location. I have trying this, but no solution so far.
Just for the sake of the answer, you could use annotation objects to get the effect that you're looking for, as correctly suggested in a comment. Note that their coordinates have to be normalized to the [0, 1] range with respect to the figure window, so it might be quite tedious to adjust them.
This does get the job done, but it's horrible. Don't do it this way.
Example
Since I don't have your original data, I'll draw something of my own (but similar to yours):
t = linspace(0, 120, 1000);
s_denoised = sin(t / 2);
s = s_denoised + 0.2 * randn(size(s_denoised));
subplot(3, 1, 1), plot(t, s, 'k')
subplot(3, 1, 2), plot(t, s, 'k', t, s_denoised, 'r')
subplot(3, 1, 3), plot(t, s, 'k', t, s_denoised, 'r'), xlim([20 40])
Now let's add "annotation" lines like you want:
annotation('doublearrow', [.26 .39], [.38 .38]); %// Top double-arrow line
annotation('doublearrow', [.13 .9], [.34 .34]); %// Bottom double-arrow line
annotation('line', [.325 .325], [.38 .37]); %// Top little connector
annotation('line', [.515 .515], [.35 .34]); %// Bottom little connector
annotation('line', [.325 .515], [.37 .35]); %// Line
Result:
A bit late in the game, but still it can be beneficial to know of these optional tools that are available at the file exchange (FEX):
inset2DAbsolute - creates an axes inset, defined using the larger axes, and corresponding annotations.
On-figure magnifier - is a zooming tool for 2D graphics of images on the same plot. It is composed of two blocks (the secondary axes and the magnifier). The secondary axes, which can be arbitrarily allocated within the limits of the figure, displays the area marked by the magnifier.
Interesting question.
However, from my experience, beautification of graphs and plots can be done more efficiently using graphics software.
I usually use excel + powerpoint for this purpose.
Therefore, my advice (which is not exactly a good answer for your question) is:
export your data to excel, using xlswrite
use excel to create the desired plots.
copy-paste the plots to power point for "hand-crafted" finishing...

Plot data behind 2D plot in Matlab

I have a fairly complex plotting problem that i thought it would be interesting to get a solution to. Say i have two plots, number 1:
This plot was created using plotyy.
And number 2:
This plot was created using plot3(x, y, z, '.')
Now, the complex part is i want to take plot number 2, watermark it and put it behind plot number 1. Which would result in something like this:
Effectively what i want to show is that plot 1 is made from data that looks like plot 2. Now i haven't been able to find how to do this so it may not even be possible, but if it can be done then it would be a great tutorial to have on stack overflow!
You can do this but it will take some work to get the axes formatted so they look nice.
What you need to do is put one axes object on top of another axes; however, to prevent the top axes from occluding the bottom one you need to set the 'Color' property of the top axes object to 'none'.
Here is an example script that generates something similar to what you are looking for
f = figure;
axes();
x = rand(100,3)*3 + 3;
plot3(x(:,1), x(:,2), x(:,3),'.');
axes('Color', 'none');
x = -5:5;
y = x.^2;
line(x,y, 'Color', 'r', 'LineWidth', 2);
Here is the resulting figure:
If you don't like how this works out you can try to project your 3D data into 2D and then draw that projection as an image behind your lines. Here is a link to a discussion about how you might go about creating the 2D projection.

joining dots of a scatter plot and create a line

How is possible to join dots of a scatter plot after plotting, and make a line from a dotted plot?
I'm guessing you generated a scatter plot from x and y coordinates by,
plot(x,y,'.');
Join them with
plot(x,y,'.');
hold on;
plot(x,y,'-');
Or in one command
plot(x,y,'.-');
Is this what you wanted?
If you have an existing plot as a scatter plot, you cannot simply just join the dots without knowing which points are connected to which others.
If you know the order/connectivity of the points, then you could simply have used the plot function to do that in the first place. The call
plot(x,y,'-')
will connect the dots with straight line segments. If you wish to use a marker symbol at each point along the line, then you can add one of the markers that plot allows, as this:
plot(x,y,'o-')
You can get a list of the allowed markers from
help plot
If you have used scatter on a set of points, and now wish to overlay a line connecting the points, then use the hold function to force matlab to plot on top of the scatter plot. For example,
scatter(x,y)
hold on
plot(x,y,'-')
hold off
Again, any of these variations require you to know the connectivity between the points. There are some schemes that can sometimes work to recover that connectivity from a list of isolated points. One of these methods is called CRUST, often used for 3-d surface reconstruction. I found many references by a simple search for "crust algorithm".
If you have a scatterplot (made with the scatter function I suspect) and for some reason don't want to redraw it with plot, here is what you can do to connect the dots:
h = findobj(gca,'type','hggroup');
hold on
for k=1:numel(h)
x = get(h(k),'xdata');
y = get(h(k),'ydata');
plot(x,y,'-')
end
hold off
The dots will be connected by their original order. If you want you can sort the data before plot, for example by x:
[x,ind] = sort(x);
y = y(ind);
To answer the question of how to do this in Maple, you can simply use the PointPlot command from the Statistics package with the style option set to line or pointline. For example:
Statistics:-PointPlot([2, 4, 6, 4], xcoords=[1, 2, 3, 4], style=pointline);
Specifying the option style = pointline shows both the points and a connecting line; style = line shows just the line.