{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel as pn\n", "import pandas as pd\n", "import numpy as np\n", "\n", "pn.extension('perspective')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``Perspective`` pane provides an interactive visualization component for large, real-time datasets built on the [Perspective](https://perspective.finos.org/) project.\n", "\n", "#### Parameters:\n", "\n", "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", "\n", "* **``aggregates``** (dict): Aggregation spec, e.g. {x: \"distinct count\"}\n", "* **``columns``** (list): List of displayed columns.\n", "* **``expressions``** (list): List of expressions, e.g. `['\"x\"+\"y\"']`\n", "* **``filters``** (list): A list of filters, e.g. `[[\"x\", \"<\", 3], [\"y\", \"contains\", \"abc\"]]`.\n", "* **``group_by``** (list): List of columns to group by, e.g. `[\"x\", \"y\"]`\n", "* **``object``** (dict or pd.DataFrame): The plot data declared as a dictionary of arrays or a DataFrame.\n", "* **``selectable``** (bool, default=True): Whether rows are selectable\n", "* **``split_by``** (list): A list of columns to pivot by. e.g. `[\"x\", \"y\"]`\n", "* **``sort``** (list): List of sorting specs, e.g. `[[\"x\", \"desc\"]]`\n", "* **``plugin``** (str): The name of a plugin to display the data. For example 'datagrid' or 'd3_xy_scatter'.\n", "* **``plugin_config``** (dict): Configuration for the PerspectiveViewerPlugin \n", "* **``toggle_config``** (bool): Whether to show the config menu.\n", "* **``theme``** (str): The theme of the viewer, available options include `'material'`, `'material-dark'`, `'material-dense'`, `'material-dense-dark'`, `'monokai'`, `'solarized'`, `'solarized-dark'` and `'vaporwave'`\n", "\n", "___\n", "\n", "The `Perspective` pane renders columns of data specified as a dictionary of lists or arrays and pandas DataFrames:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = {'x': [1, 2, 3], 'y': [1, 2, 3]}\n", "\n", "pn.pane.Perspective(data, width=1000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also provide configuration options for the viewer plugins:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "random_df = pd.DataFrame(np.random.randn(20, 2), columns=list('XY'))\n", "\n", "pn.pane.Perspective(random_df, width=1000, plugin_config={\n", " 'columns': {\n", " 'X': {'gradient': 0.7836544570728833, 'neg_color': '#f07160', 'number_color_mode': 'gradient', 'pos_color': '#7dc3f0'},\n", " 'Y': {'gradient': 1.5673089141457666, 'neg_color': '#ff9485', 'number_color_mode': 'gradient', 'pos_color': '#607785'}\n", " }\n", "})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also set the various config settings such as choosing the `columns` to display or the `theme` from Python:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randn(400, 4), columns=list('ABCD')).cumsum()\n", "\n", "stream_perspective = pn.pane.Perspective(\n", " df, plugin='d3_y_line', columns=['A', 'B', 'C', 'D'], theme='material-dark',\n", " sizing_mode='stretch_width', height=500, margin=0\n", ")\n", "\n", "stream_perspective" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `Perspective` pane also supports `stream` and `patch` methods allowing us to efficiently update the data. The amount of data to keep in the streaming buffer can be controlled via the `rollover` option:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rollover = pn.widgets.IntInput(name='Rollover', value=500)\n", "\n", "def stream():\n", " data = df.iloc[-1] + np.random.randn(4)\n", " stream_perspective.stream(data, rollover.value)\n", "\n", "cb = pn.state.add_periodic_callback(stream, 50)\n", "\n", "pn.Row(cb.param.period, rollover)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively we can also `patch` the data:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mixed_df = pd.DataFrame({'A': np.arange(10), 'B': np.random.rand(10), 'C': [f'foo{i}' for i in range(10)]})\n", "\n", "perspective = pn.pane.Perspective(mixed_df, height=500)\n", "\n", "perspective" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The easiest way to patch the data is by supplying a dictionary as the patch value. The dictionary should have the following structure:\n", "\n", "```python\n", "{\n", " column: [\n", " (index: int or slice, value),\n", " ...\n", " ],\n", " ...\n", "}\n", "```\n", " \n", "As an example, below we will patch the 'A' and 'C' columns. On the `'A'` column we will replace the 0th row and on the `'C'` column we replace the first two rows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "perspective.patch({'A': [(0, 3)], 'C': [(slice(0, 1), 'bar')]})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Controls\n", "\n", "The `Perspective` pane exposes a number of options which can be changed from both Python and Javascript try out the effect of these parameters interactively:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pn.Row(perspective.controls(jslink=True), perspective)" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }