Im trying to create a triangle wave in matlab with equal rise and fall slope.
I searched around abit and found a code example:
n=input ('Enter the length of the sequence N= ');
t=0:n;
y=(-1).^t;
stem(t,y);
ylabel ('Amplitude');
xlabel ('Time Index');
TITLE ('Triangular waveform');
This code creates the the triangle form, but there are only data plots at the tip of each triangle. I want more data plots that follow the lines of the triangles.
Is there any function in matlab that can fill in data points with a specific width between the plots in the plotted lines from the graph?
If no, how am I supposed to solve this?
You need to linearly interpolate:
t2 = 0:0.5:n;
y2 = interp1(t, y, t2);
where t and y are the arrays from your example. You can use any size of interval for t2:
t2 = 0:0.1:n;
for example.
Change t=0:n; to t=0:0.1:n; and y=(-1).^t; to y=2*abs(mod(t,2)-1)-1;
This is what I got:
Related
I'm trying to use Matlab for some data plotting. In particular I need to plot a series of lines, some times given two points belonging to it, some times given the orthogonal vector.
I've used the following to obtain the plot of the line:
Line given two points A = [A(1), A(2)] B = [B(1), B(2)]:
plot([A(1),B(1)],[A(2),B(2)])
Line given the vector W = [W(1), W(2)]':
if( W(1) == 0 )
plot( [W(1), rand(1)] ,[W(2), W(2)])
else
plot([W(1), W(1) + (W(2)^2 / W(1))],[W(2),0])
end
where I'm calculating the intersection between the x-axis and the line using the second theorem of Euclid on the triangle rectangle formed by the vector W and the line.
My problem as you can see from the picture above is that the line will only be plotted between the two points and not on all the range of my axis.
I have 2 questions:
How can I have a line going across the whole axis range?
Is there a more easy and direct way (maybe a function?) to plot the line perpendicular to a vector? (An easier and more clean way to solve point 2 above.)
Thanks in advance.
Do you know the bounds of your axis for displaying the plot? If so, you can specify the range of the plot with the axis([xmin, xmax, ymin, ymax]) function.
So, from your question, if you know the slope m and intercept b, you can make sure your function plots the line across the whole window by specifying:
plot([xmin, xmax], [m*xmin + b, m*xmax + b]);
axis([xmin, xmax, min(m*xmin+b, m*xmax+b), max(m*xmin+b, m*xmax+b)]);
where xmin and xmax are values you specify as the range of your x-axis. This will make your line go from the corner of your plot to the other corner. If you want a buffer in the y-direction, then add one like so:
buffer = 5; % for example, you set this to something that looks good.
axis([xmin, xmax, min(m*xmin+b, m*xmax+b)-buffer, max(m*xmin+b, m*xmax+b)+buffer]);
I have a set of data that contains 3d Cartesian points (x, y, z) and a time stamp.
I would like to plot this data as a connected line in 3d space with the line colour changing based on the time stamp value.
Effectively i want to show the time difference in a colorbar.
Does anyone know of a way to do this?
Consider the following example of a 3D point moving along a helix-shaped path over time:
%# data
t = linspace(0,8*pi,200);
x = 20*t; y = cos(t); z = sin(t);
%# plot 3D line
plot3(x,y,z)
axis tight, grid on, view(35,40)
Now if you want to draw a multi-colored line, the naive solution would be to write a for-loop, drawing each small segment as a separate line, each having a different color. This is because a single line object can only have one color.
A better approach is to use a surface graphics object:
c = 1:numel(t); %# colors
h = surface([x(:), x(:)], [y(:), y(:)], [z(:), z(:)], ...
[c(:), c(:)], 'EdgeColor','flat', 'FaceColor','none');
colormap( jet(numel(t)) )
The result:
I am using MATLAB to plot two lines of a time series... (a min and max line)
I have the points converging at a single point at the end of the data.
I am trying to fill the area in between the lines and then plot other lines on top of the shaded area.
Here is my problem:
When I use "fill" it does exactly what I want it to do...but it draws a line from the last point of the data back to the initial data point. How do I get rid of it?
Here is a very vague sketch of my 2 examples:
The line below the graph is what I am talking about...
Any ideas how to avoid that?
Thanks!
I guess that you create the fill with
fill([xData1;xData2],[yData1;yData2])
where xData1 is a n-by-1 array of x-data for your first curve. This will lead to a weirdly-shaped polygon because the 'corners' of the polygon are not properly ordered.
Instead, you should do
fill([xData1;xData2(end:-1:1)],[yData1;yData2(end:-1:1])
i.e. flip the order of one of the two data sets.
As #Jonas explained (beat me to it), you need to properly order the data of the two time-series. Let me add an example to that:
%# first series
x1 = linspace(pi/4, 5*pi/4, 100);
y1 = cos(x1);
%# second series
x2 = linspace(pi/4, 5*pi/4, 100);
y2 = sin(x2);
subplot(121), fill([x1 x2], [y1 y2], 'r')
subplot(122), fill([x1 fliplr(x2)], [y1 fliplr(y2)], 'r')
hold on
plot(x1,y1, 'Color','b', 'LineWidth',3)
plot(x2,y2, 'Color','g', 'LineWidth',3)
I have a question about using the area function; or perhaps another function is in order...
I created this plot from a large text file:
The green and the blue represent two different files. What I want to do is fill in the area between the red line and each run, respectively. I can create an area plot with a similar idea, but when I plot them on the same figure, they do not overlap correctly. Essentially, 4 plots would be on one figure.
I hope this makes sense.
Building off of #gnovice's answer, you can actually create filled plots with shading only in the area between the two curves. Just use fill in conjunction with fliplr.
Example:
x=0:0.01:2*pi; %#initialize x array
y1=sin(x); %#create first curve
y2=sin(x)+.5; %#create second curve
X=[x,fliplr(x)]; %#create continuous x value array for plotting
Y=[y1,fliplr(y2)]; %#create y values for out and then back
fill(X,Y,'b'); %#plot filled area
By flipping the x array and concatenating it with the original, you're going out, down, back, and then up to close both arrays in a complete, many-many-many-sided polygon.
Personally, I find it both elegant and convenient to wrap the fill function.
To fill between two equally sized row vectors Y1 and Y2 that share the support X (and color C):
fill_between_lines = #(X,Y1,Y2,C) fill( [X fliplr(X)], [Y1 fliplr(Y2)], C );
You can accomplish this using the function FILL to create filled polygons under the sections of your plots. You will want to plot the lines and polygons in the order you want them to be stacked on the screen, starting with the bottom-most one. Here's an example with some sample data:
x = 1:100; %# X range
y1 = rand(1,100)+1.5; %# One set of data ranging from 1.5 to 2.5
y2 = rand(1,100)+0.5; %# Another set of data ranging from 0.5 to 1.5
baseLine = 0.2; %# Baseline value for filling under the curves
index = 30:70; %# Indices of points to fill under
plot(x,y1,'b'); %# Plot the first line
hold on; %# Add to the plot
h1 = fill(x(index([1 1:end end])),... %# Plot the first filled polygon
[baseLine y1(index) baseLine],...
'b','EdgeColor','none');
plot(x,y2,'g'); %# Plot the second line
h2 = fill(x(index([1 1:end end])),... %# Plot the second filled polygon
[baseLine y2(index) baseLine],...
'g','EdgeColor','none');
plot(x(index),baseLine.*ones(size(index)),'r'); %# Plot the red line
And here's the resulting figure:
You can also change the stacking order of the objects in the figure after you've plotted them by modifying the order of handles in the 'Children' property of the axes object. For example, this code reverses the stacking order, hiding the green polygon behind the blue polygon:
kids = get(gca,'Children'); %# Get the child object handles
set(gca,'Children',flipud(kids)); %# Set them to the reverse order
Finally, if you don't know exactly what order you want to stack your polygons ahead of time (i.e. either one could be the smaller polygon, which you probably want on top), then you could adjust the 'FaceAlpha' property so that one or both polygons will appear partially transparent and show the other beneath it. For example, the following will make the green polygon partially transparent:
set(h2,'FaceAlpha',0.5);
You want to look at the patch() function, and sneak in points for the start and end of the horizontal line:
x = 0:.1:2*pi;
y = sin(x)+rand(size(x))/2;
x2 = [0 x 2*pi];
y2 = [.1 y .1];
patch(x2, y2, [.8 .8 .1]);
If you only want the filled in area for a part of the data, you'll need to truncate the x and y vectors to only include the points you need.
I am currently a begineer, and i am using matlab to do a data analysis. I have a a text file with data at the first row is formatted as follow:
time;wave height 1;wave height 2;.......
I have column until wave height 19 and rows total 4000 rows.
Data in the first column is time in second. From 2nd column onwards, it is wave height elevation which is in meter. At the moment I like to ask matlab to plot a 3d graph with time on the x axis, wave elevation on the y axis, and wave elevation that correspond to wave height number from 1 to 19, i.e. data in column 2 row 10 has a let say 8m which is correspond to wave height 1 and time at the column 1 row 10.
I have try the following:
clear;
filename='abc.daf';
path='C:\D';
a=dlmread([path '\' filename],' ', 2, 1);
[nrows,ncols]=size(a);
t=a(1:nrows,1);%define t from text file
for i=(1:20),
j=(2:21);
end
wi=a(:,j);
for k=(2:4000),
l=k;
end
r=a(l,:);
But everytime i use try to plot them, the for loop wi works fine, but for r=a(l,:);, the plot only either give me the last time data only but i want all data in the file to be plot.
Is there a way i can do that. I am sorry as it is a bit confusing but i will be very thankful if anyone can help me out.
Thank you!!!!!!!!!!
Once you load your data as you do in your code above your variable a should be a 4000-by-20 array. You could then create a 3-D plot in a couple of different ways. You could create a 3-D line plot using the function PLOT3, plotting one line for each column of wave elevation data:
t = a(:,1); %# Your time vector
for i = 2:20 %# Loop over remaining columns
plot3(t,(i-1).*ones(4000,1),a(:,i)); %# Plot one column
hold on; %# Continue plotting to the same axes
end
xlabel('Time'); %# Time on the x-axis
ylabel('Wave number'); %# Wave number (1-19) on y-axis
zlabel('Wave elevation'); %# Elevation on z-axis
Another way to plot your data in 3-D is to make a mesh or surface plot, using the functions MESH or SURF, respectively. Here's an example:
h = surf(a(:,1),1:19,a(:,2:20)'); %'# Plot a colored surface
set(h,'EdgeColor','none'); %# Turn off edge coloring (easier to see surface)
xlabel('Time'); %# Time on the x-axis
ylabel('Wave number'); %# Wave number (1-19) on y-axis
zlabel('Wave elevation'); %# Elevation on z-axis
I don't quite understand what your function does, for example, I do not see any plot command.
Here's how I'd try to make a 3D plot according to your specs:
%# Create some data - time from 0 to 2pi, ten sets of data with frequency 1 through 10.
%# You would just load A instead (I use uppercase just so I know that A is a 2D array,
%# rather than a vector)
x = linspace(0,2*pi,100)';%#' linspace makes equally spaced points
w = 1:10;
[xx,ww]=ndgrid(x,w); %# prepare data for easy calculation of matrix A
y = ww.*sin(xx.*ww);
A = [x,y]; %# A is [time,data]
%# find size of A
[nRows,nCols] = size(A);
%# create a figure, loop through the columns 2:end of A to plot
colors = hsv(10);
figure,
hold on,
for i=1:nCols-1,
%# plot time vs waveIdx vs wave height
plot3(A(:,1),i*ones(nRows,1),A(:,1+i),'Color',colors(i,:)),
end
%# set a reasonable 3D view
view(45,60)
%# for clarity, label axes
xlabel('time')
ylabel('wave index')
zlabel('wave height')
Or, you could try gnuplot. Fast, free and relatively easy to use. I use it to generate heat maps for datasets in the millions of rows.