Reputation: 7447
When using the tqdm progress bar: can I add a message to the same line as the progress bar in a loop?
I tried using the "tqdm.write" option, but it adds a new line on every write. I would like each iteration to show a short message next to the bar, that will disappear in the next iteration. Is this possible?
Upvotes: 263
Views: 277245
Reputation: 7656
The example shown in Usage of tqdm works well for me.
pbar = tqdm(["a", "b", "c", "d"])
for char in pbar:
pbar.set_description("Processing %s" % char)
Or alternatively, starting Python 3.8 which supports the walrus operator :=
:
for char in (pbar := tqdm(["a", "b", "c", "d"])):
pbar.set_description(f"Processing {char}")
Upvotes: 489
Reputation: 130
When using the tqdm progress bar in Python, there are different ways to define it, either by using the with statement or by assigning the progress bar to a variable with tqdm()
function. In some cases, you may want to update the progress bar inside the loop without adding an extra indentation layer.
To achieve this, you can use the set_postfix()
method to update the progress bar with the latest information. To avoid adding an extra indentation layer, you can define the progress bar outside of the loop and use it inside the loop. For example, you can use the enumerate()
function to iterate over a list while keeping track of the index, and then pass this to the progress bar like this:
from tqdm import tqdm
object_list = ["a", "b", "c"]
pbar = tqdm(enumerate(object_list), descr="...")
for i, obj in pbar:
...
pbar.set_postfix("foo")
...
pbar.set_postfix("bar")
In this way, you define the tqdm progress bar before the loop, and then you can use the set_postfix()
method to update the progress bar inside the loop without adding an extra indentation layer. By using the enumerate()
function, you also have access to the current index, which you can pass to the set_postfix()
method to display it in the progress bar.
This approach provides the flexibility to update the progress bar inside the loop while keeping the code clean and readable. This answer is based on the comments from @cbrnr and @tim-mb.
Upvotes: -1
Reputation: 3472
Although all the answers here are correct, tqdm
also provides a set_postfix_str
method. The advantage over set_postfix
is that you can pass your own formatted string in place of key value pairs. Also set_postfix
sorts the key value pairs alphabetically. Here is an MWE.
from tqdm import tqdm
import numpy as np
loop_obj = tqdm(np.arange(10))
for i in loop_obj:
loop_obj.set_description(f"Count: {i}") # Adds text before progessbar
loop_obj.set_postfix_str(f"Next count: {i+1}") # Adds text after progressbar
Upvotes: 9
Reputation: 3738
I personally use .set_description() and a progression_bar assignment statement before the for loop:
from tqdm import tqdm
progression_bar = tqdm(["An", "iterable", "object"])
for element in (progression_bar):
progression_bar.set_description("Processing « %s »" % str(element))
Upvotes: 3
Reputation: 1797
Other answers focus on dynamic description, but for a static description you can add a desc
argument into the tqdm function.
from tqdm import tqdm
x = [5]*1000
for _ in tqdm(x, desc="Example"):
pass
Example: 100%|██████████████████████████████████| 1000/1000 [00:00<00:00, 1838800.53it/s]
Upvotes: 165
Reputation: 101
I personally find it much cleaner to use the with
statement:
from tqdm import tqdm
with tqdm(['a','b','c']) as t:
for c in t:
t.set_description(f'{c}')
Upvotes: 9
Reputation: 16570
You can change the description to show a small message before the progress bar, like this:
from tqdm import trange
from time import sleep
t = trange(100, desc='Bar desc', leave=True)
for i in t:
t.set_description("Bar desc (file %i)" % i)
t.refresh() # to show immediately the update
sleep(0.01)
/EDIT: in the latest releases of tqdm
, you can use t.set_description("text", refresh=True)
(which is the default) and remove t.refresh()
(thanks to Daniel for the tip).
Upvotes: 163
Reputation: 1965
You can use set_postfix
to add values directly to the bar.
Example:
from tqdm import tqdm
pbar = tqdm(["a", "b", "c", "d"])
num_vowels = 0
for ichar in pbar:
if ichar in ['a','e','i','o','u']:
num_vowels += 1
pbar.set_postfix({'num_vowels': num_vowels})
The postfix dictionary is integrated into the progress bar:
100%|███████████| 4/4 [00:11<00:00, 2.93s/it, num_vowels=1]
Instead of a dictionary, you can use set_postfix_str
to just add a string to the end of the progress bar.
Upvotes: 110