Skip to content

Commit e5a818a

Browse files
authored
Refactor z-order to ensure axes are on top (#906)
* Only auto-offset images, and push back instead of forward * remove unnecessary use of offset * restore thin line * restore gridplot * new screenshots * add examples * update examples again? * remove screenshots added in wrong plance * better blending for iris scatter example
1 parent 75ff892 commit e5a818a

File tree

12 files changed

+57
-55
lines changed

12 files changed

+57
-55
lines changed

examples/gridplot/gridplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@
3030
# See the "JupyterLab and IPython" section in the user guide
3131
if __name__ == "__main__":
3232
print(__doc__)
33-
fpl.loop.run()
33+
fpl.loop.run()

examples/scatter/scatter_colorslice_iris.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
data=data[:, :-1],
2424
sizes=6,
2525
alpha=0.7,
26-
colors=colors # use colors from the list of strings
26+
alpha_mode="weighted_blend", # blend overlapping dots
27+
colors=colors, # use colors from the list of strings
2728
)
2829

2930
figure.show()
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

fastplotlib/graphics/_axes.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,22 @@ def __init__(
191191
)
192192

193193
# create ruler for each dim
194-
self._x = pygfx.Ruler(alpha_mode="solid", **x_kwargs)
195-
self._y = pygfx.Ruler(alpha_mode="solid", **y_kwargs)
196-
self._z = pygfx.Ruler(alpha_mode="solid", **z_kwargs)
194+
self._x = pygfx.Ruler(
195+
alpha_mode="solid", render_queue=RenderQueue.axes, **x_kwargs
196+
)
197+
self._y = pygfx.Ruler(
198+
alpha_mode="solid", render_queue=RenderQueue.axes, **y_kwargs
199+
)
200+
self._z = pygfx.Ruler(
201+
alpha_mode="solid", render_queue=RenderQueue.axes, **z_kwargs
202+
)
197203

198204
# We render the lines and ticks as solid, but enable aa for text for prettier glyphs
199205
for ruler in self._x, self._y, self._z:
206+
ruler.line.material.depth_compare = "<="
207+
ruler.points.material.depth_compare = "<="
208+
ruler.text.material.depth_compare = "<="
200209
ruler.text.material.alpha_mode = "auto"
201-
ruler.text.material.render_queue = RenderQueue.auto + 50
202210
ruler.text.material.aa = True
203211

204212
self._offset = offset

