Skip to content
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

Add new filter sample_over_line and refactor plot_over_line #525

Merged
merged 5 commits into from
Jan 13, 2020

Conversation

MatthewFlamm
Copy link
Contributor

This PR enables a new filter sample_over_line, which is a simple refactoring of plot_over_line, but enables the user to retrieve the data instead of just plotting it. plot_over_line calls sample_over_line, and now only does plotting.

if resolution is None:
resolution = int(dataset.n_cells)
if not isinstance(resolution, int) or resolution < 0:
raise RuntimeError('`resolution` must be a positive integer, not {}'.format(type(resolution)))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd expect the resolution checking to happen in pyvista.Line.

Copy link
Member

Choose a reason for hiding this comment

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

Ah good point! It would be good to go ahead and move that check over to thee pyvista.Line function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did nothing but refactor the code, so this was original, but it is always good to clean things up. Let me dig deeper, I suppose this is a chance to learn more about pyvista internals.

Copy link
Member

Choose a reason for hiding this comment

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

Yep, this one is on me when I originally wrote this filter. If you could move that check over to the following function, it would be a help!

def Line(pointa=(-0.5, 0., 0.), pointb=(0.5, 0., 0.), resolution=1):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the current version if I do

pv.Line([0, 0, 0], [0, 0, 1], resolution=10.5)

I get a helpful error already from presumably vtk

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/redacted/pyvista/pyvista/utilities/geometric_objects.py", line 348, in Line
    src.SetResolution(resolution)
TypeError: SetResolution argument 1: integer argument expected, got float

Do you still prefer a check inside pyvista with RunTimeError?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't touch this part yet as I'm not sure what you want. My understanding is that ValueError is for arguments of the wrong type, which seems to fit here.

Copy link
Member

Choose a reason for hiding this comment

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

ah that's a good point - then I would just let that chack from vtk be it

Copy link
Member

Choose a reason for hiding this comment

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

i.e. no need to even have a check inside pyvista

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 more subtleties....

pv.Line([0, 0, 0], [0, 0, 1], resolution=0)
pv.Line([0, 0, 0], [0, 0, 1], resolution=-1)

All of these lines return a line with two points. I think we should still check the magnitude to be positive in Line, which is in the newest commit I pushed.

Copy link
Member

@banesullivan banesullivan left a comment

Choose a reason for hiding this comment

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

Great idea! I think it would be best to have the filter return a PyVista mesh object rather than two numpy arrays. A lot more can be done with the PolyData line such as creating a tube and plotting it in 3D. Also, this would allow you to sample all arrays in the dataset at once

pyvista/core/filters.py Outdated Show resolved Hide resolved
pyvista/core/filters.py Outdated Show resolved Hide resolved
pyvista/core/filters.py Outdated Show resolved Hide resolved
@banesullivan banesullivan added the enhancement Changes that enhance the library label Jan 9, 2020
@MatthewFlamm
Copy link
Contributor Author

I removed the check for integer resolution, but moved the check for positive resolution (this one isn't checked in vtk) to Line. I added to test_line to make sure that revisions in vtk don't break this behavior. I also added some a test for the new sample_over_line filter.

Copy link
Member

@banesullivan banesullivan left a comment

Choose a reason for hiding this comment

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

Looks great now!

@MatthewFlamm MatthewFlamm changed the title Refactor plot_over_line filter to enable retrieving result with sample_over_line Add new filter sample_over_line and refactor plot_over_line Jan 11, 2020
@banesullivan
Copy link
Member

@MatthewFlamm, I'm happy with this at this point, are you finished?

@imsodin, does this look good to you now?

@MatthewFlamm
Copy link
Contributor Author

I'm done, unless there are other comments.

line = pyvista.Line(pointa, pointb, resolution=resolution)
sampled = line.sample(dataset)
# Sample on line
sampled = DataSetFilters.sample_over_line(dataset, pointa, pointb, resolution)
Copy link
Contributor

@imsodin imsodin Jan 12, 2020

Choose a reason for hiding this comment

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

EDIT: Actually this seems to be valid, wouldn't have expected that but on second thoughts it makes sense. Still in my opinion:.
This must be dataset.sample_...

More generally maybe there should be a static analyser on CI to catch such things.

Copy link
Member

Choose a reason for hiding this comment

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

I've implemented a lot of filters that call other filters this way. I thought it was "safer"

Copy link
Member

Choose a reason for hiding this comment

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

is this bad practice, @imsodin?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This whole class is littered with both types examples. What is the preferred approach, and I can use that one?

Copy link
Member

Choose a reason for hiding this comment

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

I'm happy with it as is, but yes, you're right that the class has both examples all over the place. We're working to refactor things like this to make them more consistent on a separate branch, so I say just leave it and we'll choose the "proper" method later

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I haven't been aware this was used in the same file. Maybe it's just simply lack of experience on my part that i have never seen a class instance method be called like this. The only practice I could come up with that might be somewhat relevant is that in python there should be "one, preferably obvious way of doing things" and if I had to choose I'd definitely choose variable.method(... over class.method(variable, ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with @imsodin . I found this reference that

There is a simple way to call the base class method directly: just call BaseClassName.methodname(self, arguments).

This is the strategy used here. I see this being useful if you don't want derived classes to overwrite the sample_over_line method call inside the plot_over_line method, but you do want to be able to overwrite it in general.

I'm not sure this is what you want however.

Copy link
Contributor

Choose a reason for hiding this comment

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

Regardless of whether or not it should change, that's a topic for a separate PR.

@banesullivan banesullivan merged commit 6d017f2 into pyvista:master Jan 13, 2020
@MatthewFlamm MatthewFlamm deleted the refactor_plot_over_line branch January 13, 2020 18:09
akaszynski pushed a commit that referenced this pull request Mar 6, 2021
sampled_line should be checked
@akaszynski akaszynski mentioned this pull request Mar 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Changes that enhance the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants