-
Notifications
You must be signed in to change notification settings - Fork 440
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
Default set active vectors for filters #2433
Conversation
This PR is set to draft with one implementation for |
cc @adeak since we have discussed this in the past, in case you are able/willing to review. |
pyvista/utilities/helpers.py
Outdated
else: | ||
mesh.set_active_vectors(possible_vectors_cell[0], preference='cell') | ||
elif n_possible_vectors < 1: | ||
raise ValueError("No vector-like data available.") |
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.
I'm not sure that ValueError
is the right Error to be raised in both cases.
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.
Thanks for the ping, I've got this on my radar but I won't be able to give a closer look today.
I agree that the errors seem a bit different. If we stick to ValueError
then that can work I guess. But we could consider defining some semantically correct ValueError
subclasses, e.g. MissingDataError
and AmbiguousDataError
or whatever. (There's a school of thought that exceptions shouldn't be distinguished by error messages, and instead one should make liberal use of exception subclasses.)
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.
I like this suggestion, but I need to think about it. I also think that having a ton of error subclasses will lead to confusion too. The art is getting the right level of generality vs. specificity.
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.
Based on my comment below that glyph filter uses the active vector by default. It would be very useful to have specific Errors for the different types of problems here. Then we can catch those in glyph
and provide an informative warning message.
Codecov Report
@@ Coverage Diff @@
## main #2433 +/- ##
==========================================
- Coverage 93.70% 93.66% -0.05%
==========================================
Files 74 75 +1
Lines 15994 16030 +36
==========================================
+ Hits 14987 15014 +27
- Misses 1007 1016 +9 |
The glyph filter unfortunately currently has a default to orient by the active vectors. If none are present, it simply does not orient and continues silently. We can either allow an error to be raised as in the current PR state, or we can add in an optional value to the helper to change the error to a warning. I'm leaning towards the second option so as to avoid a breaking change. Edit: Instead of adding an option to use warnings instead of raising an Error, I've chosen to raise more specific Errors and then catch those in glyph. This allows for more control over specific warnings for each use case. It is not so straightforward to 're-throw' warnings without side effects. |
Since glyphing doesn't always need vectors (see also the current behaviour), I would also want to keep the option where no vectors are present. One could easily have a point cloud they want to colour/scale by scalars only, for instance. But if I understood your edit correctly, this is what you ended up doing (still haven't looked at the implementation yet). |
The problem is that the default behavior is to require vectors ( Additionally, I think orienting glyphs is a very common use case (arrow vector plots being an example), so there are probably lots of users using the default behavior with orientation as well. It is a bit of a pickle. The options I see are, with my perceived pros and cons. As you can see, I am a proponent of option 2.
|
I have implemented in all the filters I could find using vectors, at least ones with input parameters named This is fully ready for review. PS. this is my first big-ish PR since |
I don't see it as that much of a pickle. We could choose to ignore
As we both agree we shouldn't raise when there are no vectors. This almost always means someone not touching From the above options I'd also go with 2 like you did. But I would consider another, additional change (which might be too eager for its own good): switching to |
except AmbiguousDataError as err: | ||
warnings.warn( | ||
f"{err}\nIt is unclear which one to use. orient will be set to False." | ||
) | ||
orient = False |
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.
And in this case, i.e. orient=True
and there are too many potential vectors to use, I might even consider raising. This has to be a user error, and we have to force the user to do something (either disable orient, or choose vectors to orient by).
I'm leaning towards agreeing with your parenthetical, but I don't lean too far in that direction. Users might be puzzled why using I will wait for more input on this before making more changes. |
pyvista/utilities/helpers.py
Outdated
f"Multiple vector-like data available: {possible_vectors}.\n" | ||
"Set one as active using DataSet.set_active_vectors(name)" |
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.
I wonder how confusing this would be if there's a single point vectors and a single cell vectors with the same name (might actually be more common than expected). We'd print the same name twice, and the set_active_vectors
call would probably also need a preference
kwarg to distinguish the two.
But I have no idea how to make this more descriptive for this case while keeping it concise.
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.
We don't need to set a preference to call this function because we have, so far, taken the decision to raise an error if there is more than one vector-like array.
It would be most complete to print the vector-like arrays separately for points and cells. But we don't do this for usage like mesh.array_names
so I don't know.
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.
With the preference I just meant the recommendation in the error message: "Set one as active using DataSet.set_active_vectors(name)
". But again it would be cumbersome to try and add the preference distinction to the message (to the effect of "also don't forget to choose the right preference if you have a name clash").
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.
We could print cell and point vectors separately and then use DataSet.set_active_vectors(name, preference=type)
something like this. This gives the user two pointers without having to be super explicit.
@@ -631,7 +631,15 @@ def test_glyph(datasets, sphere): | |||
geom=geoms, scale='arr', orient='Normals', factor=0.1, tolerance=0.1, progress_bar=True | |||
) | |||
assert sphere.glyph(geom=geoms[:1], indices=[None], progress_bar=True) | |||
assert sphere_sans_arrays.glyph(geom=geoms, progress_bar=True) | |||
|
|||
with pytest.warns(Warning): # tries to orient but no orientation vector available |
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.
I don't want to go overboard, but do we want to define a custom DataWarning
/ActiveDataWarning
or something to be emitted in these cases? 😄 (I'm still not great at naming things.)
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.
I'm thinking that the warning should indicate that the input parameter is changed/ignored. This would be a general and fairly useful warning type. I'm blanking on a concise name too.
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.
Good idea making it broader. Let's think about an appropriate name...
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.
I am torn in two directions.
One is something like ActiveAttributesWarning
, since we cannot set an active attribute in the vtk sense. If this too vtkish, I like your ActiveDataWarning
. These are the cause of the warning.
To go another way, something like ParameterChangeWarning
to indicate the effect of what is happening.
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.
I think we can resolve this later, but as-is, this is sufficient.
Co-authored-by: Andras Deak <adeak@users.noreply.github.com>
Co-authored-by: Andras Deak <adeak@users.noreply.github.com>
…yvista into default_active_vectors
I'm starting to think that we may want to leave |
@MatthewFlamm, is this ready for review? |
Yes |
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.
Great work, and thanks for the review @adeak
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.
Potential future work in
- Default set active vectors for filters #2433 (comment)
- Default set active vectors for filters #2433 (comment)
- Default set active vectors for filters #2433 (comment)
But I agree with @akaszynski that this is good as-is. Thanks!
Trying to avoid PRs becoming too long lived (big believer in trunk based development and short lived branches). Agree with follow-ups. |
Overview
This PR implements a common helper to set a default for active_vectors on a mesh. This currently implements option #2 from #2334 (comment). Reproduced here:
Details
The logic used here is to set a default active_vectors only if there is one vector-like array, i.e. shape
(n, 3)
. It is still possible that the vector-like array is not truly a vector in the vtk sense (RGB array for example), but in this case the user should be aware of what is happening since it is unambiguous what the intent is.