Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 16:26
    kmuehlbauer commented #1568
  • Jan 31 2019 16:15
    kmuehlbauer commented #1568
  • Jan 31 2019 15:53
    djhoese commented #1568
  • Jan 31 2019 15:46
    kmuehlbauer edited #1568
  • Jan 31 2019 15:44
    kmuehlbauer opened #1568
  • Jan 31 2019 15:32
    djhoese commented #1566
  • Jan 31 2019 15:30
    djhoese commented #1567
  • Jan 31 2019 14:18
    GuillaumeFavelier commented #1561
  • Jan 31 2019 14:15
    GuillaumeFavelier commented #1561
  • Jan 31 2019 12:46
    opekar synchronize #1130
  • Jan 31 2019 09:54
    kmuehlbauer commented #1567
  • Jan 31 2019 09:53
    kmuehlbauer synchronize #1567
  • Jan 31 2019 09:37
    kmuehlbauer labeled #1567
  • Jan 31 2019 09:37
    kmuehlbauer labeled #1567
  • Jan 31 2019 09:37
    kmuehlbauer labeled #1563
  • Jan 31 2019 09:36
    kmuehlbauer labeled #1563
  • Jan 31 2019 09:28
    kmuehlbauer commented #1567
  • Jan 31 2019 09:27
    kmuehlbauer synchronize #1567
  • Jan 31 2019 09:19
    kmuehlbauer assigned #1563
  • Jan 31 2019 09:17
    kmuehlbauer opened #1567
kmuehlbauer
@kmuehlbauer:matrix.org
[m]
@djhoese Sorry, I can only have a look next week. But one thing mentioned in the docstring is text collections. Was there any initial work on this already? It might be the right thing for the OP.
David Hoese
@djhoese
I don't think they'd be able to mix collections and Visuals/SceneCanvas
Andy Sweet
@andy-sweet

Over on napari/napari#3357 we noticed that canvas widgets have a default _border_width of 1, which can result in unexpected/undesired borders. The only easy way I found to remove that border is to modify the vispy source to make the default border_width parameter 0 instead.

Before I open any issues/PRs on vispy, I wanted to check a few of things.

  • Is this an intended behavior of vispy? If not, would you be open to changing the default _border_widthto be 0?
  • Can you think of any other ways to make all canvas widgets have a _border_width of 0?

There are some code snippets on the napari issue, but I'm happy to try to create a minimal reproducer - napari's Qt widgets/layout are non-trivial, so it's very possible that the default 1-pixel transparent borders only cause an issue for us (e.g. because of the effective background color of some Qt widget). Though, when calling grabFrameBuffer on the native Qt widget, we'll also getting that border, so I think that constrains where that color is coming from.

David Hoese
@djhoese

@andy-sweet Thanks for reaching out.

  • Is this intended? VisPy has been off and on with maintainers for so long that it is likely the people who originally made that suggestion don't even remember making it or why. I'll see if I can track something down in the git history
  • You should be able to "manually" create Widget-subclass (ViewBox, Widget, Grid) and add them to the SceneCanvas instead of relying on the default behavior. For example, canvas.central_widget.add_view() (or whatever it is) create a Grid widget as a central_widget implicitly and then add_view creates a ViewBox widget. But I think at least for the view you should be able to import the ViewBox class, instantiate it, then add it to the grid widget with central_widget.add_widget(view, ...). At least I think so. I might be mixing up multiple interfaces.

Am I OK with border width being set to 0? Sure, probably. It will probably cause a lot of tests to fail. @almarklein @rougier @larsoner any memory of the border width stuff? Looks like it came from a PR by @campagnola in vispy/vispy#1030

Nicolas P. Rougier
@rougier
I don't remember either but a default of 1 is ok if border could be disabled (by default), else a default of 0 seems ok. Question is wheter code for drawing the border is ran when border=0
David Hoese
@djhoese
some of the comments in #1030 seem related to having multiple views in the same Canvas. @andy-sweet I'd say make a pull request and we'll see what tests fail
Andy Sweet
@andy-sweet

@djhoese : thanks for the quick reply! I think you effectively solved this issue by educating me on add_view.

We have already have a VispyCanvas that extends SceneCanvas so by overriding the SceneCanvas.central_widget property there and by passing border_width=0 through to add_view, I think I'm able to get the desired behavior in napari, so I think that's probably going to be enough.

So unless I'm get some pushback from other people on napari, or you are / someone else is really curious about how many and what tests fails, I'm probably going to avoid opening that PR for now.

