Skip to content

Commit

Permalink
Tqdm Indicator (#2079)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcSkovMadsen committed Jun 30, 2021
1 parent 2ca40e5 commit d98bb0b
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 6 deletions.
196 changes: 196 additions & 0 deletions examples/reference/indicators/Tqdm.ipynb
@@ -0,0 +1,196 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n",
"import panel as pn\n",
"\n",
"from panel.widgets import Tqdm\n",
"\n",
"pn.extension()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``Tqdm`` indicator wraps the well known [`tqdm`](https://github.com/tqdm/tqdm) progress indicator and displays the progress towards some target. You can use it in the notebook or in your Panel web app.\n",
"\n",
"[![Tqdm](https://raw.githubusercontent.com/tqdm/tqdm/master/images/logo.gif)](https://github.com/tqdm/tqdm)\n",
"\n",
"#### Parameters:\n",
"\n",
"* **``layout``** (Column or Row): The layout of the `progress` indicator and the `text_pane`.\n",
"* **``max``** (int): The maximum progress value.\n",
"* **``progress``** (Progress): The Progress indicator to display the progress on.\n",
"* **``text``** (int): The current text being output by tqdm.\n",
"* **``text_pane``** (Str): The Pane displaying the progress `text`.\n",
"* **``value``** (int or None): The current value towards the progress.\n",
"* **``write_to_console``** (bool): Whether or not to also write to the console, only works on server.\n",
"\n",
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb). For a general introduction to `tqdm` and lots of examples checkout the [tqdm github page](https://github.com/tqdm/tqdm).\n",
"\n",
"___"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To use the `Tqdm` indicator instantiate the object and then use the resulting variable just like you would use `tqdm.tqdm`, i.e. you can iterate over any iterable:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tqdm = Tqdm()\n",
"\n",
"def run_loop(*events, timeout=0.2):\n",
" for i in tqdm(range(0,10), desc=\"My loop bar\", leave=True, colour='#666666'):\n",
" time.sleep(timeout)\n",
" \n",
"run_loop(timeout=0.01)\n",
"\n",
"tqdm"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most of the [parameters supported by tqdm](https://github.com/tqdm/tqdm#parameters) can be passed to the call method of the `Tqdm` indicator. \n",
"\n",
"Click the button below to see the progress bar update (if you viewing this on a live kernel):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"button = pn.widgets.Button(name=\"Run Loop\", button_type=\"success\")\n",
"button.on_click(run_loop)\n",
"button"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Nesting\n",
"\n",
"When nesting `Tqdm` indicators using the `margin` parameter allows visually indicating the level of nesting."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tqdm_outer = Tqdm()\n",
"tqdm_inner = Tqdm(margin=(0, 0, 0, 20))\n",
"\n",
"def run_nested_loop(*events, timeout=0.05):\n",
" for i in tqdm_outer(range(10)):\n",
" for j in tqdm_inner(range(10)):\n",
" time.sleep(timeout)\n",
" \n",
"run_nested_loop(timeout=0.01)\n",
"\n",
"pn.Column(tqdm_outer, tqdm_inner)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"button = pn.widgets.Button(name=\"Run Nested Loop\", button_type=\"success\")\n",
"button.on_click(run_nested_loop)\n",
"button"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pandas\n",
"\n",
"To use the tqdm pandas integration you can activate it by calling `tqdm.pandas` with all the configuration options. Once activated the `progress_apply` method is available on a `pandas.DataFrame`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tqdm_pandas = Tqdm(width=500)\n",
"\n",
"# Register Pandas. This gives DataFrame.progress_apply method\n",
"tqdm_pandas.pandas(desc=\"Pandas Progress\")\n",
"\n",
"df = pd.DataFrame(np.random.randint(0, 100, (100000, 600)))\n",
"\n",
"def run_df(*events):\n",
" df.progress_apply(lambda x: x**2)\n",
" \n",
"run_df()\n",
"\n",
"tqdm_pandas"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pandas_button = pn.widgets.Button(name=\"Run Pandas Apply\", button_type=\"success\")\n",
"pandas_button.on_click(run_df)\n",
"pandas_button"
]
}
],
"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.8.8"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
5 changes: 3 additions & 2 deletions panel/tests/widgets/test_base.py
Expand Up @@ -6,13 +6,14 @@
from panel.links import CallbackGenerator
from panel.widgets import (
CompositeWidget, Dial, FileDownload, FloatSlider, TextInput,
Terminal, ToggleGroup, Widget
Terminal, ToggleGroup, Tqdm, Widget
)
from panel.widgets.tables import BaseTable
from panel.tests.util import check_layoutable_properties

excluded = (
BaseTable, CompositeWidget, Dial, FileDownload, ToggleGroup, Terminal
BaseTable, CompositeWidget, Dial, FileDownload, ToggleGroup, Terminal,
Tqdm
)

all_widgets = [
Expand Down
95 changes: 95 additions & 0 deletions panel/tests/widgets/test_tqdm.py
@@ -0,0 +1,95 @@
"""Tests of the Tqdm indicator"""
import panel as pn

from panel.widgets import Tqdm


def test_tqdm():
tqdm = Tqdm(layout="row", sizing_mode="stretch_width")

for index in tqdm(range(0, 3)):
pass

assert tqdm.value == 3
assert tqdm.max == 3
assert tqdm.text.startswith('100% 3/3')

assert isinstance(tqdm.progress, pn.widgets.indicators.Progress)
assert isinstance(tqdm.text_pane, pn.pane.Str)
assert isinstance(tqdm.layout, pn.Row)


def test_tqdm_leave_false():
tqdm = Tqdm(layout="row", sizing_mode="stretch_width")

for index in tqdm(range(0, 3), leave=False):
pass

assert tqdm.value == 0
assert tqdm.max == 3
assert tqdm.text == ''


def test_tqdm_color():
tqdm = Tqdm()

for index in tqdm(range(0, 3), colour='red'):
pass

assert tqdm.text_pane.style == {'color': 'red'}


def get_tqdm_app():
import time
import pandas as pd
import numpy as np

tqdm = Tqdm(layout="row", sizing_mode="stretch_width")

def run(*events):
for index in tqdm(range(0, 10)):
time.sleep(0.2)

button = pn.widgets.Button(name="Run Loop", button_type="primary")
button.on_click(run)

# Register Pandas. This gives DataFrame.progress_apply method
tqdm.tqdm.pandas(desc="my bar!")

df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))

def run_df(*events):
df.progress_apply(lambda x: x ** 2)

pandas_button = pn.widgets.Button(name="Pandas Apply", button_type="success")
pandas_button.on_click(run_df)
pandas_button

component = pn.Column(button, pandas_button, tqdm, sizing_mode="stretch_width")
template = pn.template.FastListTemplate(
title="Panel - Tqdm Indicator",
main=[component],
sidebar=[
pn.Param(tqdm, sizing_mode="stretch_width"),
],
)
return template

def get_tqdm_app_simple():
import time

tqdm = Tqdm(layout="row", sizing_mode="stretch_width")

def run(*events):
for index in tqdm(range(0, 10)):
time.sleep(0.2)

button = pn.widgets.Button(name="Run Loop", button_type="primary")
button.on_click(run)
return pn.Column(
tqdm, button
)

if __name__.startswith("bokeh"):
# get_tqdm_app_simple().servable()
get_tqdm_app().servable()
3 changes: 2 additions & 1 deletion panel/widgets/__init__.py
Expand Up @@ -13,7 +13,8 @@
LoadingSpinner,
Number,
Progress,
Trend
Trend,
Tqdm,
)
from .input import ( # noqa
ColorPicker,
Expand Down

0 comments on commit d98bb0b

Please sign in to comment.