Home > Back-end >  Plot functions using Matplotlib similar to Matlab
Plot functions using Matplotlib similar to Matlab

Time:10-25

I have a function which plots a figure

import matplotlib.pyplot as plt


def myplot(x, y):
    plt.figure()
    plt.plot(x, y)
    plt.show()


myplot([1, 2, 3], [4, 5, 6])
myplot([1, 2, 3], [4, 5, 6])

However after I run the script only one figure shows up, and the second one shows when I close the first figure. I can move plt.show() into main function which calls myplot and this works fine, but I still want a better way, just like plot in Matlab. Thank you in advance.

CodePudding user response:

this is not a simple thing, as Matlab is already running a GUI eventloop, while for python ... it depends on the IDE, for example Spyder will run it similar to Matlab as it is running an event loop, while Pycharm / VScode don't allow python to snatch their event loop, and jupyter notebook is running an asyncio server which sends the data to your browser so it can do it but it's not the same as Matlab .... so it depends on your IDE.

now assuming that you are running an interactive session inside your terminal ... or any IDE like IDLE, you can create another process that will be running that eventloop using loky, that has to run inside a thread ...

import matplotlib.pyplot as plt
import threading
from loky import ProcessPoolExecutor
import traceback

def myplot(*args,**kwargs):
    thread = threading.Thread(target=threaded_func,args=args,kwargs=kwargs,daemon=False)
    thread.start()

def threaded_func(*args,**kwargs):
    try:
        with ProcessPoolExecutor(max_workers=1) as executor:
            res = executor.submit(plotting_func,*args,**kwargs)
            res.result()
    except RuntimeError as e:
        pass

def plotting_func(*args,**kwargs):
    try:
        plt.figure()
        plt.plot(*args,**kwargs)
        plt.show()
    except Exception as e:
        traceback.print_exc()

myplot([1, 2, 3], [4, 5, 6])
myplot([1, 2, 3], [4, 5, 6])

this is obviously not perfect as you can only modify your plots inside your plotting_func, not inside your interactive code as Matlab does, and while there are ways to get some code working as expected, it really depends on the exact use-case, not a generic code like yours.

for example you can have matplotlib running a temporary eventloop in interactive mode.

import matplotlib.pyplot as plt
plt.ion()  # activate interactive mode

def myplot(x, y):
    plt.figure()
    plt.plot(x, y)
    plt.show()


myplot([1, 2, 3], [4, 5, 6])
myplot([1, 2, 3], [4, 5, 6])
plt.pause(5)  # run eventloop for 5 seconds

now everytime you want the plot to update you just call

plt.pause(5)

which will run the eventloop for 5 seconds for you to inspect the plot, and you can interactively modify it like matlab, but this is just a band-aid, and you have to think about writing python code that's not mirrored matlab code.

  • Related