Problems with quiver plot

4 vues (au cours des 30 derniers jours)
Lukas
Lukas le 27 Août 2025
Modifié(e) : David Goodmanson le 31 Août 2025
Hey!
I try to create a quiver plot with unequl axis length. I' like to have the arrows the same length, which somehow does not want to work.
Any ideas?
Thanks!
%% system paramters
eta = .1;
mu = .1;
nu = 1;
gamma = 2;
%% dependent variables
roi = 2;
s = linspace(max([(1-roi)*s_0,0]),(1+roi)*s_0,10);
Unrecognized function or variable 's_0'.
p = linspace(max([(1-roi)*p_0,0]),(1+roi)*p_0,10);
[s,p] = meshgrid(s,p);
%% gradient flow
v = s.*p.^gamma ./ (1+(1+s).*p.^gamma);
ds = -v + eta;
dp = mu*(v - nu*p);
mag = sqrt(ds.^2 + dp.^2);
arrow_scale = 3E-1;
norm_ds = arrow_scale*ds./mag;
norm_dp = arrow_scale*dp./mag;
%% plot
q = quiver(s,p,norm_ds,norm_dp,'Autoscale','off', 'Color',.6*[1,1,1]);
q.ShowArrowHead = 'off';
q.Marker = '.';
  6 commentaires
David Goodmanson
David Goodmanson le 29 Août 2025
Modifié(e) : David Goodmanson le 31 Août 2025
Hi Sam, here's the best I could do trying to reproduce the wikipedia plot, including the aspect ratio. The arrows are all normalized to the same value, but at least as importantly the plottting points for quiver are not equally spaced meshgrid values. Rather every x,y quiver point is changed slightly from what meshgrid has. I didn't use 'axis equal' so I guess the vectors are not quite constant length visually.
xx = linspace(-5,5,22);
yy = linspace(-10,10,22);
[x0 y0] = meshgrid(xx,yy);
th = atan(x0.^2-x0-2);
sf = 1/2; % factor to visually reduce the arrow length on the plot
u = sf*cos(th);
v = sf*sin(th);
x = x0 - u/2; % move the center of the arrow to the constant-spaced points
y = y0 - v/2;
figure(1)
quiver(x,y,u,v,'showarrowhead','off','autoscale','off')
ylim([-10 10])
xlim([-10 10])
hold on
x1 = -5:.01:5
y1 = x1.^3/3 -x1.^2/2-2*x1+4;
y2 = x1.^3/3 -x1.^2/2-2*x1;
y3 = x1.^3/3 -x1.^2/2-2*x1-4;
plot(x1,y1,x1,y2,x1,y3)
hold off
Sam Chak
Sam Chak le 30 Août 2025
Thank you for your input. It appears that there is no specific parameter to set a constant length for all quiver objects without altering the original magnitudes of the directional components specified by u and v. However, you are absolutely correct that "constant length" representations are visually meaningless if the aspect ratios of the x- and y-axes are not equal.
s_0 = 10; % estimated based on the original image posted by the OP (now removed)
p_0 = 0.1; % estimated based on the original image posted by the OP (now removed)
%% system paramters
eta = .1;
mu = .1;
nu = 1;
gamma = 2;
%% dependent variables
roi = 2;
numArrX = 19; % number of arrows per row
numArrY = 19; % number of arrows per column
s = linspace(max([(1-roi)*s_0,0]), (1+roi)*s_0, numArrX);
p = linspace(max([(1-roi)*p_0,0]), (1+roi)*p_0, numArrY);
[s,p] = meshgrid(s,p);
%% gradient flow
v = s.*p.^gamma./(1 + (1 + s).*p.^gamma);
ds = -v + eta;
dp = mu*(v - nu*p);
mag = sqrt(ds.^2 + dp.^2);
Xarrow_scale = 4E-1;
Yarrow_scale = 1E-1;
norm_ds = Xarrow_scale*ds./mag;
norm_dp = Yarrow_scale*dp./mag;
% Finding the equilibrium point
fun = @(x) [-(x(1).*x(2).^gamma./(1 + (1 + x(1)).*x(2).^gamma)) + eta;
mu*(x(1).*x(2).^gamma./(1 + (1 + x(1)).*x(2).^gamma) - nu*x(2))];
x0 = [11, 1]; % initial guess
eq = fsolve(fun, x0) % equilibrium point
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
eq = 1×2
11.2222 0.1000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
%% plot
l = streamslice(s, p, norm_ds, norm_dp, 0.5, 'noarrows');
set(l, 'Color', "#F63C4C"); % Red Salsa
hold on
q = quiver(s, p, norm_ds, norm_dp, 'off', 'Color', .6*[1,1,1]); % automatic scaling is disabled
q.ShowArrowHead = 'off'; % no arrowheads
q.Marker = '.'; % for the tails
% adding the equilibrium point to the slope field
plot(eq(1), eq(2), 'o', 'markersize', 10, 'linewidth', 1.5, 'Color', "#2F2CE0") % Palatinate Blue
hold off
title('Gradient flow')
xlabel('s')
ylabel('p')
xlim([0 30])
ylim([0 .3])

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 27 Août 2025
Modifié(e) : Matt J le 27 Août 2025
I think you just need axis equal.
%% system paramters
eta = .1;
mu = .1;
nu = 1;
gamma = 2;
%% dependent variables
roi = 2;
s_0=1; p_0=3; %<---- Matt J chose randomly
s = linspace(max([(1-roi)*s_0,0]),(1+roi)*s_0,10);
p = linspace(max([(1-roi)*p_0,0]),(1+roi)*p_0,10);
[s,p] = meshgrid(s,p);
%% gradient flow
v = s.*p.^gamma ./ (1+(1+s).*p.^gamma);
ds = -v + eta;
dp = mu*(v - nu*p);
mag = sqrt(ds.^2 + dp.^2);
arrow_scale = 3E-1;
norm_ds = arrow_scale*ds./mag;
norm_dp = arrow_scale*dp./mag;
%% plot
q = quiver(s,p,norm_ds,norm_dp,'Autoscale','off', 'Color',.6*[1,1,1]);
q.ShowArrowHead = 'off';
q.Marker = '.';
axis equal %<---- Matt J added
  5 commentaires
Lukas
Lukas le 27 Août 2025
Perffect, this works. Many thanks!
Matt J
Matt J le 27 Août 2025
You're very welcome, but since it works, please Accept-click the answer to indicate so.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Vector Fields dans Help Center et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by