2

I have been making a sorting visualizer in Python, based of "Sound of Sorting". I've ran into a problem. I can't run matplotlib plot and update it, while the sorting is happening, and I want the plot to be animated. The obvious solution would be asyncio or multi-threading, but I can't get it to work. I can't think up a solution to this and have resorted to asking for help. Here is the code:

from random import randint
from timeit import repeat
from matplotlib import animation
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import time
import numpy as np 
import os
import asyncio

def bubble_sort(array):
    n = len(array) 
    global arrayGlobal 
    for i in range(n):
        already_sorted = True
        for j in range(n - i - 1):
            if array[j] > array[j + 1]:

                array[j], array[j + 1] = array[j + 1], array[j]
                already_sorted = False
        if  already_sorted:
            break
        arrayGlobal = array
        time.sleep(0.1)
        print(arrayGlobal)
    return array 

def visTest():
    reshaped = np.reshape(arrayGlobal, (5, 5))
    fig = plt.figure()
    def animate(i):
        sns.heatmap(reshaped, cbar=False)
    anim = animation.FuncAnimation(fig, animate)
    plt.show()

ARRAY_LENGTH = 25
array = [randint(0, 100) for i in range(ARRAY_LENGTH)]

async def start():
  loop = asyncio.get_running_loop()
  await asyncio.gather(loop.run_in_executor(None, bubble_sort, (array)), loop.run_in_executor(None, visTest))

asyncio.run(start())

Thank you in advance.

1
  • 2
    Have you considered using the manim library (the one used to animate 3b1b videos if you are familiar), would be really powerful for your purpose here. Commented Dec 22, 2021 at 13:08

1 Answer 1

4

Depending on how you are running Python, you can use plt.pause(0.01) to show the intermediate plot. asyncio isn't needed (you aren't sorting millions of numbers).

Here is an example (tested in an interactive PyCharm environment).

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np

def bubble_sort(array):
    n = len(array)
    for i in range(n):
        already_sorted = True
        for j in range(n - i - 1):
            if array[j] > array[j + 1]:
                array[j], array[j + 1] = array[j + 1], array[j]
                already_sorted = False
            # sns.heatmap(np.reshape(array, (5, 5)), cbar=False, ax=ax)
            ax.cla()
            sns.barplot(x=np.arange(n), y=array,
                        hue=(np.arange(n) == j + 1) + 2 * (np.arange(n) > n - i - 1),
                        dodge=False, palette=['turquoise', 'crimson', 'deepskyblue'], ax=ax)
            ax.legend_.remove()
            ax.set_xticks([])

            plt.pause(0.1)
        plt.pause(1)
        if already_sorted:
            break
    return array

fig, ax = plt.subplots()
array = np.random.uniform(2, 100, 10)
bubble_sort(array)

bubble sort animation

Sign up to request clarification or add additional context in comments.

4 Comments

I’ve implement this, and it works great but the limit is the speed of the rendering. When I raise the number count to over 50, the rendering takes over a minute. How to render faster or increase the speed of the animation?
You can set the waiting smaller, e.g. pause(0.001) (the parameter is the time in seconds), but depending on your system and the size of the plot, it still will take much longer than 1 millisecond to show one of the frames. Note that bubble sort is a quadratic algorithm, sorting 50 numbers will use about 50^2/2 swaps. For faster rendering, you can create the first plot via seaborn, and in all the later steps only update heights and colors.
How would I update a seaborn plot, I cannot find any material on this. Can you please elaborate? Thank you.
Didn't it work with just decreasing the wait times? Doing all kind of internal optimisation would help a bit but wouldn't be extreme faster. Is it really that important to run it with 50 instead of 40 bars? It wouldn't work anymore for 60 or so, as it is a quadratic algorithm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.