-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Specifying tolerance distance in streamplot #9269
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
Comments
In my opinion, what you really want is a way to put arrows on |
Thank you, @jklymak . I just played with import numpy as np
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
def calc_psi2d(fx, fy, dx=1, dy=1):#solenoidal flows
'''
Calcualte psi by integrating dpsi = -fy*dx + fx*dy, psi[0,0]=0.
Notes:
1. (fx=dpsi/dy,fy=-dpsi/dx) is called Hamiltonian gradient of psi
2. contours of psi give vector field (fx, fy);
3. div(f)=0
'''
ny,nx=fx.shape
psi=np.zeros((ny,nx))
for jx in range(1,nx):
psi[0,jx]=psi[0,jx-1]-fy[0,jx]*dx
for jy in range(1,ny):
psi[jy,:]=psi[jy-1,:]+fx[jy,:]*dy
return psi
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
U = Y
V = -X
Z = calc_psi2d(U,V)
plt.figure()
CS = plt.contour(X, Y, Z)
fmt = ticker.StrMethodFormatter('>')
plt.clabel(CS, CS.levels, fmt=fmt, inline=False)
plt.title('contour+clabel: arrow directions randomly wrong')
plt.figure()
plt.streamplot(X,Y,U,V)
plt.title('streamplot: arrow directions correct')
plt.show() This looks nice (though the "arrow" tips are still off a little), but the some arrow directions are wrong? Is possible to further improve the results using PS: I think calc_label_rot_and_inline does the rotation of label. |
See http://matplotlib.org/devdocs/users/whats_new.html#maximum-streamline-length-and-integration-direction-can-now-be-specified and http://matplotlib.org/devdocs/api/_as_gen/matplotlib.axes.Axes.streamplot.html#matplotlib.axes.Axes.streamplot Some of this will be in 2.1 (there is an RC out now, I really do plan to tag the final release tonight) |
I think the right long-term path here is to split the streamplot code in half along the 'integrate the lines' vs 'create the artists to draw the lines' axes. That way we can continue to ship a simple integrator and make it easy for users to bring their own integrator. |
I think thats great as well. I'm sure there are lots of different ways to calculate streams, so a flexible way to do it would probably be welcome. But in this case I think the OP wants to contour the streamfunction, which in a two-d flow is a field. But he would also like some helpful markers to indicate flow direction. Thats actually pretty different than what |
For the issue with discontinuous I am not very familiar with the source code nor a python expert, but I am willing to look into and play with |
@jimgreen Sounds good! I suggest asking questions either here or the matplotlib-users@python.org mailing list. |
@jimgreen In case this helps: The streamline-breaking behavior appears to be caused by trajectory updating method inside the StreamMask: def _update_trajectory(self, xm, ym):
"""Update current trajectory position in mask.
If the new position has already been filled, raise `InvalidIndexError`.
"""
if self._current_xy != (xm, ym):
if self[ym, xm] == 0:
self._traj.append((ym, xm))
self._mask[ym, xm] = 1
self._current_xy = (xm, ym)
else:
raise InvalidIndexError In fact, a solution was proposed by @ketch in #8388 a while ago: don't raise the InvalidIndexError if the new position/cell is already marked in case the user asks for such a behavior. That issue apparently hasn't gained any traction since, but a solution along these lines should work. |
Hi! |
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help! |
This continues to be the right solution, and is well aligned with the data-prototype work. Part of me wants to label this is a "good first issue" as it is a very constrained part of the code base, but there will be API design involved so probably not. |
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help! |
Desired results
Tecplot can produce continuous 2d contours with arrows nicely centered on the lines. For example,
.
Outcome of Matplotlib
streamplot
. However, the stopping of tracing is hard to adjust and one often gets broken (i.e., not continuous) lines, which can misleadingly look like sudden disappearance/stopping of streams or field lines. For example,minlength
anddensity
at the same time helps, but this basically traces more seeds and rejects many of them unless a carefully chosen set of seeds are used. This could be better done by using smaller tolerance distance between integration points.quiver
. But the arrow tips usually fall off the contour lines a little.Requested feature
streamplot
is desirable. Right now, it appears to me thatstreamplot
divides the domain into blocks and stop tracing when entering a block occupied by another traced line. But the number of blocks, and thus the size of the blocks rely ondensity
only. Maybe it is better to allow specifying the tolerance distance. Or, maybe we can simply allow a "density_stop" to set the block sizes separately.The text was updated successfully, but these errors were encountered: