Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/gridplot/gridplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@
# See the "JupyterLab and IPython" section in the user guide
if __name__ == "__main__":
print(__doc__)
fpl.loop.run()
fpl.loop.run()
3 changes: 2 additions & 1 deletion examples/scatter/scatter_colorslice_iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
data=data[:, :-1],
sizes=6,
alpha=0.7,
colors=colors # use colors from the list of strings
alpha_mode="weighted_blend", # blend overlapping dots
colors=colors, # use colors from the list of strings
)

figure.show()
Expand Down
4 changes: 2 additions & 2 deletions examples/screenshots/line_collection_slicing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions examples/screenshots/scatter_colorslice_iris.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 12 additions & 4 deletions fastplotlib/graphics/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,22 @@ def __init__(
}

# create ruler for each dim
self._x = pygfx.Ruler(alpha_mode="solid", **x_kwargs)
self._y = pygfx.Ruler(alpha_mode="solid", **y_kwargs)
self._z = pygfx.Ruler(alpha_mode="solid", **z_kwargs)
self._x = pygfx.Ruler(
alpha_mode="solid", render_queue=RenderQueue.axes, **x_kwargs
)
self._y = pygfx.Ruler(
alpha_mode="solid", render_queue=RenderQueue.axes, **y_kwargs
)
self._z = pygfx.Ruler(
alpha_mode="solid", render_queue=RenderQueue.axes, **z_kwargs
)

# We render the lines and ticks as solid, but enable aa for text for prettier glyphs
for ruler in self._x, self._y, self._z:
ruler.line.material.depth_compare = "<="
ruler.points.material.depth_compare = "<="
ruler.text.material.depth_compare = "<="
ruler.text.material.alpha_mode = "auto"
ruler.text.material.render_queue = RenderQueue.auto + 50
ruler.text.material.aa = True

