Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pydeck pane - ABANDONED #959

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.vscode/settings.json
.vscode/panel.code-workspace
__pycache__/dodo.cpython-37.pyc
__pycache__/setup.cpython-37.pyc
0.5.0
panel/.version
.doit.db
.mypy_cache/
332 changes: 332 additions & 0 deletions examples/reference/other/Param.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import panel as pn\n",
"import param\n",
"\n",
"pn.extension()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``panel.Param`` pane allows customizing the widgets, layout and style of the parameters of a `param.Parametrized` Class.\n",
"\n",
"#### Parameters:\n",
"\n",
"The basic parameters are\n",
"\n",
"* **`object`** (param.parameterized.Parameters): The `param` attribute of a `param.Parameterized` Class\n",
"* **`parameters`** (None or List[str]): A list identifying the subset of parameters to include in the Pane.\n",
"* **`widgets`** (Dict): A Dictionary specifying which parameters and widgets to use for a given parameter. You can also specify widget attributes.\n",
"\n",
"The more advanced parameters give you more control and they are\n",
" \n",
"* **`default_layout`** (ClassSelector) A layout like Column, Row etc or a Custom GridBox.\n",
"* **`expand`** (bool) Whether or not to expand\n",
"* **`expand_button`** (None or Button) The expand button\n",
"* **`expand_layout`** (ClassSelector) A layout like Column, Row etc. or a Custom GridBox.\n",
"* **`show_labels`** (bool) Whether or not to show labels\n",
"* **`show_name`** (bool) Whether or not to show the name of the Parameterized Class \n",
"\n",
"For more layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
"\n",
"For an alternative example of using `panel.Param` see the [parameters user guide](../../user_guide/Param.ipynb).\n",
"\n",
"___"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets build a model of a cycling Athlete and his PowerCurve. \n",
"\n",
"The PowerCurve is a recording of his maximum power output in Watt per kg for fixed durations of time."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import datetime\n",
"import pandas as pd\n",
"import hvplot.pandas\n",
"\n",
"DATE_BOUNDS = (datetime.date(1900, 1, 1), datetime.datetime.now().date())\n",
"\n",
"class PowerCurve(param.Parameterized):\n",
" ten_sec = param.Number(1079)\n",
" ten_sec_date = param.Date(datetime.date(2018, 8, 21), bounds=DATE_BOUNDS)\n",
" one_min = param.Number(684)\n",
" one_min_date = param.Date(datetime.date(2017, 8, 31), bounds=DATE_BOUNDS)\n",
" ten_min = param.Number(419)\n",
" ten_min_date = param.Date(datetime.date(2017, 9, 22), bounds=DATE_BOUNDS)\n",
" twenty_min = param.Number(398)\n",
" twenty_min_date = param.Date(datetime.date(2017, 9, 22), bounds=DATE_BOUNDS)\n",
" one_hour = param.Number(319)\n",
" one_hour_date = param.Date(datetime.date(2017, 8, 6), bounds=DATE_BOUNDS)\n",
" \n",
" @param.depends(\"ten_sec\", \"one_min\", \"ten_min\", \"twenty_min\", \"one_hour\")\n",
" def plot(self):\n",
" data = {\n",
" \"duration\": [10 / 60, 1, 10, 20, 60],\n",
" \"power\": [self.ten_sec, self.one_min, self.ten_min, self.twenty_min, self.one_hour],\n",
" }\n",
" dataframe = pd.DataFrame(data)\n",
" line_plot = dataframe.hvplot.line(\n",
" x=\"duration\", y=\"power\", width=300, line_color=\"#007BFF\", line_width=3,\n",
" )\n",
" scatter_plot = dataframe.hvplot.scatter(x=\"duration\", y=\"power\", width=300).opts(\n",
" marker=\"o\", size=6, color=\"#007BFF\"\n",
" )\n",
" fig = line_plot * scatter_plot\n",
" gridstyle = {\"grid_line_color\": \"black\", \"grid_line_width\": 0.1}\n",
" fig = fig.opts(\n",
" responsive=True,\n",
" toolbar=None,\n",
" yticks=list(range(0, 1600, 200)),\n",
" ylim=(0, 1500),\n",
" gridstyle=gridstyle,\n",
" show_grid=True,\n",
" )\n",
" return fig\n",
" \n",
" \n",
"\n",
"class Athlete(param.Parameterized):\n",
" name_ = param.String(\"P.A. Nelson\")\n",
" birthday = param.Date(datetime.date(1976, 9, 17), bounds=DATE_BOUNDS)\n",
" weight = param.Number(default=82, bounds=(20,300))\n",
" power_curve = param.ClassSelector(class_=PowerCurve, default=PowerCurve())\n",
" \n",
"athlete = Athlete()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `pn.Param` can be used to view and edit the models.\n",
"\n",
"Try clicking the `...` button. This will expand the PowerCurve if running in an interactive notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Param(athlete)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The default Name and Birthday widgets are slow to use. So lets change them to a DatePicker and a LiteralInput for ints."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Param(athlete, widgets={\"birthday\": pn.widgets.DatePicker, \"weight\": pn.widgets.LiteralInput})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets expand the power curve by default."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Param(\n",
" athlete, \n",
" widgets={\n",
" \"birthday\": pn.widgets.DatePicker, \n",
" \"weight\": pn.widgets.LiteralInput\n",
" }, expand=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lets try to display the Name and Birthday only and in a Row."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Param(\n",
" athlete,\n",
" widgets={\"birthday\": pn.widgets.DatePicker},\n",
" parameters=[\"name_\", \"birthday\"],\n",
" show_name=False,\n",
" default_layout=pn.Row,\n",
" width=400\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets customize the view of the Athlete some more"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"athlete_view = pn.Param(\n",
" athlete,\n",
" widgets={\n",
" \"birthday\": pn.widgets.DatePicker, \n",
" \"weight\": {\"type\": pn.widgets.LiteralInput, \"width\": 100}\n",
" },\n",
" parameters=[\"name_\", \"birthday\", \"weight\"],\n",
" show_name=False,\n",
" default_layout=pn.Row,\n",
" width=600\n",
")\n",
"athlete_view"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets take a look at the PowerCurve"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Param(athlete.power_curve)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The PowerCurve layout is not that tidy. Lets change the layout to two columns."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class GridBoxWithTwoColumns(pn.GridBox):\n",
" def __init__(self, *objects, **params):\n",
" super().__init__(*objects, **params, ncols=2)\n",
" \n",
"power_curve_columns_view = pn.Param(\n",
" athlete.power_curve, \n",
" default_layout=GridBoxWithTwoColumns, \n",
" show_name=False,\n",
" widgets = {\n",
" \"ten_sec_date\": pn.widgets.DatePicker, \n",
" \"one_min_date\": pn.widgets.DatePicker, \n",
" \"ten_min_date\": pn.widgets.DatePicker, \n",
" \"twenty_min_date\": pn.widgets.DatePicker, \n",
" \"one_hour_date\": pn.widgets.DatePicker, \n",
" }\n",
")\n",
"power_curve_columns_view\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets put a plot of the PowerCurve in the mix"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"power_curve_view = pn.Row(\n",
" power_curve_columns_view,\n",
" pn.layout.VSpacer(width=50),\n",
" athlete.power_curve.plot,\n",
")\n",
"power_curve_view"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finally. Lets put the things together"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pn.Column(\n",
" pn.pane.Markdown(\"### Athlete\"), \n",
" athlete_view, \n",
" pn.pane.Markdown(\"#### Power Curve\"), \n",
" power_curve_view,\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
29 changes: 29 additions & 0 deletions panel/pane/pydeck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Defines a PyDeck Pane which renders a PyDeck plot using a PyDeckPlot
bokeh model.

For now I've just experimented a bit.

There is a simple implementation of an app using PyDeck in the gallery at
[awesome-streamlit.org](https://awesome-streamlit.org).

See

- [pydeck implementation](https://github.com/MarcSkovMadsen/awesome-panel/blob/master/package/awesome_panel/express/pane/pydeck.py)
- [test_pydeck app](https://github.com/MarcSkovMadsen/awesome-panel/blob/master/src/pages/gallery/awesome_panel_express_tests/test_pydeck.py)
- [test_pydeck test](https://github.com/MarcSkovMadsen/awesome-panel/blob/master/package/tests/test_pydeck.py)

It's based on the following resources

- [PyDeck Github](https://github.com/uber/deck.gl/tree/master/bindings/pydeck)
- [PyDeck Docs](https://deckgl.readthedocs.io/en/latest/)
- [PyDeck Deck Implementation](https://github.com/uber/deck.gl/blob/master/bindings/pydeck/pydeck/bindings/deck.py)
- [PyDeck render_json_to_html Implementation](https://github.com/uber/deck.gl/blob/master/bindings/pydeck/pydeck/io/html.py)

When I move on I believe I can find inspiration in

- The Panel implementation of the Plotly Pane and Plotly Bokeh Model
- [Extending Bokeh](https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html)
- [PyDeck Jupyter Implementation](https://github.com/uber/deck.gl/blob/master/bindings/pydeck/pydeck/widget/widget.py)
"""