#!/usr/bin/env python # coding: utf-8 # In[ ]: import panel as pn import numpy as np import holoviews as hv pn.extension(sizing_mode = 'stretch_both') # For a large variety of use cases we do not need complete control over the exact layout of each individual component on the page, as could be achieved with a [custom template](../../user_guide/Templates.ipynb), we just want to achieve a more polished look and feel. For these cases Panel ships with a number of default templates, which are defined by declaring four main content areas on the page, which can be populated as desired: # # * **`header`**: The header area of the HTML page # * **`sidebar`**: A collapsible sidebar # * **`main`**: The main area of the application # * **`modal`**: A modal area which can be opened and closed from Python # # These four areas behave very similarly to other Panel layout components and have list-like semantics. The `ReactTemplate` in particular however is an exception to this rule as the `main` area behaves like panel `GridSpec` object. Unlike regular layout components however, the contents of the areas is fixed once rendered. If you need a dynamic layout you should therefore insert a regular Panel layout component (e.g. a `Column` or `Row`) and modify it in place once added to one of the content areas. # # Templates can allow for us to quickly and easily create web apps for displaying our data. Panel comes with a default Template, and includes multiple Templates that extend the default which add some customization for a better display. # # #### Parameters: # # In addition to the four different areas we can populate the `ReactTemplate` declares a few variables to configure the layout: # # * **`cols`** (dict): Number of columns in the grid for different display sizes (`default={'lg': 12, 'md': 10, 'sm': 6, 'xs': 4, 'xxs': 2}`) # * **`breakpoints`** (dict): Sizes in pixels for various layouts (`default={'lg': 1200, 'md': 996, 'sm': 768, 'xs': 480, 'xxs': 0}`) # * **`row_height`** (int, default=150): Height per row in the grid # * **`dimensions`** (dict): Minimum/Maximum sizes of cells in grid units (`default={'minW': 0, 'maxW': 'Infinity', 'minH': 0, 'maxH': 'Infinity'}`) # * **`prevent_collision`** (bool, default=Flase): Prevent collisions between grid items. # * **`save_layout`** {bool, default=False): Save layout changes to localStorage. # # These parameters control the responsive resizing in different layouts. The `ReactTemplate` also exposes the same parameters as other templates: # # * **`busy_indicator`** (BooleanIndicator): Visual indicator of application busy state. # * **`header_background`** (str): Optional header background color override. # * **`header_color`** (str): Optional header text color override. # * **`logo`** (str): URI of logo to add to the header (if local file, logo is base64 encoded as URI). # * **`site`** (str): Name of the site. Will be shown in the header. Default is '', i.e. not shown. # * **`site_url`** (str): Url of the site and logo. Default is "/". # * **`title`** (str): A title to show in the header. # * **`theme`** (Theme): A Theme class (available in `panel.template.theme`) # * **`sidebar_width`** (int): The width of the sidebar in pixels. Default is 350. # # ________ # In this case we are using the `ReactTemplate`, built on [react-grid-layout](https://github.com/STRML/react-grid-layout), which provides a responsive, resizable, draggable grid layout. Here is an example of how you can set up a display using this template: # In[ ]: react = pn.template.ReactTemplate(title='React Template') xs = np.linspace(0, np.pi) freq = pn.widgets.FloatSlider(name="Frequency", start=0, end=10, value=2) phase = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi) @pn.depends(freq=freq, phase=phase) def sine(freq, phase): return hv.Curve((xs, np.sin(xs*freq+phase))).opts( responsive=True, min_height=400) @pn.depends(freq=freq, phase=phase) def cosine(freq, phase): return hv.Curve((xs, np.cos(xs*freq+phase))).opts( responsive=True, min_height=400) react.sidebar.append(freq) react.sidebar.append(phase) # Unlike other templates the `ReactTemplate.main` area acts like a GridSpec react.main[:4, :6] = pn.Card(hv.DynamicMap(sine), title='Sine') react.main[:4, 6:] = pn.Card(hv.DynamicMap(cosine), title='Cosine') react.servable(); # With the `row_height=150` this will result in the two `Card` objects filling 4 rows each totalling 600 pixels and each taking up 6 columns, which resize responsively to fill the screen and reflow when working on a smaller screen. When hovering of the top-left corner of each card a draggable handle will allow dragging the components around while a resize handle will show up at the bottom-right corner. #

ReactTemplate with DefaultTheme

# #
#

ReactTemplate with DarkTheme

# # The app can be displayed within the notebook by using `.servable()`, or rendered in another tab by replacing it with `.show()`. # # Themes can be added using the optional keyword argument `theme`. Each template comes with a DarkTheme and a DefaultTheme, which can be set `ReactTemplate(theme=DarkTheme)`. If no theme is set, then DefaultTheme will be applied. # # It should be noted that Templates may not render correctly in a notebook, and for the best performance the should ideally be deployed to a server.