{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel as pn\n", "\n", "from panel.layout.gridstack import GridStack\n", "\n", "pn.extension('gridstack')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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.\n", "\n", "#### Parameters:\n", "\n", "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", "\n", "* **``allow_resize``** (bool): Whether to allow resizing grid cells.\n", "* **``allow_drag``** (bool): Whether to allow dragging grid cells.\n", "* **``ncols``** (int): Allows specifying a fixed number of columns (otherwise grid expands to match assigned objects)\n", "* **``nrows``** (int): Allows specifying a fixed number of rows (otherwise grid expands to match assigned objects)\n", "* **``mode``** (str): Whether to 'warn', 'error', or simply 'override' on overlapping assignment\n", "* **``objects``** (list): The list of objects to display in the GridSpec. Should not generally be modified directly except when replaced in its entirety.\n", "\n", "___" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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.\n", "\n", "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gstack = GridStack(sizing_mode='stretch_both')\n", "\n", "gstack[ : , 0: 3] = pn.Spacer(background='red', margin=0)\n", "gstack[0:2, 3: 9] = pn.Spacer(background='green', margin=0)\n", "gstack[2:4, 6:12] = pn.Spacer(background='orange', margin=0)\n", "gstack[4:6, 3:12] = pn.Spacer(background='blue', margin=0)\n", "gstack[0:2, 9:12] = pn.Spacer(background='purple', margin=0)\n", "\n", "gstack" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gstack.grid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to assigning objects to the grid we can also index the grid:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pn.Row(gstack[2, 2], width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And select a subregion using slicing semantics:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gstack[0, 1:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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.\n", "\n", "### Fixed size grids\n", "\n", "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import holoviews as hv\n", "import holoviews.plotting.bokeh\n", "\n", "from bokeh.plotting import figure\n", "\n", "fig = figure()\n", "fig.scatter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 2, 1, 0, -1, -2, -3])\n", "\n", "gstack = GridStack(width=800, height=600)\n", "\n", "gstack[0, :3] = pn.Spacer(background='#FF0000')\n", "gstack[1:3, 0] = pn.Spacer(background='#0000FF')\n", "gstack[1:3, 1:3] = fig\n", "gstack[3:5, 0] = hv.Curve([1, 2, 3])\n", "gstack[3:5, 1] = 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png'\n", "gstack[3:5, 2] = pn.Column(\n", " pn.widgets.FloatSlider(),\n", " pn.widgets.ColorPicker(),\n", " pn.widgets.Toggle(name='Toggle Me!')\n", ")\n", "\n", "gstack" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }