Skip to content

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

Merged
merged 11 commits into from
Nov 21, 2016
Merged

Conversation

gzahl
Copy link
Contributor

@gzahl gzahl commented Feb 25, 2016

Hello,
I have added the option to specify the maximum streamline length. This is handy if one e.g. only needs a single (or a few) streamlines. It is especially handy if used together with "start_points".

This may be enhanced by forcing only forward (or backward) streamline integration. But that should probably be taken care of in another patch. Do you agree?

@tacaswell tacaswell added this to the 2.1 (next point release) milestone Feb 25, 2016
@tacaswell
Copy link
Member

Can you add a test for this?

Other than that seems perfectly reasonable and I agree doing the integration direction as a second PR is a good idea. Smaller changes are easier to review.

@gzahl
Copy link
Contributor Author

gzahl commented Feb 25, 2016

I will try to set up a short test.

My first interface idea for the integration direction is to change maxlength optionally in a tuple:
maxlength=[0,2] # this would be only forward integration.
maxlength=[-4,0] # only (longer) backward integration.
maxlength=2 # this would be translated to maxlength=[-2,2], which is the old default.

This would give the most flexibility. Or is it too complicated?

@tacaswell
Copy link
Member

The negatives would be confusing. I think a tri-state integration_direction in {'forward', 'reverse', 'both'} and then the maximum_length is either all forward, all back or split evenly would be simpler and get almost as much power.

@gzahl
Copy link
Contributor Author

gzahl commented Feb 25, 2016

Ok, i have added a test and copied the interface to axes and pyplot. I hope this was the right thing to do?
Tristate sounds good. Do you have an example, how it should be done in matplotlib?
I think 'backward' is better than 'reverse', since it is the standard term when referring to integrations.

@tacaswell
Copy link
Member

I think just strings are good enough (just validate on the way in).

You will also need to commit the test image see http://matplotlib.org/devel/testing.html#writing-an-image-comparison-test

This should be a png only test I think.

@gzahl
Copy link
Contributor Author

gzahl commented Feb 26, 2016

Hi,
thanks for the all your help and quick replies! I now have added two more patches:

  1. The baseline image for the maxlength test
  2. A complete patch + test for the integration direction

Let me know, if anything has to be changed and i will try to do it tomorrow.

@gzahl
Copy link
Contributor Author

gzahl commented Feb 26, 2016

Ok, after ironing out my rookie mistakes, i have added two more commits.
Now only a single test fails, but it does not seem to be realted to my commits.
Is there anything i can do? Thanks!

edit: Seems like the last problem fixed itself!

@@ -4465,21 +4465,25 @@ def stackplot(self, x, *args, **kwargs):
label_namer=None)
def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
minlength=0.1, transform=None, zorder=2, start_points=None):
minlength=0.1, maxlength=4.0, transform=None, zorder=2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All new args need to go at the end to maintain back-compatibility. The reason is if people are (un wisely!) passing in everything as positional args.

When we can drop python2 and can break API again most of these should be converted to kwarg only, but for now they need to go at the end.

@tacaswell
Copy link
Member

Left a few minor comments that need to be addressed. I see what you are doing putting minlength and maxlength together, but we should not break API 😞 .

Could you also add an entry into https://github.com/matplotlib/matplotlib/tree/master/doc/users/whats_new so that this gets properly advertised in the next release?

@gzahl
Copy link
Contributor Author

gzahl commented Mar 14, 2016

Hi, Sorry for the delay. It seems like i don't get any Email notifications. I have hopefully addressed all the issues.
I will try to enable my notifications.

@@ -52,9 +53,13 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
See :class:`~matplotlib.patches.FancyArrowPatch`.
*minlength* : float
Minimum length of streamline in axes coordinates.
*maxlength* : float
Maximum length of streamline in axes coordinates.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you re-arrange the docstrings too?

@gzahl
Copy link
Contributor Author

gzahl commented Nov 3, 2016

The tests are failing after the merge with upstream. I have to track that down later.

@afvincent
Copy link
Contributor

Might the test failures be related to the fact that FancyArrowPatch (which is used for streamplots) was modified in parallel with your PR (#6504 that superseded #6054)?

@tacaswell
Copy link
Member

Sorry this got dropped!

Can you rebase instead of merging upstream into your branch?

See http://matplotlib.org/devdocs/devel/gitwash/development_workflow.html?highlight=rebase

@gzahl
Copy link
Contributor Author

gzahl commented Nov 4, 2016

Thanks for the hint about a rebase rather than a merge.
But if i now revert the merge commit, i still have the merge/merge-revert in the history, which makes the rebase rather difficult (After conflicts with my changes, i get conflicts because of the merge commit).
Is there an easier way to do it? Sorry to bother you because of this. The easiest way would to make a new branch, and cherry-pick my changes. But i can not change the branch attached to this pull request.

@WeatherGod
Copy link
Member

If you do an interactive rebase, you can delete the commits that you don't
want in the branch and then force-push that up to github.

On Fri, Nov 4, 2016 at 7:04 AM, Manuel Jung notifications@github.com
wrote:

Thanks for the hint about a rebase rather than a merge.
But if i now revert the merge commit, i still have the merge/merge-revert
in the history, which makes the rebase rather difficult (After conflicts
with my changes, i get conflicts because of the merge commit).
Is there an easier way to do it? Sorry to bother you because of this. The
easiest way would to make a new branch, and cherry-pick my changes. But i
can not change the branch attached to this pull request.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#6062 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AARy-AWfEMOjbTmqfAsmDjVSw-XVJLTsks5q6xEsgaJpZM4HjPdA
.

@gzahl
Copy link
Contributor Author

gzahl commented Nov 4, 2016

Ok, thanks for the hint about the interactive rebase. The rebase is done, but the test (of course) still fail.
I have looked into it for a bit, but i don't think this is (mainly) because of the #6504. The starting/end points seem to be slightly different. I will look into this asap.

@afvincent
Copy link
Contributor

If the diff images do not show any issue with the arrows (especially their size), then I think you are right about #6504 not being related to the test failures.

@gzahl
Copy link
Contributor Author

gzahl commented Nov 7, 2016

Looking at the history of streamplot.py and its test file, i make the following observations:

  1. The test cases have been renamed bd63121. I will do the same with mine, to comply to the others.
  2. My observation about the different starting points seem to be related to commit 71b9ae8. Following this a new test case has been submitted 20959b3, which uses the starting_points option, which is also used by my tests. I therefore conclude, that this fix results in the changes of my test and will resubmit the expected image (Since it otherwise seems to be fine).

@QuLogic
Copy link
Member

QuLogic commented Nov 7, 2016

Can you rebase and remove the extra copies of the test images?

Do an interactive rebase, move the update commits right below the original addition of the files, and change the update commits to 'fixup'.

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor stuff + the rebase mentioned earlier.

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 visibilty of the flow pattern in some use cases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visibilty -> visibility

Also, wrap at 80.

@@ -2855,7 +2855,7 @@ def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear',
# This function was autogenerated by boilerplate.py. Do not edit as
# changes will be lost
@_autogen_docstring(Axes.hist)
def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False,
def hist(x, bins=None, range=None, normed=False, weights=None, cumulative=False,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but this is generated by boilerplate.py. Maybe it was changed in another commit, but boilerplate.py was not run? I rerun boilerplate.py in the 9634c0e.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is because pyplot was not updated with f1b89b2 change

Copy link
Contributor Author

@gzahl gzahl Nov 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That does seem right. Should this be fixed in another issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to update this here. We should be better about not letting pyplot get 'stale', but it is what it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I guess this request can therefore be closed.
I rebase again yesterday. Again there are unrelated changes from boilerplate.py (4775d7e
).

@@ -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* : ['foward','backward','both']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foward -> forward

  • space after commas

@@ -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." %
integration_direction)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misaligned.

if integration_direction not in ['both', 'forward', 'backward']:
errstr = ("Integration direction '%s' not recognised." %
integration_direction)
errstr += "Expected 'both', 'forward' or 'backward'."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not place it all in one string from the onset?

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:]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent should be a multiple of 4.

def swirl_velocity_field():
x = np.linspace(-3.,3.,100)
y = np.linspace(-3.,3.,100)
X,Y = np.meshgrid(x,y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add space after commas in above 3 lines.

def test_maxlength():
x, y, U, V = swirl_velocity_field()
plt.streamplot(x, y, U, V, maxlength=10., start_points=[[0.,1.5]],
linewidth=2,density=2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add space after commas in above two lines.

def test_direction():
x, y, U, V = swirl_velocity_field()
plt.streamplot(x, y, U, V, integration_direction='backward',
maxlength=1.5, start_points=[[1.5,0.]],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after comma.

@tacaswell tacaswell changed the title Add maximum streamline length property. [MRG+1] Add maximum streamline length property. Nov 9, 2016
@gzahl
Copy link
Contributor Author

gzahl commented Nov 21, 2016

@QuLogic Github still shows me a requested change, but i think i did all revisions? Otherwise please leave me a hint what is missing. Thanks!

@@ -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
Copy link
Member

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.

Copy link
Contributor Author

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?

@@ -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']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you specify the default in the docstring?

Copy link
Member

@QuLogic QuLogic Nov 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, according to numpydoc, it should be braces {} instead of brackets [], then the first value is the default (so put 'both' first.)

@@ -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):
Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, if it was public, i should leave it like that?

@NelleV
Copy link
Member

NelleV commented Nov 21, 2016

Hi @gzahl
It looks good overall, but do you mind making that new function private? Else, it adds this to the list of elements that need to be backward compatible :)
The "*" removal is just bonus points: we can merge this PR without that nitpick being fixed.

@QuLogic
Copy link
Member

QuLogic commented Nov 21, 2016

Unfortunately, that function is not new (WRT this PR, at least.)

@NelleV
Copy link
Member

NelleV commented Nov 21, 2016

Indeed, it is not… (I am clearly not caffeinated enough).

@NelleV NelleV merged commit 33a1cad into matplotlib:master Nov 21, 2016
@tacaswell
Copy link
Member

Glad this finally got merged!

@gzahl Thanks for your contribution and sorry the review took so long!

@gzahl
Copy link
Contributor Author

gzahl commented Nov 22, 2016

Thanks @tacaswell and all the others for your patience!

@QuLogic QuLogic changed the title [MRG+1] Add maximum streamline length property. Add maximum streamline length property. Nov 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants