-1

I used threading library to plot 2 real-time diagrams using matplotlib.

from fbm import MBM
import matplotlib.pyplot as plt
import threading

plt.style.use('ggplot')
fig, ax = plt.subplots(nrows=2, ncols=1)


def h_90(t):
    return 0.9


def h_75(t):
    return 0.75


def thread_fgn_9():
    x_vec = []
    y_vec = []
    i = 1
    while True:
        f = MBM(n=1, hurst=h_90, length=1, method='riemannliouville')
        fgn_sample = f.mgn()
        x_vec.append(i)
        y_vec.append(fgn_sample[0])
        i += 1
        ax[0].plot(x_vec, y_vec, "g-o")
        plt.pause(0.1)
    plt.show()


def thread_fgn_75():
    x_vec_ = []
    y_vec_ = []
    i = 1
    while True:
        f = MBM(n=1, hurst=h_75, length=1, method='riemannliouville')
        fgn_sample = f.mgn()
        x_vec_.append(i)
        y_vec_.append(fgn_sample[0])
        i += 1
        ax[1].plot(x_vec_, y_vec_, "r-o")
        plt.pause(0.2)
    plt.show()


if __name__ == "__main__":

    plt.ion()
    x2 = threading.Thread(target=thread_fgn_75(), name="H_75")
    x2.daemon = True
    x2.start()
    x1 = threading.Thread(target=thread_fgn_9(), name="H_90")
    x1.daemon = True
    x1.start()

I expect to see to plots being plotted real-time but I see something like below: enter image description here

can anybody understand what is wrong in my code ?? The code is completed and you can simply just copy/paste in your IDE to run it.

Thanks

================= New change ================ I just changed the main section as below:

if __name__ == "__main__":

    x1 = threading.Thread(target=thread_fgn_9(), name="H_90").start()
    x2 = threading.Thread(target=thread_fgn_75(), name="H_75").start()
    plt.show()

but still the result is the same as before.

======New New change ===============

if __name__ == "__main__":
    x1 = threading.Thread(target=thread_fgn_9, name="H_90").start()
    x2 = threading.Thread(target=thread_fgn_75, name="H_75").start()
    #plt.pause(0.2)
    plt.show()

I just erased the parentheses in target=function_name it seems it is correct but the plot is not showing smoothly. Also I see an error in console like this:

  File "/usr/local/lib/python3.9/site-packages/matplotlib/transforms.py", line 312, in xmin
    return np.min(self.get_points()[:, 0])
  File "<__array_function__ internals>", line 5, in amin
RecursionError: maximum recursion depth exceeded

-------Final Change-----------------------

The best way to do this in matplotlib is below code:

plt.style.use('ggplot')
fig, ax = plt.subplots(nrows=2, ncols=1)
mutex = Lock()

def thread_fgn_9():
    print(threading.current_thread().getName())
    x_vec = []
    y_vec = []
    i = 1
    while True:
        #mutex.acquire()
        f = MBM(n=1, hurst=h_90, length=1, method='riemannliouville')
        fgn_sample = f.mgn()
        x_vec.append(i)
        y_vec.append(fgn_sample[0])
        i += 1
        ax[0].plot(x_vec, y_vec, "g-o")
        plt.pause(0.01)
        #mutex.release()


def thread_fgn_75():
    print(threading.current_thread().getName())
    x_vec_ = []
    y_vec_ = []
    i = 1
    while True:
        #mutex.acquire()
        f = MBM(n=1, hurst=h_75, length=1, method='riemannliouville')
        fgn_sample = f.mgn()
        x_vec_.append(i)
        y_vec_.append(fgn_sample[0])
        i += 1
        ax[1].plot(x_vec_, y_vec_, "r-o")
        plt.pause(0.01)
        #mutex.release()


if __name__ == "__main__":
    x1 = multiprocessing.Process(target=thread_fgn_9, name="H_90").start()
    x2 = multiprocessing.Process(target=thread_fgn_75, name="H_75").start()
    plt.show()

I believe the reason is because both processes try to write in one single main plot. In order to have a multiple smooth plot changing over time, we need to take another technique.

Ben Eslami
  • 70
  • 8

1 Answers1

1

thread_fgn_9 is being called and blocking even before it is sent to the thread. Be sure to send the function itself.

plt.pause or plt.show need to be called from the main thread. Additionally, Matplotlib makes no thread safety guarantees in general, so you should avoid this concept entirely unless you know exactly what you are doing. Consider the techniques in this question instead: Fast Live Plotting in Matplotlib / PyPlot