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

resize and set different size of arrows #2526

Open
envelope-chaos opened this issue Sep 11, 2023 · 2 comments
Open

resize and set different size of arrows #2526

envelope-chaos opened this issue Sep 11, 2023 · 2 comments

Comments

@envelope-chaos
Copy link

Hi!

I encountered some problems while drawing arrows, and I'm unsure how to achieve my requirements. I would greatly appreciate your assistance in resolving this.

My requirement is to overlay data with a vector field, similar to marking wind direction and magnitude on a map. I believe this can be achieved by combining Image and Arrow for display. I'm using the following code as a simple example.

import sys
import numpy as np
from vispy import scene
from vispy import app
from vispy.io import load_data_file, read_png

canvas = scene.SceneCanvas(keys='interactive')
canvas.size = 800, 600
canvas.show()

view = canvas.central_widget.add_view()

# Create the image
img_data = read_png(load_data_file('mona_lisa/mona_lisa_sm.png'))
interpolation = 'nearest'

image = scene.visuals.Image(img_data,
                            interpolation=interpolation,
                            parent=view.scene,
                            method='subdivide')

canvas.title = 'Spatial Filtering using %s Filter' % interpolation

arrows = np.random.rand(20, 4) * 500
node = scene.visuals.Arrow(arrows=arrows,
                           arrow_size=16,
                           arrow_color=(1, 0, 0, 0.5),
                           connect='segments')

view.add(node)

view.camera = scene.TurntableCamera(azimuth=0, elevation=-90)


if __name__ == '__main__' and sys.flags.interactive == 0:
    app.run()

Now, my issues are as follows:

  1. Resize: When I scroll the mouse wheel, the image scales, but the arrow sizes remain the same. Consequently, when the image shrinks to a certain extent, the arrows fill the entire screen, which looks odd. How should I configure it so that the arrow sizes also change along with the image?

  2. I want to use arrow size to represent the magnitude of the field, so I would like to pass an array to arrow_size. However, it appears that currently, I can only set a fixed size."

  3. When the image is rotated to a certain extent, the arrows appear strange.

image

@envelope-chaos
Copy link
Author

Because the data is 3D volume, I display it in several slices (Image). So I use a TurntableCamera camera.

@djhoese
Copy link
Member

djhoese commented Sep 11, 2023

  1. Unfortunately, I don't think this is implemented and would need to be implemented in both the Python and shader code. The good news is it is probably something that can be copied from the MarkersVisual. The bad news is it might be annoyingly complicated because of the history of the MarkersVisual and handling of scaling (CC @brisvag).

  2. Skimming the code I don't think there is anything stopping this from working in the shader code. It looks like it is mostly the python code that is limiting this. Do you get an error when you try passing an array? My guess is this part of the code isn't happy:

@arrow_size.setter
def arrow_size(self, value):
if value is None:
self._arrow_size = 5.0
else:
if value <= 0.0:
raise ValueError("Arrow size should be greater than zero.")
self._arrow_size = value
self._arrows_changed = True

  1. If I remember correctly the 3D support for the ArrowsVisual is very much a hack. I believe it was written only for 2D space, someone wanted to use it in 3D, so the shader code was naively/easily updated to just not drop the third axis. This doesn't necessarily mean that everything will look good which I think is what's happening in your image in your third point. I'm not sure what can be done about it, but I think there is another issue very similar to this (can't find it right now). My guess is that the calculations for the orientation of the arrow results in a divide by 0 in one of the dimensions and things just get weird after that. See:

vec3 body = $transform(v2).xyz - $transform(v1).xyz;
v_orientation = (body / length(body));

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

No branches or pull requests

2 participants