MultiRangeBar¶
MultiRangeBar shows several named ranges as segments of one bar.
Reach for it to visualize a whole made of distinct categories (done,
processing, scheduled, not started) as proportional segments of a
single bar, rather than a single fill fraction. markers gives one
character per category, and the segment sizes come from the bar
variable named by name. In the demo, units migrate between
segments until every one is “done”.
- class progressbar.widgets.MultiRangeBar(name, markers, **kwargs: Any)[source]
Bases:
Bar,VariableMixinA bar with multiple sub-ranges, each represented by a different symbol.
The various ranges are represented on a user-defined variable, formatted as
[['Symbol1', amount1], ['Symbol2', amount2], ...]
Create a MultiRangeBar.
- Parameters:
name – data[‘variables’] key holding the range amounts (see VariableMixin).
markers – One single-character marker (or callable, see string_or_lambda) per range, in the same order as the amounts in data[‘variables’][name].
**kwargs – Forwarded to Bar.__init__.
- get_values(progress: ProgressBarMixinBase, data: Data)[source]
Return the configured [amount, …] list, or [] if unset.
Example¶
"""``MultiRangeBar`` shows several named ranges as segments of one bar.
Reach for it to visualize a whole made of distinct categories -- done,
processing, scheduled, not started -- as proportional segments of a
single bar, rather than a single fill fraction. Compare
``MultiProgressBar``, which shows independent per-job progress instead
of categories of one whole. Its loop runs until every unit reaches the
"done" range rather than a fixed ``STEPS`` count, since that is what the
widget is for.
"""
import random
import time
import progressbar
random.seed(0)
UNITS = 25
def main() -> None:
markers = [
'\x1b[38;5;2m█\x1b[39m', # Done (green)
'\x1b[38;5;3m#\x1b[39m', # Processing (yellow)
'\x1b[38;5;1m.\x1b[39m', # Scheduled (red)
' ', # Not started
]
widgets = [progressbar.MultiRangeBar('amounts', markers=markers)]
amounts = [0] * (len(markers) - 1) + [UNITS]
with progressbar.ProgressBar(widgets=widgets) as bar:
while True:
incomplete = [
idx
for idx, amount in enumerate(amounts)
for _ in range(amount)
if idx != 0
]
if not incomplete:
break
which = random.choice(incomplete)
amounts[which] -= 1
amounts[which - 1] += 1
bar.update(amounts=amounts, force=True)
time.sleep(0.005)
if __name__ == '__main__':
main()
See also¶
MultiProgressBar: independent per-job progress instead of categories of one whole.
JobStatusBar: per-job success/failure markers instead of proportional segments.