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
Eric Younkin
@ericgyounkin
I should also mention that I am getting close to having a real interactive 3d scatter plot widget, not sure if that is something that is worth trying to add to Vispy. It might be more code than you want.
David Hoese
@djhoese
@ericgyounkin How does that differ from the scatter plot available through the plotting API? Oh duh, ours is only 2D, right? A 3D implementation would be appreciated.
qaz10102030
@qaz10102030
Hi all, i want do the real-time object tracking use vispy. i use regionprops function in scipy to get the bbox information. does vispy have add_patch function like plt and opencv or any suggest or example, thanks!
David Hoese
@djhoese
@qaz10102030 No. You would want to either create a LineVisual to create a simple series of lines or create a RectangleVisual. I've never done what you're trying to do so feel free to tell me if I'm missing something important here.
qaz10102030
@qaz10102030
OK, i got it. Thank you!
black banana
@blackbanana_gitlab
can you please recommend resources for learning vispy
David Hoese
@djhoese

@blackbanana_gitlab What are you trying to accomplish? Everything we have is described here: https://vispy.org/

Admittedly it needs a lot of work. I would suggest as a beginner to use the SceneCanvas and look at the Gallery of examples for the "Scene". There are also resources linked on our website about OpenGL understanding the basics of that.

martianmartin
@martianmartin
Greeting! I would like to synchronize the x-axis of two plots, so that when I drag one, the other moves as well. I am using the plotting api. After some digging I found the _process_mouse_event() method in SceneCanvas, which finds the VisualNode at event.pos and passes it the event. I tried passing the event to both of the desired ViewBox objects found in VisualNode._visual_ids, but only the second one was effected... Should I be taking a different approach to implementing this functionality or am I on the right track? Please advise. Thanks in advance!
David Hoese
@djhoese
@martianmartin I'm not sure we've had anyone successfully share axes with vispy plotting yet (I personally don't use the plotting API for my work so little experience). Looking at the code, I see there are ways it could be implemented inside vispy in a better way. As for making it work with vispy as-is, using mouse events doesn't seem wrong (I can't think of a better way off the top of my head). Is it possible for you to show me a minimal example of what you're doing?
martianmartin
@martianmartin
@djhoese
def _process_mouse_event(self, event, override_picked=False):
        prof = Profiler()  # noqa
        next_picked = None # sync hack
        deliver_types = ['mouse_press', 'mouse_wheel']
        if self._send_hover_events:
            deliver_types += ['mouse_move']

        picked = self._mouse_handler if not override_picked else override_picked
        if picked is None:
            if event.type in deliver_types:
                picked = self.visual_at(event.pos)

        # NOTE: hack to sync other ViewBox, should check a sync dict or parameter of VisualNodes instead
        if type(picked) == ViewBox and not override_picked:
            next_picked = VisualNode._visual_ids[33]

        # No visual to handle this event; bail out now
        if picked is None:
            return

        # Create an event to pass to the picked visual
        scene_event = SceneMouseEvent(event=event, visual=picked)

        # Deliver the event
        if override_picked: # we know ViewBox handles event directly so don't need to search parents and don't want to change _mouse_handler
            getattr(picked.events, event.type)(scene_event)
        elif picked == self._mouse_handler:
            # If we already have a mouse handler, then no other node may
            # receive the event
            if event.type == 'mouse_release':
                self._mouse_handler = None
            getattr(picked.events, event.type)(scene_event)
        else:
            # If we don't have a mouse handler, then pass the event through
            # the chain of parents until a node accepts the event.
            while picked is not None:
                getattr(picked.events, event.type)(scene_event)
                if scene_event.handled:
                    if event.type == 'mouse_press':
                        self._mouse_handler = picked
                    break
                if event.type in deliver_types:
                    # events that are not handled get passed to parent
                    picked = picked.parent
                    scene_event.visual = picked
                else:
                    picked = None

        # If something in the scene handled the scene_event, then we mark
        # the original event accordingly.
        event.handled = scene_event.handled

        if next_picked: # propagate to synced node
            self._process_mouse_event(event, override_picked=next_picked)
Apologize for the large message, if there's another way I should share please let me know. Anyways I hacked this together to test the approach and it's working fine. I think a non hard-coded approach may be to add an attribute to the VisualNode that we want to sync that includes the other Node(s) which are synced to it, then simply to propagate the event as shown. Thoughts?
martianmartin
@martianmartin

For context my top level looks like this:

from vispy import plot as vp
...
fig = vp.Fig(size=(800, 800), show=False)

ohlc = fig[0, 0].ohlc_plot((x, o, h, l, c), line_pos, symbol='c', title='BTC/USD 1 Minute Candles',
                      xlabel='Current (pA)', ylabel='Membrane Potential (mV)')
lines_plot = fig[1, 0].plot((x, c))

grid = vp.visuals.GridLines(color=(0, 0, 0, 0.5))
grid.set_gl_state('translucent')
fig[0, 0].view.add(grid)

This results in two Viewbox's being added to the SceneCanvas which contain the plots to be synced

David Hoese
@djhoese

@martianmartin Ok, so that hack works for you right now? I'm not sure I follow the details of this, but is the basic issue that the mouse event handler is finding the "picked" AxisVisual/Widget and call its mouse handler but it never "finds" the other axis visual? Oh or is it not the AxisVisual's mouse handler that is called but the ViewBox and the AxisVisual is responding to those changes? I'm trying to think of other ways this could be done.

Side node: Don't do if type(picked) == ViewBoxand instead do if isinstance(picked, ViewBox).

martianmartin
@martianmartin
@djhoese This hack works for now, I just wanted to check if there was some obviously better way that I was missing as I'm new to this library. Thanks for your feedback!
David Hoese
@djhoese
@kmuehlbauer have you done anything like shared axes in vispy? ^
Kai Mühlbauer
@kmuehlbauer
Not that I recall. But if, I think I would have done similar things.
Thomas Doman
@tjjdoman_gitlab

Hello I am having a strange issue with Canvas.render(). I am creating a canvas with scene.SceneCanvas and then a view with canvas.central_widget.add_view() and placing image visuals withing that view. I then attach some vert filters to position the image visuals and some frag filters to correct their color and alter the alpha channel to blend the seams. My final view looks like the first image.

However once I try to render the canvas to the cpu it seems as if all of the frag filters are removed (notice the seams around the "H2"). I wonder if it is something to do with the order I apply my filters and if the rendering is happening before these filters are applied. If so is there a way to specify at which point in the pipeline the rendering happens? Thanks for the help!

image.png
^^^final view before rendering
image after rendering vvv
image.png
David Hoese
@djhoese

@tjjdoman_gitlab I think we need more to go on. When you talk about calling .render(), you are then saving that array to an image on disk? When you say "vert filters" and "frag filters", how exactly are you applying these? Is it possible for you to show us a minimal example?

It is hard to tell the difference between the images since they are different sizes...and I don't know what I'm looking at

Thomas Doman
@tjjdoman_gitlab
ok I figured I would check in case there was an obvious solution. I will make an example. Thanks
David Hoese
@djhoese
@tjjdoman_gitlab what version of vispy are you using?
Thomas Doman
@tjjdoman_gitlab
'0.8.1'
David Hoese
@djhoese
ok, darn
Thomas Doman
@tjjdoman_gitlab

@djhoese Here is a minimal example of the issue I am seeing:


from vispy.visuals.transforms import MatrixTransform
import numpy as np
import matplotlib.pyplot as plt
from vispy import scene
import vispy
vispy.use('pyqt5')

images = np.zeros(shape=(2, 2, 400, 400, 4), dtype=np.uint8)
images[..., 3] = 255
images[1, 1, -200:, :, 3] = 100
images[1, 1, :, -200:, 3] = 100
images[1, 0, -200:, :, 3] = 100
images[0, 1, :, -200:, 3] = 100

images[0,0,..., 0] = 255
images[1,0,..., 1] = 255
images[0,1,..., 2] = 255
images[1,1,...,:3] = 255

s = scene.SceneCanvas(size=(600, 600), title='actual')
view = s.central_widget.add_view()
# if i comment out the below line my image changes to a gray square in the corner
view.camera = 'panzoom'

im = np.ndarray((2,2), dtype=object)
for c, i in enumerate(np.ndindex(im.shape)):
    im[i] = scene.visuals.Image(images[i], parent=view.scene)
    imX = im[i]
    mat = np.eye(4)
    mat[3, 1] = -i[0] * 200
    mat[3, 0] = -i[1] * 200
    mat[3, 2] = 3 - c
    imX.transform = MatrixTransform(mat)
    imX.order = c
    imX.update()
s.show()
view.camera.set_range(x=(-200, 400), y=(-200, 400))

render = imX.parent.canvas.render()
plt.figure()
plt.imshow(render)

The image show on the canvas (left) shows 9 different color squares, while the rendered image (right) only shows 3 squares and 3 rectangles.
Thank you for any advice!

image.png
David Hoese
@djhoese
@tjjdoman_gitlab This definitely has something to do with ordering. If I reverse the order .order = -c then I get the same image for both vispy and imshow:
image.png
@tjjdoman_gitlab I don't know why, but changing your last Z matrix entry to mat[3, 2] = -c * 100 makes it work
David Hoese
@djhoese
if I do anything less than 35 in the line then it isn't the same and the red covers more than expected. Must be some Z level precision
martianmartin
@martianmartin
@djhoese I am struggling to grok the dynamics of the SceneCanvas. Specifically I want to implement autoscale of y-axis so that when I pan left and right, the y-axis automatically adjusts to fit the data in my plot widget. More generally though, I am wondering if you can briefly explain or point to any documentation which relates the SceneCanvas to the following key objects: ViewBox, Camera, Visuals, and Transform system. Thanks!
David Hoese
@djhoese

@martianmartin There isn't much beyond the examples in the repository and the gallery: https://vispy.org/gallery/scene/index.html

That is a long and broad list of topics that you've asked about though. You've basically asked for how all of VisPy works. With the plotting API, things are even less documented as that interface was never really "finished" by the people who originally wrote it and we've been working more on improving the Visuals and SceneCanvas rather than plotting. If you have a specific question about how they interact I can try to answer as much as I can.

David Hoese
@djhoese
@kmuehlbauer or @almarklein or anyone, if you can provide some ideas for speeding this up (the user's use case or the TextVisual's handling in general) I'd appreciate the help: https://stackoverflow.com/questions/69871325/text-labels-in-image-pixel-coordinate-system-in-vispy
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.