Conversation
|
Hello @kne42! Thanks for updating the PR.
Comment last updated on October 23, 2018 at 00:18 Hours UTC |
1c1aea9 to
dcbe887
Compare
|
What if a layer does not define the notion of 'shape' -- that's very much an image-centric concept. |
|
@royerloic Actually I would like to require some sort of required API that helps us determine the shape of the layer (perhaps even by slice but this may be costly in terms of memory) so that we can show a visual selection rectangle on the gui to allow users to move, scale, and rotate the visual. |
|
Ok, makes sense. Maybe my question really is: what units do we have for 'shape' if the units is pixels of images that would work, assuming that we use the same units for the coordinates of other layers... Important: just as for image layers, other layers can have different shapes, but can be stacked together nevertheless, using the bounding box info... |
|
Ah, perhaps we should instead just require them to provide their |
|
Asking for the shape works, and should not depend on slicing.
You would return the shape as (width, height) and the coordinates
of the points used for drawing would be (x-x0, y-y0) assuming
the bounding box is (x0, y0, width, height) …
Slicing would only display objects that are entirely or intersect with
the viewing plane — unless max projection mode is used in which
case all objects are displayed as projection…
Yeah, just realising that slicing and objects are an interesting topic.
Nothing really hard actually, but very interesting… We can start
simple and see how it goes…
… On 14. Oct 2018, at 19:22, Kira Evans ***@***.***> wrote:
Ah, perhaps we should instead just require them to provide their ndims and some function that returns (x, y, width, height) given a set of indices (like in _set_view_slice)?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#12 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AByMklEFwlWIdAGS9MSSSqyX5kAj72eFks5uk_FZgaJpZM4XbQ_C>.
|
|
why can't we infer the shape to be the min and max of the data? This should be super fast. If we want to allow offsets, we can add |
|
Imagine you ‘mark’ two places in an image,
you can’t use the min and max values for x and y
to define the bounding box, because that would
effectively move these marks —always— on the
borders of the image. You need to know the
boundaries independently of the actual point
locations…
… On 14. Oct 2018, at 20:49, Juan Nunez-Iglesias ***@***.***> wrote:
why can't we infer the shape to be the min and max of the data? This should be super fast. If we want to allow offsets, we can add origin=(0,) * ndim as the default, but settable by new layers.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#12 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AByMks0zOWL2ldGHJ2CvtVhrwNMpIsShks5ulAWvgaJpZM4XbQ_C>.
|
|
Oh you mean because you are doing all this crazy resizing/moving around inside the canvas that I told you was a bad idea? =P |
|
actually it is unrelated.
the problem exists even with just a single layer.
… On 14. Oct 2018, at 20:56, Juan Nunez-Iglesias ***@***.***> wrote:
Oh you mean because you are doing all this crazy resizing/moving around inside the canvas that I told you was a bad idea? =P
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#12 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AByMkvJ8oykrrJIhzGIZW5pig10LoEj9ks5ulAdxgaJpZM4XbQ_C>.
|
|
Ok I'm gonna wait till our meeting to discuss since I feel some drawing is required. =) |
|
The key but subtle difference between an image and a list of points,
is that an image has pixels that completely fill its ‘frame',
whereas a list of points does not necessarily have
points on its ‘frame’ border. For example, you might not always
have a point with x=0 or y=0… So we can’t use min and max
to define the ‘frame’ for list of points, lines etc…,
it must be explicitly provided.
But that’s perfectly fine, that does not cause any trouble,
In fact it avoids problems down the line…
most of the time the frame will correspond to the pixel coordinate
range.
And then this leads to avoiding using a fix coordinate frame
for coordinates for the list of points, but instead we do everything
relative to the frame. Anyway, gets a bit technical but it is
important to get this right from the start. In practice that means
that you could use any range of values [0,1] or [0,width] and it
all works nicely because we use a relative scheme. Makes it
also much easier to have different units like pixels or microns
or whatever…
… On 14. Oct 2018, at 20:58, Juan Nunez-Iglesias ***@***.***> wrote:
Ok I'm gonna wait till our meeting to discuss since I feel some drawing is required. =)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#12 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AByMklwa0coMB649rNSwsj2S-iqiYTkeks5ulAfYgaJpZM4XbQ_C>.
|
0a495ed to
4ee7754
Compare
c9a8e3f to
0d455e6
Compare
0d455e6 to
dd4007a
Compare
|
I'm looking through the PR right now and ran into a problem not sure what I'm missing. When I run the following code the opacity and colormap changes work fine, but I get an error message when trying to change the clims. It's nice that when I change the opacity etc. the gui window automatically updates |
|
Thanks for poking around, you found a bug! There’s a line below
`@clim.setter` that should be `def clim(self, clim):`. I’ll push a fix when
I get back to my laptop which won’t be for a while so if you want you can
go ahead and change it in your branch.
…On Fri, Oct 19, 2018 at 5:20 PM Nicholas Sofroniew ***@***.***> wrote:
I'm looking through the PR right now and ran into a problem not sure what
I'm missing. When I run the following code the opacity and colormap changes
work fine, but I get an error message when trying to change the clims. It's
nice that when I change the opacity etc. the gui window automatically
updates
window = gui.imshow(patch)
layer = window.layers[0]
layer.opacity = .5
layer.colormap = 'viridis'
layer.clim = (0,100)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-54-e8219f68bee2> in <module>()
3 layer.opacity = .5
4 layer.colormap = 'viridis'
----> 5 layer.clim = (0,100)
TypeError: clim() takes 1 positional argument but 2 were given
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#12 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/Ab0F06H9HETghP1-jMKdUJOFyoI7FF78ks5ummxpgaJpZM4XbQ_C>
.
|
|
Thanks! No rush. I also think I've encountered the opacity bug you mentioned at the top of the thread, and saw your chats in vispy. Looks like it is being handled there |
|
Is there a remove layer / delete layer function? Would be nice. Also might be nice to be able to create an empty window, could be with something like Another thing that might be nice is if you pass a list of images Also is it worth including the concept we talked about on thursday where if we call Also unclear to me why |
|
Is there a remove layer / delete layer function? Would be nice.
Yes, right now this is implemented as `Viewer.layers.remove(layer)`.
Also might be nice to create an empty window, could be with something like `window = gui.imshow()`
Good point but this isn’t the PR for that. It’ll come later in a specific PR addressing the API.
|
ok nice, i get it now, it's just like any list, i can use |
…visible
The visibilitychanged slot currently updates the title regardless of the visibility. We are seeing a crash when the viewer is shut down and a signal is sent to the visibilitychanged slot. That executes some code which causes a segfault in the python process[1]. This PR changes the visibility changed slot to only update the title bar if the widget is visible.
[1]
```
* frame #0: 0x0000000115cc96e4 QtWidgets`QWidgetPrivate::reparentFocusWidgets(QWidget*) + 356
frame napari#1: 0x0000000115cb99cf QtWidgets`QWidget::setParent(QWidget*, QFlags<Qt::WindowType>) + 911
frame napari#2: 0x0000000115cb82c0 QtWidgets`QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) + 688
frame napari#3: 0x0000000115d73e5e QtWidgets`QFrame::QFrame(QFramePrivate&, QWidget*, QFlags<Qt::WindowType>) + 14
frame napari#4: 0x0000000115dc3705 QtWidgets`QLabel::QLabel(QWidget*, QFlags<Qt::WindowType>) + 277
frame napari#5: 0x0000000116503189 QtWidgets.abi3.so`Sbk_QLabel_Init(_object*, _object*, _object*) + 1497
frame napari#6: 0x000000010015f84d Python`wrap_init + 12
frame napari#7: 0x0000000100113e64 Python`_PyObject_FastCallDict + 143
frame napari#8: 0x00000001001b17a2 Python`call_function + 439
frame napari#9: 0x00000001001aa46b Python`_PyEval_EvalFrameDefault + 3078
frame napari#10: 0x00000001001b1ee2 Python`_PyEval_EvalCodeWithName + 1638
frame napari#11: 0x00000001001b281b Python`_PyFunction_FastCallDict + 447
frame napari#12: 0x0000000100113e99 Python`_PyObject_FastCallDict + 196
frame napari#13: 0x0000000100113fa3 Python`_PyObject_Call_Prepend + 131
frame napari#14: 0x0000000100113d1e Python`PyObject_Call + 101
frame napari#15: 0x000000010015f7d1 Python`slot_tp_init + 57
frame napari#16: 0x000000010015c782 Python`type_call + 178
frame napari#17: 0x0000000100113e64 Python`_PyObject_FastCallDict + 143
frame napari#18: 0x00000001001141fa Python`_PyObject_FastCallKeywords + 97
frame napari#19: 0x00000001001b17a2 Python`call_function + 439
frame napari#20: 0x00000001001aa4fb Python`_PyEval_EvalFrameDefault + 3222
frame napari#21: 0x00000001001b28e0 Python`_PyFunction_FastCall + 110
frame napari#22: 0x0000000100113e99 Python`_PyObject_FastCallDict + 196
frame napari#23: 0x0000000100113fa3 Python`_PyObject_Call_Prepend + 131
frame napari#24: 0x0000000100113d1e Python`PyObject_Call + 101
frame napari#25: 0x000000011126f146 libpyside2.abi3.5.14.dylib`PySide::SignalManager::callPythonMetaMethod(QMetaMethod const&, void**, _object*, bool) + 534
frame napari#26: 0x000000011126eb77 libpyside2.abi3.5.14.dylib`PySide::SignalManager::qt_metacall(QObject*, QMetaObject::Call, int, void**) + 519
```
Added tests and adjusted events in shapes_mouse_bindings tests in order for event.pos to be supported
* Add white space for images diff * Add missing images to diff * Apply event alt text! Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com> Co-authored-by: Andy Sweet <andrew.d.sweet@gmail.com> Co-authored-by: Kandarp Khandwala <kandarpksk@users.noreply.github.com> * Copy edits and clean up * Remove white space placeholders * Remove typos and white space * Update docs/howtos/layers/shapes.md Co-authored-by: Melissa Weber Mendonça <melissawm@gmail.com> Co-authored-by: isabela-pf <irpf.design@gmail.com> Co-authored-by: Isabela Presedo-Floyd <50221806+isabela-pf@users.noreply.github.com> Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com> Co-authored-by: Andy Sweet <andrew.d.sweet@gmail.com> Co-authored-by: Kandarp Khandwala <kandarpksk@users.noreply.github.com> Co-authored-by: Melissa Weber Mendonça <melissawm@gmail.com>
Introduces a standard for layers, a way to register them as convenience methods on
Viewers, and a better programmatic management system.gui.layers.Layerand callsuper().__init__(visual_node)with their central/controlling visual node_get_shape,_refresh, and propertydata_set_view_slice,_after_set_viewer, and property_qtadd_*methods can be automatically added toViewers by using the function/decoratorgui.layers.add_to_viewergui.layers.LayerListprovides a list-like interface to add and remove layers, as well as providing theswapandreordermethods to programmatically change the rendering order of layersNote: ordering system used in this PR introduces an opacity-related bug: see vispy/vispy#1541