Search code examples
pythonpython-3.xformattingtqdm

Customize tqdm bar in Python


I'm trying to change the display of 10000.000000001317/10000 to only two decimals.

Finished: 100%|████████████████████████████| 10000.000000001317/10000 [00:01<00:00, 9330.68it/s]

This is my code right now;

def create_dataframe(size):    
    df = pd.DataFrame()
    pbar = tqdm(total=size)
    #Increment is equal to the total number of records to be generated divided by the fields to be created
        #divided by total (this being the necessary iterations for each field)
    increment = size / 5 / size
    df["ID"] = range(size)
    pbar.set_description("Generating Names")
    df["Name"], _ = zip(*[(fake.name(), pbar.update(increment)) for _ in range(size)])
    pbar.set_description("Generating Emails")
    df["Email"], _ = zip(*[(fake.free_email(), pbar.update(increment)) for _ in range(size)])
    pbar.set_description("Generating Addresses")
    df["Address"], _ = zip(*[(fake.address(), pbar.update(increment)) for _ in range(size)])
    pbar.set_description("Generating Phones")
    df["Phone"], _ = zip(*[(fake.phone_number(), pbar.update(increment)) for _ in range(size)])
    pbar.set_description("Generating Comments")
    df["Comment"], _ = zip(*[(fake.text(), pbar.update(increment)) for _ in range(size)])
    pbar.set_description("Finished")
    pbar.close()
    return df

According to the docs, or at least what I've understood, this would be the default formatting to the argument bar_format;

pbar = tqdm(total=size, bar_format='{desc}{percentage:3.0f}%|{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ''{rate_fmt}{postfix}]')

I tried:

  1. Setting .2f in n_ftm, the output of this results in an error.
pbar = tqdm(total=size, bar_format='{desc}{percentage:3.0f}%|{bar}| {n_fmt:.2f}/{total_fmt} [{elapsed}<{remaining}, ''{rate_fmt}{postfix}]')
  1. Or formatting the set_description,
pbar.set_description("Finished: {:.2f}/{:.2f}".format(pbar.n, size))

This prints another x/total before the actual bar;

Finished: 10000.00/10000.00: 100%|██████████| 10000.000000001317/10000 [00:01<00:00, 9702.65it/s]
  • Plus it would be ideal once the bar finished having 10000/10000 no decimals.

Solution

  • You cannot specify the number of floating points because n_fmt is a string. You can however pass unit_scale=True:

    pbar = tqdm(total=size,
                    bar_format='{desc}{percentage:3.0f}%|{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ''{rate_fmt}{postfix}]',
                    unit_scale=True)
    

    According to the doc:

    If 1 or True, the number of iterations will be reduced/scaled automatically and a metric prefix following the International System of Units standard will be added (kilo, mega, etc.)

    You'll get the following output for size=10000:

    Finished: 100%|█████████████████████████████████████████████████████████████████████| 10.0k/10.0k [00:03<00:00, 3.31kit/s]