-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add maximum streamline length property. #6062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b14d46d
c60bfe2
67aa36e
ea75ec1
6cef6bc
e67ade8
ac00e8d
e3d24e8
6695ea9
c014846
4652f7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Maximum streamline length and integration direction can now be specified | ||
------------------------------------------------------------------------ | ||
|
||
This allows to follow the vector field for a longer time and can enhance the | ||
visibility of the flow pattern in some use cases. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,8 @@ | |
|
||
def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, | ||
cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', | ||
minlength=0.1, transform=None, zorder=None, start_points=None): | ||
minlength=0.1, transform=None, zorder=None, start_points=None, | ||
maxlength=4.0, integration_direction='both'): | ||
"""Draws streamlines of a vector flow. | ||
|
||
*x*, *y* : 1d arrays | ||
|
@@ -58,6 +59,10 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, | |
In data coordinates, the same as the ``x`` and ``y`` arrays. | ||
*zorder* : int | ||
any number | ||
*maxlength* : float | ||
Maximum length of streamline in axes coordinates. | ||
*integration_direction* : ['forward', 'backward', 'both'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you specify the default in the docstring? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, according to numpydoc, it should be braces |
||
Integrate the streamline in forward, backward or both directions. | ||
|
||
Returns: | ||
|
||
|
@@ -95,6 +100,15 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, | |
line_kw = {} | ||
arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) | ||
|
||
if integration_direction not in ['both', 'forward', 'backward']: | ||
errstr = ("Integration direction '%s' not recognised. " | ||
"Expected 'both', 'forward' or 'backward'." % | ||
integration_direction) | ||
raise ValueError(errstr) | ||
|
||
if integration_direction == 'both': | ||
maxlength /= 2. | ||
|
||
use_multicolor_lines = isinstance(color, np.ndarray) | ||
if use_multicolor_lines: | ||
if color.shape != grid.shape: | ||
|
@@ -126,7 +140,8 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, | |
u = np.ma.masked_invalid(u) | ||
v = np.ma.masked_invalid(v) | ||
|
||
integrate = get_integrator(u, v, dmap, minlength) | ||
integrate = get_integrator(u, v, dmap, minlength, maxlength, | ||
integration_direction) | ||
|
||
trajectories = [] | ||
if start_points is None: | ||
|
@@ -401,7 +416,7 @@ class TerminateTrajectory(Exception): | |
# Integrator definitions | ||
#======================== | ||
|
||
def get_integrator(u, v, dmap, minlength): | ||
def get_integrator(u, v, dmap, minlength, maxlength, integration_direction): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this needs to be public. Can you make this function private? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, if it was public, i should leave it like that? |
||
|
||
# rescale velocity onto grid-coordinates for integrations. | ||
u, v = dmap.data2grid(u, v) | ||
|
@@ -435,17 +450,27 @@ def integrate(x0, y0): | |
resulting trajectory is None if it is shorter than `minlength`. | ||
""" | ||
|
||
stotal, x_traj, y_traj = 0., [], [] | ||
|
||
try: | ||
dmap.start_trajectory(x0, y0) | ||
except InvalidIndexError: | ||
return None | ||
sf, xf_traj, yf_traj = _integrate_rk12(x0, y0, dmap, forward_time) | ||
dmap.reset_start_point(x0, y0) | ||
sb, xb_traj, yb_traj = _integrate_rk12(x0, y0, dmap, backward_time) | ||
# combine forward and backward trajectories | ||
stotal = sf + sb | ||
x_traj = xb_traj[::-1] + xf_traj[1:] | ||
y_traj = yb_traj[::-1] + yf_traj[1:] | ||
if integration_direction in ['both', 'backward']: | ||
s, xt, yt = _integrate_rk12(x0, y0, dmap, backward_time, maxlength) | ||
stotal += s | ||
x_traj += xt[::-1] | ||
y_traj += yt[::-1] | ||
|
||
if integration_direction in ['both', 'forward']: | ||
dmap.reset_start_point(x0, y0) | ||
s, xt, yt = _integrate_rk12(x0, y0, dmap, forward_time, maxlength) | ||
if len(x_traj) > 0: | ||
xt = xt[1:] | ||
yt = yt[1:] | ||
stotal += s | ||
x_traj += xt | ||
y_traj += yt | ||
|
||
if stotal > minlength: | ||
return x_traj, y_traj | ||
|
@@ -456,7 +481,7 @@ def integrate(x0, y0): | |
return integrate | ||
|
||
|
||
def _integrate_rk12(x0, y0, dmap, f): | ||
def _integrate_rk12(x0, y0, dmap, f, maxlength): | ||
"""2nd-order Runge-Kutta algorithm with adaptive step size. | ||
|
||
This method is also referred to as the improved Euler's method, or Heun's | ||
|
@@ -532,7 +557,7 @@ def _integrate_rk12(x0, y0, dmap, f): | |
dmap.update_trajectory(xi, yi) | ||
except InvalidIndexError: | ||
break | ||
if (stotal + ds) > 2: | ||
if (stotal + ds) > maxlength: | ||
break | ||
stotal += ds | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please remove the "*". They are not helpful for readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course i could, but all parameters in this function use the "*". It seems inconsistent if i only remove them for the new "maxlength" parameter?