Skip to content

Commit

Permalink
Documentation fixes (#785)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored Nov 14, 2019
1 parent 58a364e commit a75cb00
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 10 deletions.
7 changes: 4 additions & 3 deletions doc/Comparisons.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ Panel and Dash can both be used to create dashboards in Python, but take very di
- Panel is plotting-library agnostic, fully supporting a wide range of Python libraries out of the box, including Plotly. Dash has full support for Plotly but only limited support for other plotting libraries, using separate extension packages.

- Dash dashboards store all of their per-user session state in the client (i.e., the browser), while Panel allows per-user, per-session state in both the server and the client, synchronizing between the two if needed. This difference has important implications:
* Dash's approach is more highly scalable in some cases, allowing many simultaneous client sessions without necessarily using up resources on the server for each new client. (That said, Dash's server only processes a single request at any one time and is `"not suitable for production" <https://dash.plot.ly/deployment>`__, so the differences may not be that large in practice.)
* Dash's approach requires dashboards to be written only in a reactive way, with logic defined by Python callback functions that have no side effects; imperative functions that change Python-based state are not supported. Panel supports server-side caching of intermediate results and other state per user, which can make complex processing pipelines that need server-side data much more practical.
For instance, both approaches can generate and update Datashader plots as a user pans and zooms, using large datasets stored only on the server, but they will work in very different ways. With Dash, all requests will need to start with the original dataset and do all the processing steps needed to fill a client request, returning the final plot rendered for the client to show, because no intermediate data will be stored on the server for a subsequent call to use. With Panel, it is possible to write apps that re-run only the very specific computations needed for a specific request, making use of previously computed intermediate values stored per user and per session on the server and never communicated to the client. The `Datashader example dashboard <https://examples.pyviz.org/datashader_dashboard/dashboard.html>`__ shows how to use this intermediate-value caching to provide the fastest possible updates for a given user action, only re-running the computation actually needed to satisfy the request, re-using cached values stored on the server when appropriate.

* Dash's approach is more highly scalable in some cases, allowing many simultaneous client sessions without necessarily using up resources on the server for each new client.

* Dash's approach requires dashboards to be written only in a reactive way, with logic defined by Python callback functions that have no side effects; imperative functions that change Python-based state are not supported. Panel supports server-side caching of intermediate results and other state per user, which can make complex processing pipelines that need server-side data much more practical. For instance, both approaches can generate and update Datashader plots as a user pans and zooms, using large datasets stored only on the server, but they will work in very different ways. With Dash, all requests will need to start with the original dataset and do all the processing steps needed to fill a client request, returning the final plot rendered for the client to show, because no intermediate data will be stored on the server for a subsequent call to use. With Panel, it is possible to write apps that re-run only the very specific computations needed for a specific request, making use of previously computed intermediate values stored per user and per session on the server and never communicated to the client. The `Datashader example dashboard <https://examples.pyviz.org/datashader_dashboard/dashboard.html>`__ shows how to use this intermediate-value caching to provide the fastest possible updates for a given user action, only re-running the computation actually needed to satisfy the request, re-using cached values stored on the server when appropriate.


Comparing Panel and ipywidgets
Expand Down
2 changes: 1 addition & 1 deletion doc/_static/site.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ A high-level app and dashboarding solution for Python
<table>
<tr>
<td border=1><a href="https://examples.pyviz.org/attractors/clifford_panel.html"><b>Interact</b></a><br><a href="https://clifford.pyviz.demo.anaconda.com"><img src="_images/clifford.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/gapminders/gapminders.html"><b>Gapminders</b></a><br><a href="https://gapminder.pyviz.demo.anaconda.com"><img src="_images/gapminders.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/gapminders/gapminders.html"><b>Gapminders</b></a><br><a href="https://gapminders.pyviz.demo.anaconda.com"><img src="_images/gapminders.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/nyc_taxi/dashboard.html"><b>NYC Taxi</b></a><br><a href="https://nyc-taxi.pyviz.demo.anaconda.com"><img src="_images/nyc_taxi.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/glaciers/glaciers.html"><b>Glaciers</b></a><br><a href="https://glaciers.pyviz.demo.anaconda.com"><img src="_images/glaciers.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/portfolio_optimizer/portfolio.html"><b>Euler's Method</b></a><br><a href="https://portfolio-optimizer.pyviz.demo.anaconda.com"><img src="_images/portfolio-optimizer.png" /></a></td>
<td border=1><a href="https://examples.pyviz.org/portfolio_optimizer/portfolio.html"><b>Portfolio Optimizer</b></a><br><a href="https://portfolio-optimizer.pyviz.demo.anaconda.com"><img src="_images/portfolio-optimizer.png" /></a></td>
<tr>
</table>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This app demonstrates how to use a variety of different [plotting libraries and data types](https://github.com/pyviz/panel/issues/2) with Panel. Here let's set up four different plotting libraries controlled by a couple of widgets, for Hans Rosling's [gapminder](https://demo.bokehplots.com/apps/gapminder) example.\n",
"This app demonstrates how to use a variety of different [plotting libraries and data types](https://github.com/pyviz/panel/issues/2) with Panel. Here let's set up four different plotting libraries controlled by a couple of widgets, for Hans Rosling's [gapminders](https://demo.bokehplots.com/apps/gapminder) example.\n",
"\n",
"**Live App URL**: https://gapminder.pyviz.demo.anaconda.com\n",
"**Live App URL**: https://gapminders.pyviz.demo.anaconda.com\n",
"\n",
"The app is defined as a notebook ipynb file and can also be viewed on MyBinder.org:\n",
"\n",
Expand Down
25 changes: 24 additions & 1 deletion examples/reference/panes/Streamz.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"\n",
"* **``always_watch``** (boolean, default=False): Whether to watch the stream even when not displayed.\n",
"* **``object``** (streamz.Stream): The streamz.Stream object being watched\n",
"* **``rate_limit``** (floa, default=0.1): The minimum interval between events.\n",
"* **``rate_limit``** (float, default=0.1): The minimum interval between events.\n",
"\n",
"___"
]
Expand Down Expand Up @@ -57,6 +57,29 @@
"streamz_pane"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now define a periodic callback which emits an increasing count on the `Stream`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"count = 1 \n",
"\n",
"def emit_count():\n",
" global count\n",
" count += 1\n",
" source.emit(count)\n",
"\n",
"streamz_pane.add_periodic_callback(emit_count, period=100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
2 changes: 1 addition & 1 deletion examples/user_guide/Param.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
" y = ((y - y.min()) / y.ptp()) * 20\n",
" array = np.array(\n",
" [list((' ' * (int(round(d)) - 1) + '*').ljust(20)) for d in y])\n",
" return pn.pane.Str('\\n'.join([''.join(r) for r in array.T]), height=350, width=500)\n",
" return pn.pane.Str('\\n'.join([''.join(r) for r in array.T]), height=380, width=500)\n",
"\n",
"\n",
"sine = Sine(name='ASCII Sine Wave')\n",
Expand Down

0 comments on commit a75cb00

Please sign in to comment.