David Hoese
@djhoese
I wouldn't mind a PR, but yeah if you don't have the time or the interest then don't worry about it
Andy Sweet
@andy-sweet
@djhoese : I did something slightly simpler, which is to make SceneCanvas.central_widget's border_width 0, since the other border widths can be more easily controlled (e.g. in add_view): vispy/vispy#2255
I'm not sure if this makes sense and I haven't set up my vispy dev environment enough to run all the tests. Feel free to run them on CI, or close this PR if it's just silly.
Jordão Bragantini
@JoOkuma
Hi, is there a way to filter the size of only a single subvisual from a visuals.Compound?I have a Compound that contains [Line(), Text(), Line(), Markers()] and when I try change the v_size the shader doesn't compile. Thanks in advance.
Lorenzo Gaifas
@brisvag
Not sure what you mean there. Can you provide some minimal example?
If you're trying to access the size of the Markers (for example), you can do that with Compound._subvisuals[3].size (3 is the index of the Markers subvisual`)
Jordão Bragantini
@JoOkuma
I'm trying to add a radius to the napari tracks layer. Here you can find the visuals and the filter.
I'm using a filter because that's how the tracks control their tail length.
Jordão Bragantini
@JoOkuma
I want to change the size of markers as the user navigates over the z-slices of the 3d-volume.
Lorenzo Gaifas
@brisvag
ah, I see! On the fork you linked I don't see anything that quickly screams wrong at me, except that you refer to self._current_time in the current_z property, which is probably not what you wanted
is there an issue/pr open in napari so we can discuss there with some context?
loctran15
@loctran15
Hi Guys, is there a way to identify x, y position of a point of an image inside a scenecanvas. The camera I am using is PanZoomCamera. Thank you
Jordão Bragantini
@JoOkuma
I haven't created the issue/pr yet. I forgot to commit the latest change, this line causes the issue
your suggestion of setting the subvisuals size might be better, but requires more change in the napari layer. I might continue the discussion in the napari board
dvsphanindra
@dvsphanindra
Hi all,
I am using the PanZoom camera for displaying a 2D grayscale image. I would like to determine the pixel under the mouse cursor when the button is clicked. What I am able to access are the coordinates in the scene coordinate framework. Also, how do I determine the pixel where the mouse is clicked even when the image is panned or zoomed. Can someone help me with a small code snippet. Thank you.
David Hoese
@djhoese
@dvsphanindra did you ask this question somewhere else? I could have sworn I just answered this question. I'll have to go searching...

@dvsphanindra Here it is: https://stackoverflow.com/questions/70193398/vispy-2d-coordinate-x-y-of-a-point-of-an-image-inside-a-scenecanvas

See my comment there, but please respond here (unless that was your question)

dvsphanindra
@dvsphanindra
@djhoese Thanks for the reply. I have the same requirement as given in the question although I am not the one who asked the question. Also, let me tell you I have already tried the transform with map and imap. I could not figure out what I was missing because I get wrong outputs with both map and imap. Can you please point out the steps to configure the transform to work properly.
David Hoese
@djhoese
@dvsphanindra it would be easiest if you could provide me a minimal example that I could run (with no extra data files) and I could see how the map/imap calls could be updated to work properly
dvsphanindra
@dvsphanindra
@djhoese Here is an example code of what I am trying to do:
I would like to recover the positions of the bright pixels that are generated randomly after clicking on the image visual which I am printing in ImageOnClickRelease() function
import numpy as np
import sys
from vispy import scene

def ImageOnClickRelease(event):
    if event.button == 1:
        print("Position: ", event.pos)
        print(view.camera.center, view.camera.get_state(), "map= ", transform.map(event.pos))

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

view = canvas.central_widget.add_view()
Set 2D camera (the camera will scale to the contents in the scene)

view.camera = scene.PanZoomCamera()
view.camera.flip = (0, 1, 0) # Y-Axis should be flipped for displaying images
canvas.events.mouse_release.connect(ImageOnClickRelease)

img_data = np.zeros((100,100))
points=np.random.randint(100,size=(30,2))
print(points)
for p in points:
    img_data[p[0],p[1]] = 0.5

image_visual = scene.visuals.Image(img_data, cmap='grays', clim=(0,1), parent=view.scene)
view.camera.set_range(margin=0)
transform = image_visual.transforms.get_transform()

if name == 'main' and sys.flags.interactive == 0:
     canvas.app.run()
David Hoese
@djhoese
@dvsphanindra Thanks for the example. It made it much easier to test. In your call to get_transform() pass map_to="canvas" and then .imap(event.pos) will give you the correct X/Y coordinate on the image. So that solves the mouse click -> image location problem, but you say you want to know where the bright pixels are. Are you the user supposed to click on the bright pixels? What is your end goal? I'm confused because couldn't you check the image data without the clicking to find the bright spots?
dvsphanindra
@dvsphanindra
@djhoese Thanks for the suggestion. The code is working now. I am working on pattern recognition wherein after the identification of various pixel groups in an image, the user can get info regarding the object pointed by mouse. I just created a small example to demonstrate my requirement.
Also can you please explain the output of map() and imap(). I have noticed that the pixel info is in the first two coordinates returned by imap(). What are the remaining two coordinates?
David Hoese
@djhoese

@dvsphanindra The transforms are going between coordinate systems. On your screen you have a 2D set of pixels, but in a Visual you could have a 3D coordinate system (ex. Volumes, Meshes, etc), but your ImageVisual is just 2D so the third z coordinate doesn't mean anything regarding that. The pan/zoom camera is kind of 3D because you are zooming in and out, but it is still a 2D view. I don't remember off the top of my head how the pan/zoom camera internally implements that, but same kind of point.

Typically the 4th dimension is a normalization value. Let me see if I can find the documentation on that, but for your application don't worry too much about it

David Hoese
@djhoese
dvsphanindra
@dvsphanindra
@djhoese Thank you I got some idea ;)
cgharib
@cgharib

Hi everyone !

So I'm trying to change two vertices coordinates over time in python and then send this information to OpenGL. I was able to do it in glumpy using :

x = .5*np.cos(totalTime)
program['position'] = np.array([(x, 0.), (-x, 0.)])

In vispy however it has been more complicated. I looked a bit in the code and finally managed to do it using :

x = .5*np.cos(totalTime)
newPos = np.array([(x, 0.), (-x, 0.)])
self.program['position'].base.set_subdata(newPos.astype(np.float32))

So this works but I was wondering about why this is so different and wether it's really the simplest way to do that. Does anyone have an idea ? Thank you !

(I think my variables are quite clear but if not I would be happy to send a more complete source.)

David Hoese
@djhoese
@cgharib It is hard to tell based on what you've provided so far. Something like what you have in glumpy should have worked in vispy. If not then I would have expected self.program['position'][:] = np.array(...) to work. What kind of error, if any, are you getting?
cgharib
@cgharib

Hey. Thanks for your answer.

With :

self.program['position'][:] = np.array([(x, 0.), (-x, 0.)]) #even with .astype(np.float32)

I get the following error :

File "/home/.../vispy/gloo/buffer.py", line 400, in __setitem__
    raise RuntimeError("Cannot set data on Buffer view")
RuntimeError: Cannot set data on Buffer view

Looking in buffer.py I concluded that I had to access to the DataBuffer that is associated with this DataBufferView. Therefore I added .base. Then I found the method set_subdata in DataBuffer. Finally I had to convert my np.float64 x to a np.float32 (because of line 426 in buffer.py).

The relevant variables are instantiated that way (in the __init__ method):

self.program = gloo.Program(vertex, fragment, count=2)
self.program['position'] = [(.5, 0), (-.5, 0)]

And I'm updating the position this way :

class MyCanvas(app.Canvas):
    def __init__....
        ...
        self.timer = app.Timer('auto', self.on_timer)
        self.timer.start()
    def on_timer(self, event):
        totalTime = self.timer.elapsed
        x =...
        newPos =...
        self.program['position'].base.set_subdata(newPos.astype(np.float32))
        self.update()
Kai Mühlbauer
@kmuehlbauer
@cgharib I would have a look into this too. Would you mind creating a minimal reproducible example we could run?
David Hoese
@djhoese
Ok so that error makes sense now that I think about it with [:]. But what do you get with self.program['position'] = np.array(...)?
cgharib
@cgharib
Thanks. So here's the code that works :
from vispy import app, gloo
import numpy as np

vertex = """
attribute vec2 position;

void main() {
    gl_Position = vec4(position, 0., 1.);
}
"""

fragment = """
void main() {
    gl_FragColor = vec4(1., 0., 0., 1.);
}
"""

class MyCanvas(app.Canvas):
    def __init__(self):
        app.Canvas.__init__(self)

        self.program = gloo.Program(vertex, fragment, count=2)
        self.program['position']= [(.5, 0), (-.5, 0)]

        self.timer = app.Timer("auto", self.on_timer)
        self.timer.start()

        self.show()

    def on_timer(self, event):
        totalTime = self.timer.elapsed
        x = .5*np.cos(totalTime)
        newPos = np.array([(x, 0), (-x, 0)])
        self.program['position'].base.set_subdata(newPos.astype(np.float32))
        self.update()

    def on_draw(self, event):
        gloo.clear()
        self.program.draw("lines")

c = MyCanvas()
app.run()

And with

self.program['position'] = newPos

I get the following error :

File "testVispy.py", line 34, in on_timer
    self.program['position'] = newPos
  File "/home/chams/.local/lib/python3.6/site-packages/vispy/gloo/program.py", line 409, in __setitem__
    vbo.set_data(data)
  File "/home/chams/.local/lib/python3.6/site-packages/vispy/gloo/buffer.py", line 381, in set_data
    raise RuntimeError("Cannot set data on buffer view.")
RuntimeError: Cannot set data on buffer view.
David Hoese
@djhoese
@cgharib This is definitely a surprise to me, but I don't have the historic context for why it is this way. A workaround is to reuse a VertexBuffer (or other buffer type) yourself, update the data, then reset that buffer. Like this with _pos:
class MyCanvas(app.Canvas):
    def __init__(self):
        app.Canvas.__init__(self)

        self.program = gloo.Program(vertex, fragment, count=2)
        self._pos = gloo.VertexBuffer()
        self.program['position'] = np.array([[.5, 0], [-.5, 0]], dtype=np.float32)

        self.timer = app.Timer("auto", self.on_timer)
        self.timer.start()

        self.show()

    def on_timer(self, event):
        totalTime = self.timer.elapsed
        x = .5*np.cos(totalTime)
        newPos = np.array([(x, 0), (-x, 0)])
        self._pos.set_data(newPos.astype(np.float32))
        self.program['position'] = self._pos
        self.update()
David Hoese
@djhoese

@almarklein @rougier Any memory why gloo.Program creates a View for each of the buffers? Meaning self.program['position'] is a DataBufferView when the program is created?

@cgharib Actually if you set the VertexBuffer in the __init__ and then do self.program['position'] = newPos.astype(np.float32) then it seems to work. The main problem seems to be that the gloo.Program creation defaults to creating a View. I'm not exactly sure why the original self.program['position'] = works as that should be a View too.

Nicolas P. Rougier
@rougier
Not sure, but maybe this is for handling the case where buffers are only one structured buffer (for example mixing position and color) and the view offers a consistent view...
Almar Klein
@almarklein
No idea ...
cgharib
@cgharib

Hey. Thanks for all your answers. So here's how I would write it based on @djhoese 's code.

import numpy as np
from vispy import app, gloo

vertex = """
attribute vec2 position;

void main() {
    gl_Position = vec4(position, 0., 1.);
}
"""

fragment = """
void main() {
    gl_FragColor = vec4(1.,0.,0.,1.);
}
"""

class MyCanvas(app.Canvas):
    def __init__(self):
        app.Canvas.__init__(self)
        self.program = gloo.Program(vertex, fragment, count=2)

        self.vertexBuffer = gloo.VertexBuffer(np.array([(.5, 0), (-.5, 0)], dtype=np.float32))
        self.program['position'] = self.vertexBuffer

        self.timer = app.Timer('auto', self.on_timer)
        self.timer.start()

        self.show()

    def on_draw(self, event):
        gloo.clear()
        self.program.draw('lines')

    def on_timer(self, event):
        totalTime = self.timer.elapsed
        x = .5*np.cos(totalTime)
        newPos = np.array([(x, 0), (-x, 0)], dtype=np.float32)
        self.vertexBuffer.set_data(newPos)
        self.update()

c = MyCanvas()
app.run()

Does it seem idiomatic to you ? Thanks a lot !

David Hoese
@djhoese
@cgharib I personally would change your timer handler to do self.program['position'] = newPos. It feels more future-proof and avoids the possibility of the VertexBuffer being copied inside the Program and your set_data not having an effect. Hopefully that makes sense. Either way should work so do what feels good to you.
cgharib
@cgharib
I understand. Thanks !
Thomas Doman
@tjjdoman_gitlab
Hello all, I am trying to specify a z position of an EllipseVisual's center so that I can layer it on image visuals, but it seems as if that is not allowed as only the first 2 elements of the passed center are used to create the vertices of the ellipse. Is there something I am missing or does this require an edit?
David Hoese
@djhoese
@tjjdoman_gitlab It looks like you are right that the center point is only 2D. You could try using an STTransform to force the Z position by doing ellipse.transform = STTransform(translate=(0, 0, some_z_shift)). You may also run into issues with drawing order between the Image and Ellipse where you may need to do something like ellipse.order = -5, but see if the Z position works well enough first.
IsolatedSushi2
@IsolatedSushi2
Hey, quick question. Im working with a 3d point cloud. I can't find how to make the camera rotate around a specific point (not the center perse). How can this be done?
David Hoese
@djhoese
@IsolatedSushi2 What camera are you using? And if the point isn't the center, then what is it as far as the camera thinks of it? Or how is it related to the center of the view?