Tutorial 2: Open a Multiview of Panels
This tutorial shows how to display multiple panels simultaneously using scivianna’s layout system.
Introduction to Layouts
Scivianna provides two layout classes for displaying multiple panels:
Layout |
Description |
|---|---|
|
Two panels split vertically or horizontally with a draggable divider |
|
Multiple panels in a grid with drag-and-drop rearrangement |
Step 1: SplitLayout - Two Panels Side by Side
SplitLayout divides the screen into two areas. You can split vertically (side by side) or horizontally (top and bottom).
from pathlib import Path
from scivianna.slave import ComputeSlave
from scivianna.interface.med_interface import MEDInterface
from scivianna.panel.panel_2d import Panel2D
from scivianna.layout.split import SplitLayout, SplitItem, SplitDirection
from scivianna.constants import GEOMETRY
import scivianna.input_file
# Path to a built-in example MED file
med_file_path = Path(scivianna.input_file.__file__).parent / "power.med"
Vertical Split (Side by Side)
Creates two panels displayed left and right with a vertical divider.
# Create two ComputeSlaves
slave1 = ComputeSlave(MEDInterface)
slave2 = ComputeSlave(MEDInterface)
# Load the same file in both slaves (or different files)
slave1.read_file(med_file_path, GEOMETRY)
slave2.read_file(med_file_path, GEOMETRY)
# Create two Panel2D instances
panel_left = Panel2D(slave=slave1, name="Left Panel")
panel_right = Panel2D(slave=slave2, name="Right Panel")
# Create a SplitItem defining the layout
split_item = SplitItem(
panel_1=panel_left,
panel_2=panel_right,
direction=SplitDirection.VERTICAL, # Side by side
)
# Create the SplitLayout
split_layout = SplitLayout(split_item)
# Display
# split_layout
Horizontal Split (Top and Bottom)
Creates two panels displayed one above the other with a horizontal divider.
# Create the split item with horizontal direction
split_item_h = SplitItem(
panel_1=panel_left,
panel_2=panel_right,
direction=SplitDirection.HORIZONTAL, # Top and bottom
)
# Create the SplitLayout
split_layout_h = SplitLayout(split_item_h)
# Display
# split_layout_h
SplitLayout Features
Draggable divider: Click and drag the divider to resize panels
Panel switching: Click on panel icons in the sidebar to switch between panels
Duplication: Use the duplicate button to split a panel further (creating nested splits)
Save/Restore: Layouts can be saved to and restored from zip files
Step 2: Nested Splits - Multiple Panels
SplitItem can be nested to create more complex layouts with multiple panels.
# Create three slaves and panels
slave_a = ComputeSlave(MEDInterface)
slave_b = ComputeSlave(MEDInterface)
slave_c = ComputeSlave(MEDInterface)
slave_a.read_file(med_file_path, GEOMETRY)
slave_b.read_file(med_file_path, GEOMETRY)
slave_c.read_file(med_file_path, GEOMETRY)
panel_a = Panel2D(slave=slave_a, name="Panel A")
panel_b = Panel2D(slave=slave_b, name="Panel B")
panel_c = Panel2D(slave=slave_c, name="Panel C")
# Create nested split item:
# +----------+----------+
# | | |
# | Panel A | Panel B |
# | | |
# +----------+----------+
# | |
# | Panel C │
# | |
# +----------+----------+
inner_split = SplitItem(
panel_1=panel_a,
panel_2=panel_b,
direction=SplitDirection.VERTICAL, # A | B
)
# Actually for 3 panels we need a different approach:
# Left: Panel A (top/bottom split with Panel C)
# Right: Panel B
nested_split = SplitItem(
panel_1=inner_split,
panel_2=panel_c,
direction=SplitDirection.HORIZONTAL, # A over C
)
nested_layout = SplitLayout(nested_split)
# nested_layout/
Step 3: GridStackLayout - Multiple Panels in a Grid
GridStackLayout provides a more flexible grid-based layout with drag-and-drop rearrangement.
from scivianna.layout.gridstack import GridStackLayout
# Create four slaves and panels
slaves = [
ComputeSlave(MEDInterface) for _ in range(4)
]
panels = {}
for i, slave in enumerate(slaves):
slave.read_file(med_file_path, GEOMETRY)
panels[f"Grid Panel {i}"] = Panel2D(slave=slave, name=f"Grid Panel {i}")
# Defining the panels bounds:
# +----------+----------+
# | | |
# | 0 | 1 |
# | | |
# +----------+----------+
# | | |
# | 2 | 3 |
# | | |
# +----------+----------+
bounds_x = {
"Grid Panel 0": [0, 4],
"Grid Panel 1": [5, 9],
"Grid Panel 2": [0, 4],
"Grid Panel 3": [5, 9]
}
bounds_y = {
"Grid Panel 0": [0, 4],
"Grid Panel 1": [0, 4],
"Grid Panel 2": [5, 9],
"Grid Panel 3": [5, 9]
}
# Create a GridStackLayout with the panels
grid_layout = GridStackLayout(
visualisation_panels = panels,
bounds_x = bounds_x,
bounds_y = bounds_y
)
# Display
# grid_layout
GridStackLayout Features
Drag-and-drop: Drag panel borders to resize cells
Resizable grid: Right-click on a cell to adjust rows/columns
Panel switching: Click on panel icons in the sidebar to switch between panels
Save/Restore: Layouts can be saved to and restored from zip files
Step 4: Save and Restore Layouts
Layouts can be saved to zip files and restored later.
# Save the layout to a zip file
# split_layout.save_to_zip("my_layout.zip", include_files=True)
# Restore the layout from a zip file
# restored_layout = SplitLayout.restore_from_zip(
# "my_layout.zip",
# include_files=True,
# )
Step 5: Synchronized Fields
Multiple panels can synchronize their displayed field when the sync_field argument is set at True.
# Create two panels sharing the same slave
shared_slave = ComputeSlave(MEDInterface)
shared_slave.read_file(med_file_path, GEOMETRY)
panel_sync1 = Panel2D(slave=shared_slave, name="Sync Panel 1")
panel_sync2 = Panel2D(slave=shared_slave, name="Sync Panel 2")
panel_sync1.sync_field = True
panel_sync2.sync_field = True
# When you change the field in one panel, both update
sync_split = SplitItem(
panel_1=panel_sync1,
panel_2=panel_sync2,
direction=SplitDirection.VERTICAL,
)
sync_layout = SplitLayout(sync_split)
# sync_layout
Summary
In this tutorial, you learned:
SplitLayout: Two-panel layouts with draggable dividers — vertical (side by side) and horizontal (stacked)
Nested splits: Building complex multi-panel layouts by nesting
SplitIteminstancesGridStackLayout: Flexible multi-panel grids with drag-and-drop resizing and configurable cell bounds
Save/Restore: Persisting layout configurations to zip files with
save_to_zip()andrestore_from_zip()Field synchronization: Linking field selections across panels using
sync_field=True
Next Steps
Tutorial 3: 2D-1D Panel Interactions — Link 2D geometry views with 1D line plots
Tutorial 4: Developing an Interface (Dev) — Create custom data interfaces