Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
189 changes: 68 additions & 121 deletions examples/notebooks/gridplot_simple.ipynb
Comment thread
ArjunPutcha marked this conversation as resolved.
Comment thread
ArjunPutcha marked this conversation as resolved.

Large diffs are not rendered by default.

60 changes: 38 additions & 22 deletions fastplotlib/layouts/_gridplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ def to_array(a) -> np.ndarray:

class GridPlot(RecordMixin):
def __init__(
self,
shape: Tuple[int, int],
cameras: Union[np.ndarray, str] = "2d",
controllers: Union[np.ndarray, str] = None,
canvas: Union[str, WgpuCanvas, pygfx.Texture] = None,
renderer: pygfx.WgpuRenderer = None,
size: Tuple[int, int] = (500, 300),
**kwargs,
self,
shape: Tuple[int, int],
cameras: Union[np.ndarray, str] = "2d",
controllers: Union[np.ndarray, str] = None,
canvas: Union[str, WgpuCanvas, pygfx.Texture] = None,
renderer: pygfx.WgpuRenderer = None,
size: Tuple[int, int] = (500, 300),
**kwargs,
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
):
"""
A grid of subplots.
Expand Down Expand Up @@ -92,12 +92,35 @@ def __init__(
self.shape
)

if "names" in kwargs.keys():
self.names = to_array(kwargs["names"])
if self.names.shape != self.shape:
raise ValueError(f"subplot names: {self.names} must be in gridplot shape: {self.shape}")
else:
self.names = None
Comment thread
ArjunPutcha marked this conversation as resolved.

if isinstance(controllers, str):
if controllers == "sync":
controllers = np.zeros(
self.shape[0] * self.shape[1], dtype=int
).reshape(self.shape)

# Check if 'names' and 'controllers' both have values; check if values in controller array are strings
if (self.names is not None) and (controllers is not None):
c = to_array(controllers)
if isinstance(c[0, 0], str):
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
idx_async_controllers = np.shape(c)[0]
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
controllers = np.zeros(
self.shape[0] * self.shape[1], dtype=int
).reshape(self.shape)
for positions in product(range(self.shape[0]), range(self.shape[1])):
item = np.argwhere(c == self.names[positions])
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
if len(item) != 0:
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
controllers[positions] = item[0][0]
else:
controllers[positions] = idx_async_controllers
idx_async_controllers += 1

if controllers is None:
controllers = np.arange(self.shape[0] * self.shape[1]).reshape(self.shape)

Expand All @@ -116,8 +139,8 @@ def __init__(
# create controllers if the arguments were integers
if np.issubdtype(controllers.dtype, np.integer):
if not np.all(
np.sort(np.unique(controllers))
== np.arange(np.unique(controllers).size)
np.sort(np.unique(controllers))
== np.arange(np.unique(controllers).size)
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
):
raise ValueError("controllers must be consecutive integers")

Expand All @@ -144,13 +167,6 @@ def __init__(
if renderer is None:
renderer = pygfx.renderers.WgpuRenderer(canvas)

if "names" in kwargs.keys():
self.names = to_array(kwargs["names"])
if self.names.shape != self.shape:
raise ValueError
else:
self.names = None

self.canvas = canvas
self.renderer = renderer

Expand Down Expand Up @@ -226,10 +242,10 @@ def _call_animate_functions(self, funcs: Iterable[callable]):
fn()

def add_animations(
self,
*funcs: Iterable[callable],
pre_render: bool = True,
post_render: bool = False,
self,
*funcs: Iterable[callable],
pre_render: bool = True,
post_render: bool = False,
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
):
"""
Add function(s) that are called on every render cycle.
Expand Down Expand Up @@ -281,7 +297,7 @@ def remove_animation(self, func):
self._animate_funcs_post.remove(func)

def show(
self, autoscale: bool = True, maintain_aspect: bool = None, toolbar: bool = True
self, autoscale: bool = True, maintain_aspect: bool = None, toolbar: bool = True
Comment thread
ArjunPutcha marked this conversation as resolved.
Outdated
):
"""
Begins the rendering event loop and returns the canvas
Expand Down