Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double Progress Bar in Python

People also ask

How do I use tqdm in Python?

Usage. Using tqdm is very simple, you just need to add your code between tqdm() after importing the library in your code. You need to make sure that the code you put in between the tqdm() function must be iterable or it would not work at all.

Does tqdm work in Pycharm?

It works smoothly in native jupyter.

What is Trange in tqdm?

It seems like the progress bar shows up whenever a tqdm. tqdm instance is constructed, which trange does: trange(n) is shorthand for tqdm.


Use the nested progress bars feature of tqdm, an extremely low overhead, very customisable progress bar library:

$ pip install -U tqdm

Then:

from tqdm import tqdm
# from tqdm.auto import tqdm  # notebook compatible
import time
for i1 in tqdm(range(5)):
    for i2 in tqdm(range(300), leave=False):
        # do something, e.g. sleep
        time.sleep(0.01)

(The leave=False is optional - needed to discard the nested bars upon completion.)

You can also use from tqdm import trange and then replace tqdm(range(...)) with trange(...). You can also get it working in a notebook.


I basically just want to add to the answer of @casper.dcl. In the slightly different case, where you have two nested for loops and want just a SINGLE progress bar you can do the following.

from tqdm import tqdm
import time
n = 5
m = 300
with tqdm(total=n * m) as pbar:
    for i1 in tqdm(range(n)):
        for i2 in tqdm(range(m)):
            # do something, e.g. sleep
            time.sleep(0.01)
            pbar.update(1)

I know that was not the question, but it might be still helpful for some folks.


It would require you to move the cursor position. I have written you a hacky thing to do it.

This script relies on the fact that the progressbar module assumes that you are on a fresh line to draw the progress bar. By simply moving the cursor up (using the escape code for "move cursor 1 row up"), and down (just using a newline. I could also use an escape code, but newline is easier and faster), one can maintain multiple progress bars.

import progressbar, time, sys

def up():
    # My terminal breaks if we don't flush after the escape-code
    sys.stdout.write('\x1b[1A')
    sys.stdout.flush()

def down():
    # I could use '\x1b[1B' here, but newline is faster and easier
    sys.stdout.write('\n')
    sys.stdout.flush()

# Total bar is at the bottom. Move down to draw it
down()
total = progressbar.ProgressBar(maxval=50)
total.start()

for i in range(1,51):
    # Move back up to prepare for sub-bar
    up()

    # I make a new sub-bar for every iteration, thinking it could be things
    # like "File progress", with total being total file progress.
    sub = progressbar.ProgressBar(maxval=50)
    sub.start()
    for y in range(51):
        sub.update(y)
        time.sleep(0.005)
    sub.finish()

    # Update total - The sub-bar printed a newline on finish, so we already
    # have focus on it
    total.update(i)
total.finish()

This is of course a bit hacky, but it gets the job done. I hope that it is useful.


Use enlighten:

import time
import enlighten

manager = enlighten.get_manager()
ticks = manager.counter(total=100, desc="Ticks", unit="ticks", color="red")
tocks = manager.counter(total=20, desc="Tocks", unit="tocks", color="blue")

for num in range(100):
    time.sleep(0.1)  # Simulate work
    print("The quick brown fox jumps over the lazy dog. {}".format(num))
    ticks.update()
    if not num % 5:
        tocks.update()

manager.stop()

enter image description here