Plotting evolution of 2D vector in 3D as a ribbon in MATLAB
I would like to plot how the amplitude and orientation of a 2D vector evolves over time. To do this I would like to create a graph reminiscent of the canonical E & B field graphs you may recall from an introductory electricity and magnetism class.
Specifically, I would like to connect my 2D vector points with a ribbon, so that they are easy to see. Is there a simple way to do this in MATLAB? quiver3
is pretty close, but it 开发者_如何学编程lacks the ribbon. Perhaps some sort of parametric surface?
You can use the plotting functions FILL3 and QUIVER3 to do something like this:
x = linspace(0,4*pi,30); %# Create some x data
y1 = sin(x); %# Create wave 1
y2 = sin(x-pi); %# Create wave 2
u = zeros(size(x)); %# Create a vector of zeroes
hRibbon1 = fill3(x,y1,u,'r'); %# Plot wave 1 and fill underneath with color
set(hRibbon1,'EdgeColor','r',... %# Change the edge color and
'FaceAlpha',0.5); %# make the colored patch transparent
hold on; %# Add to the existing plot
quiver3(x,u,u,u,y1,u,0,'r'); %# Plot the arrows
hRibbon2 = fill3(x,u,y2,'b'); %# Plot wave 2 and fill underneath with color
set(hRibbon2,'EdgeColor','b',... %# Change the edge color and
'FaceAlpha',0.5); %# make the colored patch transparent
quiver3(x,u,u,u,u,y2,0,'b'); %# Plot the arrows
axis equal; %# Use equal axis scaling
And here's the resulting plot:
here's a solution that draws a ribbon between any two lines in 3D space. you can plot your quiver over it & adjust the opacity using 'FaceAlpha' as in gnovice's solution
To make the function clearer, I am first posting it without error-checking and resizing functions (which make up most of the body of the function & aren't particularly interesting)
function h = filledRibbon (x,y,z,u,v,w,c, varargin)
%function filledRibbon (x,y,z,u,v,w,c, varargin)
%
%plots a ribbon spanning the area between the lines x,y,z and x+u,y+v,z+w
%in the color c
%varargin is passed directly to patch
%returns a handle to the patch graphic created
%make up a set of regions that span the space between the lines
xr = [x(1:end-1); x(1:end-1) + u(1:end-1); x(2:end) + u(2:end); x(2:end)];
yr = [y(1:end-1); y(1:end-1) + v(1:end-1); y(2:end) + v(2:end); y(2:end)];
zr = [z(1:end-1); z(1:end-1) + w(1:end-1); z(2:end) + w(2:end); z(2:end)];
%plot the regions with no edges
h = patch(xr,yr,zr,c, 'LineStyle','none', varargin{:});
use this error-checking version in your actual code:
function h = filledRibbon (x,y,z,u,v,w,c, varargin)
%function filledRibbon (x,y,z,u,v,w,c, varargin)
%
%plots a ribbon spanning the area between the lines x,y,z and x+u,y+v,z+w
%in the color c
%varargin is passed directly to patch
%returns a handle to the patch graphic created
if ~exist('w', 'var') || isempty(w)
w = 0;
end
if ~exist('u', 'var') || isempty(u)
u = 0;
end
if ~exist('v', 'var') || isempty(v)
v = 0;
end
if ~exist('c', 'var') || isempty(c)
c = 'b';
end
%make all vectors 1xN
x = reshape(x,1,[]);
y = reshape(y,1,[]);
z = reshape(z,1,[]);
%if any offsets are scalar, expand to a vector
if all(size(u) == 1)
u = repmat(u, size(x));
end
if all(size(v) == 1)
v = repmat(v, size(x));
end
if all(size(w) == 1)
w = repmat(w, size(x));
end
%make up a set of regions that span the space between the lines
xr = [x(1:end-1); x(1:end-1) + u(1:end-1); x(2:end) + u(2:end); x(2:end)];
yr = [y(1:end-1); y(1:end-1) + v(1:end-1); y(2:end) + v(2:end); y(2:end)];
zr = [z(1:end-1); z(1:end-1) + w(1:end-1); z(2:end) + w(2:end); z(2:end)];
%plot the regions with no edges
h = patch(xr,yr,zr,c, 'LineStyle','none', varargin{:});
精彩评论