Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 23131

PyQt5 - Using multiprocessing for matplotlib purposes

$
0
0

With this code i am trying to plot a pydub.AudioSegment signal which has duration=125msec.The plot time window (x-axis) is 3 sec.

code:

import timefrom PyQt5.QtCore import pyqtSignal, QThreadfrom multiprocessing import Process, Queue, Pipefrom datetime import datetime, timedeltaimport tracebackimport matplotlib.pyplot as pltfrom matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvasfrom matplotlib.dates import num2datefrom matplotlib.ticker import FuncFormatterimport numpy as npclass Final_Slice_Plot:    def __init__(self, main_self):        self.main_self = main_self        # chart        self.chart = Canvas(self)        self.chart.ax.set_facecolor((1, 1, 1))        self.chart.ax.tick_params(labelcolor='white')        # create process        self.process_number = 94        self.final_slice_plot_mother_pipe, self.final_slice_plot_child_pipe = Pipe()        self.final_slice_plot_queue = Queue()        self.final_slice_plot_emitter = Final_Slice_Plot_Emitter(self.final_slice_plot_mother_pipe)        self.final_slice_plot_emitter.error_signal.connect(lambda error_message: print(error_message))        self.final_slice_plot_emitter.plot_data_signal.connect(lambda plot_data: self.plot(plot_data))        self.final_slice_plot_emitter.start()        self.final_slice_plot_child_process = Final_Slice_Plot_Child_Proc(self.final_slice_plot_child_pipe, self.final_slice_plot_queue)        self.final_slice_plot_child_process.start()        counter = 0        for process in self.main_self.manage_processes_instance.processes:            if "process_number" in process:                if process["process_number"] == self.process_number:                    self.main_self.manage_processes_instance.processes[counter]["pid"] = self.final_slice_plot_child_process.pid                    self.main_self.manage_processes_instance.processes[counter]["start_datetime"] = datetime.now()                    self.main_self.manage_processes_instance.processes[counter]["status"] = "in_progress"            counter += 1        if self.main_self.manage_proccesses_window_is_open:            self.main_self.manage_proccesses_window_support_code.manage_proccesses_queue.put(                {"type": "table-update", "processes": self.main_self.manage_processes_instance.processes})    def close(self):        try:            try:                if self.final_slice_plot_child_process is not None:                    self.final_slice_plot_child_process.terminate()            except:                print(traceback.format_exc())            try:                if self.final_slice_plot_emitter is not None:                    self.final_slice_plot_emitter.terminate()            except:                print(traceback.format_exc())            counter = 0            for process in self.main_self.manage_processes_instance.processes:                if "process_number" in process:                    if process["process_number"] == self.process_number:                        self.main_self.manage_processes_instance.processes[counter]["pid"] = None                        self.main_self.manage_processes_instance.processes[counter]["start_datetime"] = None                        self.main_self.manage_processes_instance.processes[counter]["status"] = "stopped"                        self.main_self.manage_processes_instance.processes[counter]["cpu"] = 0                        self.main_self.manage_processes_instance.processes[counter]["ram"] = 0                counter += 1            if self.main_self.manage_proccesses_window_is_open:                self.main_self.manage_proccesses_window_support_code.manage_proccesses_queue.put(                    {"type": "table-update", "processes": self.main_self.manage_processes_instance.processes})            self.clear_plot()        except:            error_message = traceback.format_exc()            print(error_message)    # signal for plot_data_signal    def plot(self, plot_data):        try:            x_vals = plot_data[0]            y_vals = plot_data[1]            self.chart.li.set_xdata(x_vals)            self.chart.li.set_ydata(y_vals)            x_ticks = []            if (len(x_vals) > 0):                for i in range(499, 2500 + 1, 1000):                    tick = x_vals[0] + timedelta(milliseconds=i)                    x_ticks.append(tick)                plt.xticks(x_ticks)            self.chart.ax.set_xlim(x_vals[0], x_vals[0] + timedelta(milliseconds=3000))            self.chart.ax.xaxis.set_major_formatter(FuncFormatter(self.date_formatter_1))            self.chart.fig.canvas.draw()            self.chart.fig.canvas.flush_events()        except:            error_message = str(traceback.format_exc())            print(error_message)    # Clear the matplotlib plot    def clear_plot(self):        try:            x_vals = [datetime.now()]            y_vals = [0]            self.chart.li.set_xdata(x_vals)            self.chart.li.set_ydata(y_vals)            x_ticks = []            if (len(x_vals) > 0):                for i in range(499, 2500 + 1, 1000):                    tick = x_vals[0] + timedelta(milliseconds=i)                    x_ticks.append(tick)                plt.xticks(x_ticks)                self.chart.ax.set_xlim(x_vals[0], x_vals[0] + timedelta(milliseconds=3000))            self.chart.ax.xaxis.set_major_formatter(FuncFormatter(self.date_formatter_1))            self.chart.fig.canvas.draw()            self.chart.fig.canvas.flush_events()        except Exception as e:            error_message = str(traceback.format_exc())            print(error_message)    # Formats the x-axis of matplotlib plot    def date_formatter_1(self, a, b):        try:            t = num2date(a)            ms = str(t.microsecond)[:1]            res = f"{t.hour:02}:{t.minute:02}:{t.second:02}.{ms}"            # res = f"{t.hour:02}:{t.minute:02}:{t.second:02}"            return res        except Exception as e:            error_message = str(traceback.format_exc())            print(error_message)class Final_Slice_Plot_Emitter(QThread):    try:        error_signal = pyqtSignal(str)        plot_data_signal = pyqtSignal(list)    except:        pass    def __init__(self, from_process: Pipe):        try:            super().__init__()            self.data_from_process = from_process        except:            pass    def run(self):        try:            while True:'''if self.data_from_process.poll():                    data = self.data_from_process.recv()                else:                    time.sleep(0.1)                    continue'''                data = self.data_from_process.recv()                if data["type"] == "error":                    self.error_signal.emit(data["error_message"])                elif data["type"]=="plot_data":                    self.plot_data_signal.emit(data["plot_data"])        except:            error_message = traceback.format_exc()            self.error_signal.emit(error_message)class Final_Slice_Plot_Child_Proc(Process):    def __init__(self, to_emitter, from_mother):        try:            super().__init__()            self.daemon = False            self.to_emitter = to_emitter            self.data_from_mother = from_mother        except:            try:                error_message = str(traceback.format_exc())                to_emitter.send({"type": "error", "error_message": error_message})            except:                pass    def run(self):        try:            self.TIME_WINDOW = 3000            self.chunk_number = 0            self.current_duration_milliseconds = 0            self.now = datetime.now()            self.x_vals = np.array([])            self.y_vals = np.array([])            while(True):                data = self.data_from_mother.get()                if data["type"] == "slice":                    slice = data["slice"]                chunk_time = len(slice)                samples = slice.get_array_of_samples()                left_samples = samples[::2]                right_samples = samples[1::2]                left_audio_data = np.frombuffer(left_samples, np.int16)[::128]  # down sampling                right_audio_data = np.frombuffer(right_samples, np.int16)[::128]  # down sampling                audio_data = np.vstack((left_audio_data, right_audio_data)).ravel('F')                time_data = np.array([])                for i in range(0, len(audio_data)):                    time_data = np.append(time_data, self.now)                    self.now = self.now + timedelta(milliseconds=chunk_time / len(audio_data))                self.x_vals = np.concatenate((self.x_vals, time_data))                self.y_vals = np.concatenate((self.y_vals, audio_data))                if (self.x_vals.size > audio_data.size * (self.TIME_WINDOW / chunk_time)):                    self.x_vals = self.x_vals[audio_data.size:]                    self.y_vals = self.y_vals[audio_data.size:]                plot_data_values = [self.x_vals, self.y_vals]                self.to_emitter.send({"type": "plot_data", "plot_data": plot_data_values})                self.now = datetime.now()                self.chunk_number += 1                self.current_duration_milliseconds += chunk_time        except:            error_message = str(traceback.format_exc())            self.to_emitter.send({"type": "error", "error_message": error_message})class Canvas(FigureCanvas):    def __init__(self, parent):        try:            self.fig, self.ax = plt.subplots(figsize=(5, 4), dpi=200)            super().__init__(self.fig)            self.fig.patch.set_facecolor((6 / 255, 21 / 255, 154 / 255))            self.ax.set_position([0., 0, 1., 0.8])            self.ax.xaxis.tick_top()            self.ax.tick_params(axis='both', which='major', pad=1, length=2.4, width=0.5, color=(1, 1, 1))            parent.main_self.ui.verticalLayout_3.addWidget(self)            self.now = datetime.now()            self.chart_stop = self.now + timedelta(milliseconds=3000)            plt.cla()            plt.gca().xaxis.set_major_formatter(FuncFormatter(parent.date_formatter_1))            plt.xticks(fontsize=3)            self.ax.grid(False)            self.ax.set_ylim(-32768, 32768)            x_ticks = []            for i in range(499, 2500 + 1, 1000):                tick = self.now + timedelta(milliseconds=i)                x_ticks.append(tick)            plt.xticks(x_ticks)            self.ax.set_xlim(self.now, self.now + timedelta(milliseconds=3000))            self.li, = self.ax.plot([self.now, self.now + timedelta(milliseconds=3000)], [0, 0], color=(0, 1, 0.29),                                    linestyle='solid', marker=",")            self.show()        except:            error_message = traceback.format_exc()            print(error_message)

Error: Sometimes when i close the window, the application doesn't return until hard stop from PyCharm stop button (like Ctrl+C).

What am i doing wrong?


Viewing all articles
Browse latest Browse all 23131

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>