Download this notebook from GitHub (right-click to download).

import panel as pn

from panel.layout.gridstack import GridStack


The GridStack layout allows arranging multiple Panel objects in a grid using a simple API to assign objects to individual grid cells or to a grid span. Other layout containers function like lists, but a GridSpec has an API similar to a 2D array, making it possible to use 2D assignment to populate, index, and slice the grid.


For layout and styling related parameters see the customization user guide.

  • allow_resize (bool): Whether to allow resizing grid cells.

  • allow_drag (bool): Whether to allow dragging grid cells.

  • ncols (int): Allows specifying a fixed number of columns (otherwise grid expands to match assigned objects)

  • nrows (int): Allows specifying a fixed number of rows (otherwise grid expands to match assigned objects)

  • mode (str): Whether to ‘warn’, ‘error’, or simply ‘override’ on overlapping assignment

  • objects (list): The list of objects to display in the GridSpec. Should not generally be modified directly except when replaced in its entirety.

A GridStack can be created either with a fixed size (the default) or with responsive sizing. In both cases the GridSpec will modify the contents to ensure the objects fill the grid cells assigned to them.

To demonstrate this behavior, let us declare a responsively sized GridStack and then assign Spacer objects with distinct colors. We populate a 6x12 grid with these objects and display it:

gstack = GridStack(sizing_mode='stretch_both')

gstack[ : , 0: 3] = pn.Spacer(background='red',    margin=0)
gstack[0:2, 3: 9] = pn.Spacer(background='green',  margin=0)
gstack[2:4, 6:12] = pn.Spacer(background='orange', margin=0)
gstack[4:6, 3:12] = pn.Spacer(background='blue',   margin=0)
gstack[0:2, 9:12] = pn.Spacer(background='purple', margin=0)


As we can see the fixed-size GridStack fills the 800x600 pixels assigned to it and each of the Spacer objects has been resized to fill the alloted grid cells, including the empty grid cell in the center. A convenient way to get an overview of the grid without rendering it is to display the grid property, which returns an array showing which grid cells have been filled:

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

In addition to assigning objects to the grid we can also index the grid:

pn.Row(gstack[2, 2], width=400, height=400)

And select a subregion using slicing semantics:

gstack[0, 1:]

The behavior when replacing existing grid cells can be controlled using the mode option. By default the GridStack will warn when assigning to one or more grid cells that are already occupied. The behavior may be changed to either error or override silently, by setting mode='error' or mode='override' respectively.

Fixed size grids#

We can also set explicit width and height values on a GridStack. Just like in the responsive mode, the GridStack will automatically set the appropriate sizing values on the grid contents to fill the space correctly. This means that when we resize a component and the state is synced with Python the new size is computed there and only then is the display updated:

import holoviews as hv
import holoviews.plotting.bokeh

from bokeh.plotting import figure

fig = figure()
fig.scatter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 2, 1, 0, -1, -2, -3])

gstack = GridStack(width=800, height=600)

gstack[0, :3] = pn.Spacer(background='#FF0000')
gstack[1:3, 0] = pn.Spacer(background='#0000FF')
gstack[1:3, 1:3] = fig
gstack[3:5, 0] = hv.Curve([1, 2, 3])
gstack[3:5, 1] = ''
gstack[3:5, 2] = pn.Column(
    pn.widgets.Toggle(name='Toggle Me!')

This web page was generated from a Jupyter notebook and not all interactivity will work on this website. Right click to download and run locally for full Python-backed interactivity.

Download this notebook from GitHub (right-click to download).