Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dash: progress bar for reading files

I have seen this example of Progress & Interval components for displaying the progress in Dash:

import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

progress = html.Div(
    [
        dcc.Interval(id="progress-interval", n_intervals=0, interval=500),
        dbc.Progress(id="progress"),
    ]
)

@app.callback(
    [Output("progress", "value"), Output("progress", "children")],
    [Input("progress-interval", "n_intervals")],
)
def update_progress(n):
    # check progress of some background process, in this example we'll just
    # use n_intervals constrained to be in 0-100
    progress = min(n % 110, 100)
    # only add text after 5% progress to ensure text isn't squashed too much
    return progress, f"{progress} %" if progress >= 5 else ""

However, I cannot find any example that would actually show how to properly link the progress bar to some background process.

If, for example, I have a callback with a regular for loop, how can I show the progress of this for loop (i.e. if I'm on 10th element from 100, I want it to be displayed as 10% in the progress bar)?

like image 251
Valeria Avatar asked Dec 09 '19 02:12

Valeria


People also ask

How do I make a progress bar with multiple bars?

You can nest Progress components to make a progress bar with multiple bars. Make sure you set bar=True on each of the children. Set striped=True for a striped progress bar.

How do I make a striped progress bar in Visual Studio?

Set striped=True for a striped progress bar. If you have set striped=True, you can also set animated=True to get animated stripes. Typically to use Progress effectively, you will want to use a dcc.Interval component to periodically monitor some background process and update the progress accordingly.

How do I add a text label to the progress bar?

To add a text label to the progress bar, use the label prop. Set the height of the progress bar using the style argument. Use the color argument along with one of Bootstrap's contextual color names to set the background color of the progress bar. You can nest Progress components to make a progress bar with multiple bars.

How to add bootstrap style progress bars to your app?

Add Bootstrap style progress bars to your app with the Progress component, featuring support for stacked bars, animated backgrounds, and text labels. Use the value argument of Progress to set progress.


2 Answers

@Valeria, I created a tutorial on the progress bar and the spinner, which focuses on the formatting of the loaders. https://youtu.be/t1bKNj021do

But for the linking of the progress bar with a background process, this person was nice enough to create a sample app and code. https://github.com/tcbegley/dash-rq-demo

like image 98
Adam Schroeder Avatar answered Sep 20 '22 15:09

Adam Schroeder


I was able to use a for-loop to update the progress bar.

But i had to:

  1. Use dcc.Interval for when the dashboard should look for a new value.
  2. Use threading for making the worker work independently and not blocking the dashboard.
  3. Use Queue for thread safe communication between worker-thread and updating the progress bar.

Insted of using a global progress_memory and Queue, this could probably be grouped nicely using classes.

import dash
import time
import threading
import dash_bootstrap_components as dbc
from queue import Queue


progress_queue = Queue(1)
progress_memeory = 0


app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])


app.layout = dash.html.Div(children=[
    dash.html.H1(children='Test Progress Bar Using Loop'),
    dash.dcc.Interval(id='clock', interval=1000, n_intervals=0, max_intervals=-1),
    dbc.Progress(value=0, id="progress_bar"),
    dash.html.Button("Start Work", id='start_work', n_clicks=0)
])


@app.callback(
    [dash.Output("progress_bar", "value")],
    [dash.Input("clock", "n_intervals")])
def progress_bar_update(n):
    global progress_memeory
    if not progress_queue.empty():
        progress_bar_val = progress_queue.get()
        progress_memeory = progress_bar_val
    else:
        progress_bar_val = progress_memeory
    return(progress_bar_val,)
   

@app.callback([
    dash.Output("start_work", "n_clicks")],
    [dash.Input("start_work", "n_clicks")])
def start_bar(n):
    if n==0:
        return(0,)
    threading.Thread(target=start_work, args=(progress_queue,)).start()
    return(0,)


def start_work(output_queue):
    for i in range(101):
        time.sleep(0.5)
        if output_queue.empty():
            output_queue.put(i)
    return(None)

if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=False)
like image 38
KrisR89 Avatar answered Sep 21 '22 15:09

KrisR89