Use a thread:

import itertools
import threading
import time
import sys

done = False
#here is the animation
def animate():
    for c in itertools.cycle(['|', '/', '-', '\\']):
        if done:
            break
        sys.stdout.write('\rloading ' + c)
        sys.stdout.flush()
        time.sleep(0.1)
    sys.stdout.write('\rDone!     ')

t = threading.Thread(target=animate)
t.start()

#long process here
time.sleep(10)
done = True

I also made a couple of minor modifications to your animate() function, the only really important one was adding sys.stdout.flush() after the sys.stdout.write() calls.

Answer from Andrew Clark on Stack Overflow
🌐
Medium
medium.com › @joloiuy › creating-captivating-terminal-animations-in-python-a-fun-and-interactive-guide-2eeb2a6b25ec
Creating Captivating Terminal Animations in Python: A Fun and Interactive Guide | by KH Huang | Medium
July 31, 2023 - Use ANSI escape codes to splash text and background colors onto the terminal canvas, bringing vibrancy to your animations. Interactive Animations: Make your users a part of the tale! Accept their input during the animation to add interactive elements and create an immersive experience. While simple ASCII animations are marvelous, you’ll be awe-inspired by the wonders you can achieve using dedicated Python libraries for terminal animations.
🌐
mkaz.blog
mkaz.blog › code › python-terminal-animation
Terminal Animation with Python - mkaz.blog
In Python, it is easy to update a single line of input using a \r carriage return instead of newline \n. Try this example in the REPL to illustrate: for i in range(10): print(f" On step # {i}", end="\r") time.sleep(0.2) print() I wasn’t quite sure how to do a multi-line animation, without using curses or a more elaborate setup. I’d heard about the rich library that allows for building richer displays on the terminal.
Discussions

Python how to make simple animated loading while process is running - Stack Overflow
0 make an animated waiting dot sequence in python terminal More on stackoverflow.com
🌐 stackoverflow.com
'Waiting' animation in command prompt (Python) - Stack Overflow
Python's built-in curses package contains utilities for controlling what is printed to a terminal screen. ... curses has nothing to do with this post. he was just asking about a animation loop, ofc you can make in curses but that is not the answer for this post. More on stackoverflow.com
🌐 stackoverflow.com
Python terminal animation - Code Review Stack Exchange
Is there a better way of creating this terminal animation without having a series of conditional statements (i.e. if ... elif ... elif...)? import sys, time count = 100 i = 0 num = 0 def animatio... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
January 9, 2018
I made a a tool for creating animations in the terminal with python!
2015: you wouldn't use photoshop in the terminal! 2022: More on reddit.com
🌐 r/Python
4
21
December 20, 2022
🌐
PyPI
pypi.org › project › terminal-animation
terminal-animation · PyPI
Decorators for terminal-based wait animations.
      » pip install terminal-animation
    
Published   Apr 14, 2021
Version   0.6
Top answer
1 of 11
61

Use a thread:

import itertools
import threading
import time
import sys

done = False
#here is the animation
def animate():
    for c in itertools.cycle(['|', '/', '-', '\\']):
        if done:
            break
        sys.stdout.write('\rloading ' + c)
        sys.stdout.flush()
        time.sleep(0.1)
    sys.stdout.write('\rDone!     ')

t = threading.Thread(target=animate)
t.start()

#long process here
time.sleep(10)
done = True

I also made a couple of minor modifications to your animate() function, the only really important one was adding sys.stdout.flush() after the sys.stdout.write() calls.

2 of 11
49

Getting inspiration from the accepted answer, here's a useful class I wrote, printing a loader à la nodejs cli:

from itertools import cycle
from shutil import get_terminal_size
from threading import Thread
from time import sleep


class Loader:
    def __init__(self, desc="Loading...", end="Done!", timeout=0.1):
        """
        A loader-like context manager

        Args:
            desc (str, optional): The loader's description. Defaults to "Loading...".
            end (str, optional): Final print. Defaults to "Done!".
            timeout (float, optional): Sleep time between prints. Defaults to 0.1.
        """
        self.desc = desc
        self.end = end
        self.timeout = timeout

        self._thread = Thread(target=self._animate, daemon=True)
        self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
        self.done = False

    def start(self):
        self._thread.start()
        return self

    def _animate(self):
        for c in cycle(self.steps):
            if self.done:
                break
            print(f"\r{self.desc} {c}", flush=True, end="")
            sleep(self.timeout)

    def __enter__(self):
        self.start()

    def stop(self):
        self.done = True
        cols = get_terminal_size((80, 20)).columns
        print("\r" + " " * cols, end="", flush=True)
        print(f"\r{self.end}", flush=True)

    def __exit__(self, exc_type, exc_value, tb):
        # handle exceptions with those variables ^
        self.stop()


