How to draw a jagged line? - matlab

How can you draw a jagged line in matlab? The graph will be like a saw, the slope is same but peaks are different.
For example:
Peak # Start End
1 (0.2,2.2) (1.5,0)
2 (1.5,3) (3.27,0)
3 (3.27,1.2) (3.98,0)
etc.

Just use plot with the x and y coordinates of your points:
x = [0.2 1.5 1.5 3.27 3.27 3.98];
y = [2.2 0 3 0 1.2 0];
plot(x, y)
Unless you don't want the vertical lines? You can do it like this:
x = [0.2 1.5 nan 1.5 3.27 nan 3.27 3.98];
y = [2.2 0 nan 3 0 nan 1.2 0];
plot(x, y)

Related

Matlab - finding solution for scaling a curve

Consider two curves, for example:
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
I'd like to write a generalized algorithm that takes in x, y1, and y2, and scales y1 by a global scale factor, f, such that the new value of y2-y1 is as close as possible to 0. That is, y2-f*y1 is as close to 0 as possible.
How can I do this?
Try this:
% Create a function that you want to minimize
func = #(f, y1, y2)abs(sum(y2 - f*y1));
% Your example data
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
% Plot the before
figure()
plot(x, y2); hold all;
plot(x, y1)
% Find the optimum scale factor
f_start = 0; % May want a different starting point
f = fminsearch(#(f) func(f, y1, y2), f_start);
disp(['Scale factor = ' num2str(f)]) % print to the output
% Plot the after (scaled data)
figure()
plot(x, y2); hold all;
plot(x, f*y1)
For more information see the docs on anonymous functions and fminsearch (see example #2).
EDIT
Here is the output of the above script:
Scale factor = -2.9398
Before
After
As you can see the difference between the functions is minimized (area where y1 is greater than y2 is about the same as the area where y1 is less than y2). If you want the lines to match up as close as possible then you need to modify the minimization function like so:
func = #(f, y1, y2)sum(abs(y2 - f*y1));
I had to modify the test data for this case as it appears the data was already lined up optimally.
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = -2*y1 +1;
which gives the following output:
Scale factor = -2.9091
Before
After

contour plot with non integer coordinates

I have a matrix containing X coordinates, Y coordinates and V (value to be plotted).
X and Y values can be non integer.
I want to plot V values with a contour plot, but this type of plot only accepts a matrix as input.
My idea is to change X and Y non-integers coordinates into integers so V can be plotted with contour function.
Any idea how can I change the X and Y values to integers? (I don't care about the X an Y coordinates in this case)
Here's an example of a matrix:
H=[-0.5 0 20; 0 0 15 ; 0.5 0 40; -0.5 0.5 18; 0 0.5 35; 0.5 0.5 10; -0.5 1 3; 0 1 9; 0.5 1 20]
Just arrange your values to a matrix.
do something like:
[xcoord,ix] = unique(H(:,1));
[ycoord,iy] = unique(H(:,2));
matrix = nan(numel(xcoord),numel(ycoord))
and then sort your values in, the ix and iy are your integers...

scale part of an axis in matlab

I have the following image which I want to have the depth axis range like below :
(10 9.5 9 8.5 8 7.5 7 6 5 3 2 1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0) to show the data between depth 1 and 0 in larger scale, and I have the following code
depths = [10 5 1 0.5 0; 10 5 1 0.5 0] % these are the real depths in meter
contourf(points,depths,RFU15102013_BloomAsMainPoint);
set(gca, 'XTick', points(1) : points(2), 'XTickLabel',{ 'LSB1', 'LSB2'});
ylabel('Depth(m)');
xlabel('Points');
title('Date: 15.10.2013');
this is the image :
how can I do that?
EDIT1
Real Data:
RFU15102013_BloomAsMainPoint = [ 2.71 1.23 1.30 1.20 14.37 ; 2.51 1.36 1.01 1.24 1.15];
points = [1 1 1 1 1; 2 2 2 2 2 ];
depths = [10 5 1 0.5 0; 10 5 1 0.5 0];
As most of a data changes around zero it could be enough to change scaling of Y axis. Here is an example
close all; clear all;
z = [ 2.71 1.23 1.30 1.20 14.37 ; 2.51 1.36 1.01 1.24 1.15];
x = repmat([1; 2], 1, 5);
y = repmat([10 5 1 0.5 0], 2, 1);
% plotting with equally spaced y-s
h = subplot(1,2,1);
contourf(x,y,z);
y2 = log(y + 0.25);
yTicks = linspace(min(y2(1,:)), max(y2(1,:)), 10);
% plotting with logarithmically spaced y-s
h = subplot(1,2,2)
contourf(x,y2,z);
set(h,'YTick', yTicks)
set(h,'YTickLabel', exp(yTicks) - 0.25);
print('-dpng','scaling.png')
The result
This way any monotonic continuous function for axis scaling can be applied.
You could use UIMAGE - UIMAGESC from the mathworks file exchange and set the y values to emphaisize points in 1 to 0 range.

Extend coordinate vector [duplicate]

This question already has answers here:
How do I double the size of a vector in MATLAB with interpolation?
(2 answers)
Closed 8 years ago.
I have a row vector like
x = [ 0.125 0.25 0.5 0.75 1];
And I would like to expand it to 100 points with interpolation between points. Ho can i do it so that at the end I have equally spaced points but a length of 100 points?
Thanks
Solution
xi = [0 25 50 75 100];
yi = [0.125 0.25 0.5 0.75 1];
x = 1:1:100;
y = interp1(xi, yi, x);
Solution is y.
Explanation:
I consider your vector [0.125 0.25 0.5 0.75 1] as the result of a function F such that F(xi) = yi where xi = [0 25 50 75 100] and yi = [0.125 0.25 0.5 0.75 1].
I create x a 100-size vector using the same interval as xi;
I compute the interpolation of x based on the relationship between xi and yi;

Plot square surface in Matlab

How to plot a square surface in Matlab?
More exactly I want to plot a square square with value 0.5 surface which is located at X:-1 to X=1 and Y:2.5 to 3.5.
I tried the following
[X,Y] = meshgrid(-3.5:.5:3.5);
Z = zeros(15);
Z(end-2:end,5:9) = 0.5;
surf(X,Y,Z);
This doesn't result in a perpendicular edge. How to archive that?
This is what the patch function is for.
Matlab documentation
so for your case:
X = [ -1 -1 1 1];
Y = [3.5 2.5 2.5 3.5];
Z = [0.5 0.5 0.5 0.5];
patch(X,Y,Z,'red')
view(45,45)
You need to provide multiple Z-values together with the same X, Y values. A small example:
>> [X, Y]= meshgrid([1,2,2,3,4], 1:2)
X =
1 2 2 3 4
1 2 2 3 4
Y =
1 1 1 1 1
2 2 2 2 2
>> Z = [0,0,1,1,0;0,0,1,1,0]
Z =
0 0 1 1 0
0 0 1 1 0
>> surf(X, Y, Z)
Yields this:
This should be the same in 2D, you just need to wrap you head around which X and Y values to duplicate and adjust the Z-Matrix accordingly.
I ended up with
figure;
hold on;
X = [ -2 -2 2 2];
Y = [2 4 4 2];
Z = [0 0 0 0];
patch(X,Y,Z,'blue');
X = [ -1 -1 1 1];
Y = [3.5 2.5 2.5 3.5];
Z = [0.5 0.5 0.5 0.5];
h = patch(X,Y,Z,'red');
X = [ -1 -1 1 1];
Y = [2.5 2.5 2.5 2.5];
Z = [0 0.5 0.5 0];
patch(X,Y,Z,'red');
X = [1, 1, 1, 1];
Y = [2.5 2.5 3.5 3.5];
Z = [0 0.5 0.5 0];
patch(X,Y,Z,'red');
view(45,30)
legend(h, 'F(u,v)')
xlabel('u')
ylabel('v')
zlabel('F(u,v)')