self._offset = offset
Expand Down
12 changes: 0 additions & 12 deletions fastplotlib/graphics/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,6 @@ def add_linear_selector(

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

# place selector above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector

def add_linear_region_selector(
Expand Down Expand Up @@ -402,9 +399,6 @@ def add_linear_region_selector(

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

# place above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector

def add_rectangle_selector(
Expand Down Expand Up @@ -447,9 +441,6 @@ def add_rectangle_selector(

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

# place above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector

def add_polygon_selector(
Expand Down Expand Up @@ -485,7 +476,4 @@ def add_polygon_selector(

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

# place above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector
9 changes: 3 additions & 6 deletions fastplotlib/graphics/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def __init__(

if thickness < 1.1:
MaterialCls = pygfx.LineThinMaterial
aa = True
else:
MaterialCls = pygfx.LineMaterial

Expand All @@ -110,6 +111,7 @@ def __init__(
color=self.colors,
pick_write=True,
thickness_space=self.size_space,
depth_compare="<=",
)
else:
material = MaterialCls(
Expand All @@ -118,6 +120,7 @@ def __init__(
color_mode="vertex",
pick_write=True,
thickness_space=self.size_space,
depth_compare="<=",
)
geometry = pygfx.Geometry(
positions=self._data.buffer, colors=self._colors.buffer
Expand Down Expand Up @@ -179,9 +182,6 @@ def add_linear_selector(

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

# place selector above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector

def add_linear_region_selector(
Expand Down Expand Up @@ -238,9 +238,6 @@ def add_linear_region_selector(

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

# place selector below this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] - 1)

# PlotArea manages this for garbage collection etc. just like all other Graphics
# so we should only work with a proxy on the user-end
return selector
Expand Down
6 changes: 0 additions & 6 deletions fastplotlib/graphics/line_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,6 @@ def add_linear_selector(

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

# place selector above this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] + 1)

return selector

def add_linear_region_selector(
Expand Down Expand Up @@ -435,9 +432,6 @@ def add_linear_region_selector(

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

# place selector below this graphic
selector.offset = selector.offset + (0.0, 0.0, self.offset[-1] - 1)

# PlotArea manages this for garbage collection etc. just like all other Graphics
# so we should only work with a proxy on the user-end
return selector
Expand Down
5 changes: 1 addition & 4 deletions fastplotlib/graphics/scatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,7 @@ def __init__(
aa = kwargs.get("alpha_mode", "auto") in ("blend", "weighted_blend")

geo_kwargs = {"positions": self._data.buffer}
material_kwargs = dict(
pick_write=True,
aa=aa,
)
material_kwargs = dict(pick_write=True, aa=aa, depth_compare="<=")
self._size_space = SizeSpace(size_space)

if uniform_color:
Expand Down
39 changes: 29 additions & 10 deletions fastplotlib/layouts/_plot_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from ._utils import create_controller
from ..graphics._base import Graphic
from ..graphics import ImageGraphic
from ..graphics.selectors._base_selector import BaseSelector
from ._graphic_methods_mixin import GraphicMethodsMixin
from ..legends import Legend
Expand Down Expand Up @@ -394,6 +395,29 @@ def remove_animation(self, func):
if func in self._animate_funcs_post:
self._animate_funcs_post.remove(func)

def _sort_images_by_depth(self):
"""
In general, we want to avoid setting the offset of a graphic, because the
z-dimension may actually mean something; we cannot know whether the user is
building a 3D scene or not. We could check whether the 3d dimension of line/point data
is all zeros, but maybe this is intended, and *other* graphics in the same scene
may be actually 3D. We could check camera.fov being zero, but maybe the user
switches to a 3D camera later, or uses a 3D orthographic camera.

The one exception, kindof, is images, which are inherently 2D, and for which
layering helps a lot to get things rendered correctly. So we basically layer the
images, in the order that they were added, pushing older images backwards (away
from the camera).
"""
count = 0
for graphic in self._graphics:
if isinstance(graphic, ImageGraphic):
count += 1
auto_depth = -count
user_changed_depth = graphic.offset[2] % 1 > 0.0 # i.e. is not integer
if not user_changed_depth:
graphic.offset = (*graphic.offset[:-1], auto_depth)

def add_graphic(self, graphic: Graphic, center: bool = True):
"""
Add a Graphic to the scene
Expand All @@ -416,10 +440,8 @@ def add_graphic(self, graphic: Graphic, center: bool = True):

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

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

def insert_graphic(
self,
Expand Down Expand Up @@ -458,17 +480,14 @@ def insert_graphic(
graphic=graphic, center=center, action="insert", index=index
)

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

def _add_or_insert_graphic(
self,
graphic: Graphic,
center: bool = True,
action: str = Literal["insert", "add"],
action: Literal["insert", "add"] = "add",
index: int = 0,
):
"""Private method to handle inserting or adding a graphic to a PlotArea."""
Expand Down
5 changes: 1 addition & 4 deletions fastplotlib/legends/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ def __init__(
# construct Line WorldObject
data = np.array([[0, 0, 0], [3, 0, 0]], dtype=np.float32)

material = pygfx.LineMaterial

self._line_world_object = pygfx.Line(
geometry=pygfx.Geometry(positions=data),
material=material(
material=pygfx.LineMaterial(
alpha_mode="blend",
render_queue=RenderQueue.overlay,
thickness=8,
Expand Down Expand Up @@ -112,7 +110,6 @@ def __init__(
self._label_world_object.world.x = position[0] + 10

self.world_object.world.y = position[1]
self.world_object.world.z = 2

self.world_object.add_event_handler(
partial(self._highlight_graphic, graphic), "click"
Expand Down
7 changes: 4 additions & 3 deletions fastplotlib/utils/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class RenderQueue(IntEnum):
auto = 2600
transparent = 3000
overlay = 4000
# For selectors we use a render_queue of 3500, which is at the end of what is considered the group of transparent objects.
# So it's rendered later than the normal scene (2000 - 3000), but before overlays like legends and tooltips.
selector = 3500
# For axes and selectors we use a higher render_queue, so they get rendered later than
# the graphics. Axes (rulers) have depth_compare '<=' and selectors don't compare depth.
axes = 3400 # still in 'object' group
selector = 3600 # considered in 'overlay' group
Loading