if __name__ == "__main__":
    with Loader("Loading with context manager..."):
        for i in range(10):
            sleep(0.25)

    loader = Loader("Loading with object...", "That was fast!", 0.05).start()
    for i in range(10):
        sleep(0.25)
    loader.stop()

Also if you're willing to use an external library you might want to look into rich's console.status

from time import sleep
from rich.console import Console

console = Console()
tasks = [f"task {n}" for n in range(1, 11)]

with console.status("[bold green]Working on tasks...") as status:
    while tasks:
        task = tasks.pop(0)
        sleep(1)
        console.log(f"{task} complete")
🌐
Medium
medium.com › @guanghuiliang › make-a-simple-python-terminal-loading-animation-by-yourself-422c196fcb3b
Make a Simple Python Terminal Loading Animation by Yourself | by Gray | Medium
April 10, 2024 - To make symbols animated, we need to set the time interval between one symbol and another. We use time.sleep() as usual. Simply printing one of the symbols will show it in the terminal.
🌐
GitHub
github.com › ChrisBuilds › terminaltexteffects
GitHub - ChrisBuilds/terminaltexteffects: TerminalTextEffects (TTE) is a terminal visual effects engine, application, and Python library. · GitHub
TTE can be installed as a system application to produce effects in your terminal, or as a Python library to enable effects within your Python scripts/applications. TTE includes a growing library of built-in effects which showcase the engine's features. These features include: ... Complex character movement via Paths, Waypoints, and motion easing, with support for bezier curves. Complex animations via Scenes with symbol/color changes, layers, easing, and Path synced progression.
Starred by 4.1K users
Forked by 93 users
Languages   Python 99.9% | Nix 0.1%
🌐
Ask Ubuntu
askubuntu.com › questions › 1067434 › how-to-display-a-python-animation-in-bash-terminal
How to display a python animation in bash terminal - Ask Ubuntu
August 21, 2018 - $ ls animation.py binarydata.dat binary.f $ gfortran -o binary binary.f $ ./binary $ python animation.py body1.dat body2.dat Loading files: body1.dat body2.dat Plotting orbits...
Find elsewhere
Top answer
1 of 2
16

You can build up the string like this:

def animation(counter, length):
    stage = counter % (length * 2 + 2)
    if stage < length + 1:
        left_spaces = stage
    else:
        left_spaces = length * 2 - 1 - stage
    return '[' + ' ' * left_spaces + '=' + ' ' * (length - left_spaces) + ']'

for i in range(100):
    sys.stdout.write('\b\b\b')
    sys.stdout.write(animation(i, 6))
    sys.stdout.flush()
    time.sleep(0.2)

Alternatively store the animation strings in a tuple or list:

animation_strings = ('[=      ]', '[ =     ]', '[  =    ]', '[   =   ]',
                     '[    =  ]', '[     = ]', '[      =]', '[      =]',
                     '[     = ]', '[    =  ]', '[   =   ]', '[  =    ]',
                     '[ =     ]', '[=      ]')
for i in range(100):
    sys.stdout.write('\b\b\b')
    sys.stdout.write(animation_strings[i % len(animation_strings)])
    sys.stdout.flush()
    time.sleep(0.2)

You can replace the animation function with cycle from itertools:

import sys, time
from itertools import cycle
animation = cycle('[=      ]', '[ =     ]', '[  =    ]', '[   =   ]',
                  '[    =  ]', '[     = ]', '[      =]', '[      =]',
                  '[     = ]', '[    =  ]', '[   =   ]', '[  =    ]',
                  '[ =     ]', '[=      ]')
# alternatively:
# animation = cycle('[' + ' ' * n + '=' + ' ' * (6 - n) + ']' 
#                   for n in range(7) + range(6, -1, -1))

for _ in range(100):
    sys.stdout.write('\b\b\b')
    sys.stdout.write(animation.next())
    sys.stdout.flush()
    time.sleep(0.2)

Finally, you could make your own generator function.

def animation_generator(length):
    while True:
        for n in range(length + 1):
            yield '[' + ' ' * n + '=' + ' ' * (length - n) + ']'
        for n in range(length + 1):
            yield '[' + ' ' * (length - n) + '=' + ' ' * n + ']'

animation = animation_generator(6)
for _ in range(100):
    sys.stdout.write('\b\b\b')
    sys.stdout.write(animation.next())
    sys.stdout.flush()
    time.sleep(0.2)

EDIT: made the above suggestions less reliant on global variables

