{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "3ea7576e-1f54-4983-a8d1-1f6c0e2165de", "metadata": {}, "source": [ "# Quickstart\n", "\n", "These quick instructions will get you up and running with Datapane in a few minutes! \n", "\n", "In this quickstart, we will introduce you to the concept of Blocks, create a simple report, turn it into a data app that let's a user create a scatter plot of selected features from the popular [Iris dataset](https://en.wikipedia.org/wiki/Iris_flower_data_set).\n", "\n", "## Installation\n", "\n", "First, install Datapane using pip. Check out our [installation page](/install-datapane/) for installation options. \n", "\n", "\n", "!!! note\n", " If you don't have a Python environment, you can get started for free on our hosted [Codespaces environment](https://try.datapane.com). You can also download this Quickstart as a [Jupyter Notebook](https://raw.githubusercontent.com/datapane/datapane/main/public-docs/docs/quickstart.ipynb){:download=quickstart.ipynb}.\n", "\n", "\n", "```python\n", "pip3 install -U datapane\n", "```" ] }, { "attachments": {}, "cell_type": "markdown", "id": "8e65f2fe-82a3-48f3-8f9e-b61c3e76bcb8", "metadata": {}, "source": [ "## Setting things up" ] }, { "cell_type": "code", "execution_count": null, "id": "3e15ebac-8fae-4b37-a1fc-627e43420109", "metadata": {}, "outputs": [], "source": [ "import altair as alt\n", "import datapane as dp\n", "from vega_datasets import data" ] }, { "cell_type": "markdown", "id": "41888ecb-53a5-4b78-8027-b026acc486b4", "metadata": {}, "source": [ "We've imported `datapane`, the popular visualization library `altair`, and `vega_datasets` which contains some sample datasets.\n", "\n", "Let's load the Iris dataset and get a list of the features." ] }, { "cell_type": "code", "execution_count": null, "id": "7d284782-3f15-4f67-aecc-9961285ce671", "metadata": {}, "outputs": [], "source": [ "df = data.iris()\n", "columns = list(df.columns)\n", "print(columns)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bfc4a96c", "metadata": {}, "source": [ "## Blocks\n", "\n", "Datapane is built around the concept of _Blocks_, which are Python objects that represent an individual unit that can be processed, composed, and viewed. There are display blocks, such as _Plot_ or _DataTable_, and layout blocks, such as _Select_ and _Group_.\n", "\n", "Having loaded our DataFrame above and with knowledge of our column names, we first create a simple scatterplot using the Altair plotting library. \n", "\n", "We then build a simple set of blocks which presents two tabs: one with our plot, and one with our DataFrame." ] }, { "cell_type": "code", "execution_count": null, "id": "7ba6a3d5", "metadata": {}, "outputs": [], "source": [ "fig = (\n", " alt.Chart(df)\n", " .mark_point()\n", " .encode(x=alt.X(\"sepalLength\", scale=alt.Scale(zero=False)), \n", " y=alt.X(\"sepalWidth\", scale=alt.Scale(zero=False)),\n", " color=\"species\")\n", ")\n", "\n", "view = dp.Select(dp.Plot(fig, label=\"Plot\"), dp.DataTable(df, label=\"Data\"))\n", "view" ] }, { "attachments": {}, "cell_type": "markdown", "id": "64dc4fa3", "metadata": {}, "source": [ "## Reports\n", "\n", "Once we have a view, we can save it as an HTML report or upload it to Datapane Cloud to share.\n", "\n", "Let's save it as a report and [open it in a new window](./quickstart_report.html){:target=_blank}." ] }, { "cell_type": "code", "execution_count": null, "id": "58d6cf64", "metadata": {}, "outputs": [], "source": [ "dp.save_report(view, \"quickstart_report.html\", open=True)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "c477b27a-eb3d-4f85-9d8d-7152fde8459c", "metadata": {}, "source": [ "## Apps\n", "\n", "The blocks above that make up our report are static. This has the benefit of not requiring a running server, but the limitation of not allowing backend processing. \n", "\n", "To turn your report into an app, Datapane allows you to attach Python functions to your blocks and pass data into them to dynamically process and return new blocks. Functions can be run in response to forms or front-end events (such as on a schedules, or on a pageload).\n", "\n", "### Functions\n", "\n", "Let's build a simple function which takes two columns of the dataset as parameters, and returns a scatter plot based on these inputs." ] }, { "cell_type": "code", "execution_count": null, "id": "3c48add0-9241-4e22-bd10-5298656591be", "metadata": { "tags": [] }, "outputs": [], "source": [ "def plot_df(x_axis: str, y_axis: str, color: str) -> dp.Plot:\n", " # global dataset\n", " fig = (\n", " alt.Chart(df)\n", " .mark_point()\n", " .encode(\n", " x=alt.X(x_axis, scale=alt.Scale(zero=False)),\n", " y=alt.X(y_axis, scale=alt.Scale(zero=False)),\n", " color=color,\n", " tooltip=columns,\n", " )\n", " )\n", "\n", " return dp.Plot(fig, name=\"plot\")\n", "\n", "plot_df(x_axis=\"sepalLength\", y_axis=\"sepalWidth\", color=\"species\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "decda43c-da04-4f24-9aea-d0bb10ab4754", "metadata": {}, "source": [ "To highlight the minor differences between a _regular_ Python function, and a function that is ready for Datapane interactivity:\n", "\n", "- The parameters to the function should be the same as the `Controls` that we'll add to our form. Alternatively, your function can take a single `params` dictionary which contains all parameters.\n", "- Functions must return an object which can be wrapped up as a Datapane block. This can either be a single block (such as `dp.Plot`), a list of blocks, or an object which Datapane can automatically convert to a block (such as a pandas DataFrame)\n", "\n", "\n", "!!! note \n", " Datapane blocks have full notebook support, meaning they can be displayed in notebooks as seen above. This makes it easy to interactively develop your function, and call it from your notebook with test parameters before wiring it into your Datapane App.\n", "\n", "### Controls\n", "\n", "Let's add some controls that let the user select which features to plot. Our feature list from earlier, `columns`, will be useful here with the the `Choice` parameter that allows the user the select an item from the list." ] }, { "cell_type": "code", "execution_count": null, "id": "a38c91eb-7adf-4294-a29d-9b0c76507e34", "metadata": {}, "outputs": [], "source": [ "controls = dp.Controls(\n", " x_axis=dp.Choice(options=columns),\n", " y_axis=dp.Choice(options=columns),\n", " color=dp.Choice(options=columns),\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ae1da60a-9c45-45e3-ac81-64e6e1a53dda", "metadata": {}, "source": [ "As we can see, the name of each `dp.Choice` is used as the parameter name when calling our function.\n", "\n", "### Bringing it Together\n", "\n", "We have our function, and our controls, now let's bring them together to create a data app with a `Form` Block." ] }, { "cell_type": "code", "execution_count": null, "id": "a4c07204-af9f-4335-8295-f4f819626ba0", "metadata": {}, "outputs": [], "source": [ "view = dp.View(\n", " dp.Text(\"# Iris Dataset Plotter\"),\n", " dp.Form(plot_df, controls=controls),\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "99c3b617-f6da-48ff-b8bf-c4546de91ed5", "metadata": {}, "source": [ "Let's walk through the code. As in the report example, we are creating a list of _Blocks_ but this time we have a new Block called `Form`, which is a Compute Block that allows us to call a function from our view. \n", "\n", "It takes the function we created earlier, `plot_df`, and the controls we created, `controls`. When the user submits the form, the function is run with the parameters and, by default, the blocks returned as the output of our function are rendered below the Form in the UI.\n", "\n", "We can preview the design of our data app in this notebook (but the functions won't work until we publish it.)" ] }, { "cell_type": "code", "execution_count": null, "id": "59a9cb8e-f03d-4cf8-b1d3-fd8270ec51b5", "metadata": {}, "outputs": [], "source": [ "view" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ea646651-32c5-425b-8aeb-d34a7cdbaf30", "metadata": {}, "source": [ "## Launching the App\n", "\n", "There are many ways to publish a Datapane app, but for now, we can use the `dp.serve_app` function to see it in action locally.\n", "\n", "```python\n", "dp.serve_app(view)\n", "```\n", "\n", "That's it! You've learnt about Blocks, Views, Reports, Apps, and even built and served your first data app with Datapane.\n", "\n", "## Next Steps\n", "- [View the Gallery](https://datapane.com/gallery)\n", "- [Sign up for a free account](https://cloud.datapane.com/accounts/signup)\n", "- [Read the documentation](https://docs.datapane.com)\n", "- [Read our forums](https://forum.datapane.com/)" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }