holoviews icon indicating copy to clipboard operation
holoviews copied to clipboard

WIP: Streamlines element

Open poplarShift opened this issue 2 years ago • 12 comments

I'm starting to need this so had a go at #4837 (just blindly copying the bokeh example).

It might be good to eventually include points at either the origin or destination of a given streamline. It should be easy enough but I've become a bit rusty in holoviews...

PS: I'm not at the university anymore so got to be counting hours now, but still interested in getting this in.

Other issues:

  • should decide on the best data format. I've chosen u, v since that's what I work with, but angle/magnitude is more consistent with vectorfield, though I remember discussions about whether or not to eventually change that

MWE:

xx = np.linspace(-3, 3, 100)
yy = np.linspace(-3, 3, 100)

X, Y = np.meshgrid(xx, yy)
U = -1 - X**2 + Y
V = 1 + X - Y**2

e = hv.Streamlines((xx, yy, U, V)).opts(invert_axes=True, density=2, color='black', line_width=0.5)
e

image

poplarShift avatar Mar 23 '22 10:03 poplarShift

Cool! For most elements we have a default border, but I believe that is set to zero for RGB, HSV, Raster, VectorField, and Image elements. I'd propose that the border be zero for Streamlines and Contour elements as well.

jbednar avatar Mar 23 '22 14:03 jbednar

That's easily configured by overriding the padding parameter on the plotting class with a value of 0.

philippjfr avatar Mar 23 '22 18:03 philippjfr

Thanks for the PR @poplarShift! One of the tests in failing because of density can't be both a plot and style option (i.e. can't be a Parameter and also defined in style_opts).

maximlt avatar Jun 02 '22 13:06 maximlt

Thanks for the heads up, will look at that next time I'm in there!

poplarShift avatar Jun 07 '22 08:06 poplarShift

@poplarShift this is a very nice feature that we would like to put in the next major release, do you need any help to complete your PR?

maximlt avatar Jul 04 '22 15:07 maximlt

Hi @maximlt Some open questions would be:

  1. Is it OK to just use the bokeh streamline integration code? Its core is RK4 which is pretty standard AFAIK.
  2. Is there any sensible way of putting arrows on the lines? I don't think so but I may be missing some (new?) Bokeh features
  3. I've set the padding argument to default to 0, but padding is the same as before. If somebody could make a guess why not, that would be great!
  4. I would ideally like to be able to supply unstructured data (not regularly gridded velocities) - though I can't promise when I get around to that. So maybe that's best handled in a future PR?

poplarShift avatar Aug 10 '22 09:08 poplarShift

Hey thanks for the update! I'll ping @jlstevens who is more likely to be able to answer your questions.

maximlt avatar Aug 10 '22 09:08 maximlt

Thanks for the PR, this looks great!

  1. Is it OK to just use the bokeh streamline integration code? Its core is RK4 which is pretty standard AFAIK.

If you are worried about licensing issues, I'm sure it is ok. Ideally this code would be public API importable from Bokeh, but in this case, inlining the code is also fine.

  1. Is there any sensible way of putting arrows on the lines? I don't think so but I may be missing some (new?) Bokeh features

Not that I am aware of, but I'll go ahead and ping @mattpap for feedback on these two bokeh related questions.

Also, as long as arrows support can be added as a plot option later, I don't think those are necessary for the first release of this element.

  1. I've set the padding argument to default to 0, but padding is the same as before. If somebody could make a guess why not, that would be great!

I've got no immediate insights into this padding issue, I'm afraid! Happy to help track this down once we are happy with everything else.

I would ideally like to be able to supply unstructured data (not regularly gridded velocities) - though I can't promise when I get around to that. So maybe that's best handled in a future PR?

As long as the constructor of the element doesn't change (i.e. the element semantics are clear), I agree this can be in a future PR. Perhaps you could just give an example of what you think this data would look like and then we can postpone supporting that format till later?

jlstevens avatar Aug 10 '22 10:08 jlstevens

I've set the padding argument to default to 0, but padding is the same as before. If somebody could make a guess why not, that would be great!

Would have to know where and how you set it. I would recommend setting it as a parameter on the plotting class, i.e.:

    padding = param.ClassSelector(default=0, class_=(int, float, tuple))

philippjfr avatar Aug 10 '22 10:08 philippjfr

I've set the padding argument to default to 0, but padding is the same as before. If somebody could make a guess why not, that would be great!

Would have to know where and how you set it. I would recommend setting it as a parameter on the plotting class, i.e.:

    padding = param.ClassSelector(default=0, class_=(int, float, tuple))

Thanks for weighing in, that's exactly what I did. Will have to look at that again then...

poplarShift avatar Aug 12 '22 07:08 poplarShift

Thanks for the PR, this looks great!

  1. Is it OK to just use the bokeh streamline integration code? Its core is RK4 which is pretty standard AFAIK.

If you are worried about licensing issues, I'm sure it is ok. Ideally this code would be public API importable from Bokeh, but in this case, inlining the code is also fine.

It's from the bokeh documentation https://docs.bokeh.org/en/latest/docs/gallery/streamline.html, so not directly from the codebase.

I would ideally like to be able to supply unstructured data (not regularly gridded velocities) - though I can't promise when I get around to that. So maybe that's best handled in a future PR?

As long as the constructor of the element doesn't change (i.e. the element semantics are clear), I agree this can be in a future PR. Perhaps you could just give an example of what you think this data would look like and then we can postpone supporting that format till later?

The current gridded input format is

( (N, ), (M, ), (N, M), (N, M) )

so yes, that would have to change if we were instead to pass unstructured (columnar) data. We could reconstruct the regular grid by doing some binning/averaging preprocessing internally to make the current streamline integration algorithm work. Integrating directly on unstructured data is a bit more involved but I haven't actually done a lot of research on other implementations.

poplarShift avatar Aug 12 '22 07:08 poplarShift

Is there any sensible way of putting arrows on the lines? I don't think so but I may be missing some (new?) Bokeh features

Arrow heads can be added to a subset of glyphs via glyph decorations. Currently only Arc and Segment glyphs support this. See an example here https://github.com/bokeh/bokeh/blob/branch-3.0/examples/plotting/file/trefoil.py#L48-L52. I expect to implement broader support in bokeh 3.1. Note also that the existing API and features are experimental and subject to change.

mattpap avatar Aug 12 '22 07:08 mattpap