2 of 2
4

Notes:

  • Don't use global variables without a good (an extremely good) justification. A function is (should be) a black box that gets values and returns values (unless you have unavoidable side-effects to perform, for example reading a file or printing to the screen).
  • It's very cumbersome and inflexible to write every possible string of the progressbar by hand, use code instead to build them.

I'd write:

import sys
import time

def render(size, position):
    return "[" + (" " * position) + "=" + (" " * (size - position - 1)) + "]" 

def draw(size, iterations, channel=sys.stdout, waittime=0.2): 
    for index in range(iterations):
        n = index % (size*2)
        position = (n if n < size else size*2 - n - 1)
        bar = render(size, position)
        channel.write(bar + '\r')
        channel.flush()
        time.sleep(waittime)  

if __name__ == '__main__':
    draw(6, 100, channel=sys.stdout)
🌐
GitHub
gist.github.com › a911dd6e17aca6bcc6a2
Animations with Python and terminal output · GitHub
Animations with Python and terminal output. GitHub Gist: instantly share code, notes, and snippets.
🌐
Reddit
reddit.com › r/python › i made a a tool for creating animations in the terminal with python!
r/Python on Reddit: I made a a tool for creating animations in the terminal with python!
December 20, 2022 -

This is a little project I've been working on for a bit now. It's not super advanced, but it's way more complicated than anything I had done before and I'm really happy with it.

Anteater (not sure why I decided to name it that but oh well) is written 100% in python with only core modules. It uses curses to interact with the terminal while inside the program, and it uses ANSI escape codes to print in the rendered version of the animation.

Currently it supports:

  • selecting

  • drawing

  • filling

  • changing color

  • changing the character used to draw

  • erasing

  • copying & pasting

  • exporting

  • saving and importing

Github: https://github.com/BrewingWeasel/anteater

🌐
PyPI
pypi.org › project › asciimatics
asciimatics · PyPI
A cross-platform package to replace curses (mouse/keyboard input & text colours/positioning) and create ASCII animations
      » pip install asciimatics
    
Published   Oct 25, 2023
Version   1.15.0
🌐
GitHub
gist.github.com › Y4suyuki › 6805818
python script which print animation on console · GitHub
python script which print animation on console · Raw · print_anim.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Reddit
reddit.com › r/adventofcode › [2022 day 5 #1] small terminal python animation for part 1 of day 5, never tried "drawing" on terminal before but quite proud of the result ! (didn't put the whole thing because it's a bit long and we get the idea)
r/adventofcode on Reddit: [2022 Day 5 #1] Small terminal Python animation for part 1 of Day 5, never tried "drawing" on terminal before but quite proud of the result ! (didn't put the whole thing because it's a bit long and we get the idea)
December 6, 2022 - Awesome, came back this morning to check if you had posted it, looks really good love terminal diagrams ... I too would be interested in seeing the code! ... Would also be interested in seeing the code! ... Hey, sorry for the delay, was finishing up some things and fixing some bugs, you will find everything here : https://github.com/MrAntex/AoC-Day5p1-animated
🌐
GitHub
github.com › javialamo › Terminal-animation
GitHub - javialamo/Terminal-animation: Simple python code that creates an animation from a vector of ASCII draws
Simple python code that creates an animation from a vector of ASCII draws - javialamo/Terminal-animation
Author   javialamo
🌐
Real Python
realpython.com › lessons › animation
Animation (Video) – Real Python
This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas. ... By using the \r and \b escape sequences to control the position of the cursor, you can create flip-book style animations with your text.
Published   May 5, 2020
🌐
GeeksforGeeks
geeksforgeeks.org › python-create-simple-animation-for-console-based-application
Python | Create simple animation for console-based application - GeeksforGeeks
April 17, 2019 - As we know Python is a scripting language, and can be easily used to automate simple tasks. In this article, we will learn how to create a simple console-based animation, which can be used while developing a console based project as a utility.
🌐
PyPI
pypi.org › project › animation
animation
JavaScript is disabled in your browser. Please enable JavaScript to proceed · A required part of this site couldn’t load. This may be due to a browser extension, network issues, or browser settings. Please check your connection, disable any ad blockers, or try using a different browser
🌐
GitHub
github.com › neogib › animation-in-terminal
GitHub - neogib/animation-in-terminal: Console application created in Python 🐍 that enables displaying animations directly in the terminal. 😊 Developed with Textual and Pygame library. 📦
Terminal Animation Player is a console application created in Python that enables displaying animations directly in the terminal. The program uses the Textual library to create an interactive console user interface, along with sound support ...
Author   neogib