fastplotlib/graphics/image.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,6 @@ def add_linear_selector(
324324

325325
self._plot_area.add_graphic(selector, center=False)
326326

327-
# place selector above this graphic
328-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
329-
330327
return selector
331328

332329
def add_linear_region_selector(
@@ -402,9 +399,6 @@ def add_linear_region_selector(
402399

403400
self._plot_area.add_graphic(selector, center=False)
404401

405-
# place above this graphic
406-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
407-
408402
return selector
409403

410404
def add_rectangle_selector(
@@ -447,9 +441,6 @@ def add_rectangle_selector(
447441

448442
self._plot_area.add_graphic(selector, center=False)
449443

450-
# place above this graphic
451-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
452-
453444
return selector
454445

455446
def add_polygon_selector(
@@ -485,7 +476,4 @@ def add_polygon_selector(
485476

486477
self._plot_area.add_graphic(selector, center=False)
487478

488-
# place above this graphic
489-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
490-
491479
return selector

fastplotlib/graphics/line.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def __init__(
9696

9797
if thickness < 1.1:
9898
MaterialCls = pygfx.LineThinMaterial
99+
aa = True
99100
else:
100101
MaterialCls = pygfx.LineMaterial
101102

@@ -110,6 +111,7 @@ def __init__(
110111
color=self.colors,
111112
pick_write=True,
112113
thickness_space=self.size_space,
114+
depth_compare="<=",
113115
)
114116
else:
115117
material = MaterialCls(
@@ -118,6 +120,7 @@ def __init__(
118120
color_mode="vertex",
119121
pick_write=True,
120122
thickness_space=self.size_space,
123+
depth_compare="<=",
121124
)
122125
geometry = pygfx.Geometry(
123126
positions=self._data.buffer, colors=self._colors.buffer
@@ -179,9 +182,6 @@ def add_linear_selector(
179182

180183
self._plot_area.add_graphic(selector, center=False)
181184

182-
# place selector above this graphic
183-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
184-
185185
return selector
186186

187187
def add_linear_region_selector(
@@ -238,9 +238,6 @@ def add_linear_region_selector(
238238

239239
self._plot_area.add_graphic(selector, center=False)
240240

241-
# place selector below this graphic
242-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] - 1)
243-
244241
# PlotArea manages this for garbage collection etc. just like all other Graphics
245242
# so we should only work with a proxy on the user-end
246243
return selector

fastplotlib/graphics/line_collection.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,6 @@ def add_linear_selector(
378378

379379
self._plot_area.add_graphic(selector, center=False)
380380

381-
# place selector above this graphic
382-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)
383-
384381
return selector
385382

386383
def add_linear_region_selector(
@@ -435,9 +432,6 @@ def add_linear_region_selector(
435432

436433
self._plot_area.add_graphic(selector, center=False)
437434

438-
# place selector below this graphic
439-
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] - 1)
440-
441435
# PlotArea manages this for garbage collection etc. just like all other Graphics
442436
# so we should only work with a proxy on the user-end
443437
return selector

fastplotlib/graphics/scatter.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,7 @@ def __init__(
9797
aa = kwargs.get("alpha_mode", "auto") in ("blend", "weighted_blend")
9898

9999
geo_kwargs = {"positions": self._data.buffer}
100-
material_kwargs = dict(
101-
pick_write=True,
102-
aa=aa,
103-
)
100+
material_kwargs = dict(pick_write=True, aa=aa, depth_compare="<=")
104101
self._size_space = SizeSpace(size_space)
105102

106103
if uniform_color:

fastplotlib/layouts/_plot_area.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from ._utils import create_controller
1212
from ..graphics._base import Graphic
13+
from ..graphics import ImageGraphic
1314
from ..graphics.selectors._base_selector import BaseSelector
1415
from ._graphic_methods_mixin import GraphicMethodsMixin
1516
from ..legends import Legend
@@ -394,6 +395,29 @@ def remove_animation(self, func):
394395
if func in self._animate_funcs_post:
395396
self._animate_funcs_post.remove(func)
396397

398+
def _sort_images_by_depth(self):
399+
"""
400+
In general, we want to avoid setting the offset of a graphic, because the
401+
z-dimension may actually mean something; we cannot know whether the user is
402+
building a 3D scene or not. We could check whether the 3d dimension of line/point data
403+
is all zeros, but maybe this is intended, and *other* graphics in the same scene
404+
may be actually 3D. We could check camera.fov being zero, but maybe the user
405+
switches to a 3D camera later, or uses a 3D orthographic camera.
406+
407+
The one exception, kindof, is images, which are inherently 2D, and for which
408+
layering helps a lot to get things rendered correctly. So we basically layer the
409+
images, in the order that they were added, pushing older images backwards (away
410+
from the camera).
411+
"""
412+
count = 0
413+
for graphic in self._graphics:
414+
if isinstance(graphic, ImageGraphic):
415+
count += 1
416+
auto_depth = -count
417+
user_changed_depth = graphic.offset[2] % 1 > 0.0 # i.e. is not integer
418+
if not user_changed_depth:
419+
graphic.offset = (*graphic.offset[:-1], auto_depth)
420+
397421
def add_graphic(self, graphic: Graphic, center: bool = True):
398422
"""
399423
Add a Graphic to the scene
@@ -416,10 +440,8 @@ def add_graphic(self, graphic: Graphic, center: bool = True):
416440

417441
self._add_or_insert_graphic(graphic=graphic, center=center, action="add")
418442

419-
if self.camera.fov == 0:
420-
# for orthographic positions stack objects along the z-axis
421-
# for perspective projections we assume the user wants full 3D control
422-
graphic.offset = (*graphic.offset[:-1], len(self))
443+
if isinstance(graphic, ImageGraphic):
444+
self._sort_images_by_depth()
423445

424446
def insert_graphic(
425447
self,
@@ -458,17 +480,14 @@ def insert_graphic(
458480
graphic=graphic, center=center, action="insert", index=index
459481
)
460482

461-
if self.camera.fov == 0:
462-
# for orthographic positions stack objects along the z-axis
463-
# for perspective projections we assume the user wants full 3D control
464-
if auto_offset:
465-
graphic.offset = (*graphic.offset[:-1], index)
483+
if isinstance(graphic, ImageGraphic):
484+
self._sort_images_by_depth()
466485

467486
def _add_or_insert_graphic(
468487
self,
469488
graphic: Graphic,
470489
center: bool = True,
471-
action: str = Literal["insert", "add"],
490+
action: Literal["insert", "add"] = "add",
472491
index: int = 0,
473492
):
474493
"""Private method to handle inserting or adding a graphic to a PlotArea."""

0 commit comments

Comments
 (0)