I am trying to plot microphone speech (real time) with python and matplotlib.
Here is what i have done:
file:chart_1.py
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import dates as mpl_dates
from matplotlib.animation import FuncAnimation
from pydub import AudioSegment
import numpy as np
import datetime
import pyaudio
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# constants
self.CHUNK = int(16384/4)
self.CHUNK_TIME = 125 #msec
self.FORMAT = pyaudio.paInt16
self.CHANNELS = 1
self.RATE = 32750
self.p = pyaudio.PyAudio()
MainWindow.setObjectName("MainWindow")
MainWindow.resize(630, 200)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(0, 200))
MainWindow.setMaximumSize(QtCore.QSize(16777215, 200))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
MainWindow.setCentralWidget(self.centralwidget)
self.chart = Canvas(self)
self.chart.ax.set_facecolor((1,1,1))
self.chart.ax.tick_params(labelcolor='white')
self.stream = self.p.open(format=self.FORMAT,channels=self.CHANNELS,rate=self.RATE,input=True,output=True,frames_per_buffer=self.CHUNK)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Microphone chart"))
def plot_microphone_data(self):
now = datetime.datetime.now()
self.x_vals = []
self.y_vals = []
while(True):
data = self.stream.read(self.CHUNK)
#slice = AudioSegment(data, sample_width=2, frame_rate=self.RATE, channels=1)
#print(len(slice))
#print(len(slice.raw_data))
self.stream.write(data)
audio_data = np.frombuffer(data, np.int16)
self.chart.li.set_xdata(np.arange(len(audio_data)))
self.chart.li.set_ydata(audio_data)
self.chart.fig.canvas.draw()
self.chart.fig.canvas.flush_events()
class Canvas(FigureCanvas):
def __init__(self,parent):
self.fig , self.ax = plt.subplots(figsize=(5,4),dpi=200)
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(color=(1,1,1))
super().__init__(self.fig)
parent.verticalLayout.addWidget(self)
plt.cla()
plt.xticks(fontsize=5)
self.ax.grid(False)
self.li, = self.ax.plot([], [])
self.ax.set_xlim(0,1000)
self.ax.set_ylim(-8000,8000)
self.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
ui.plot_microphone_data()
sys.exit(app.exec_())
works well, but it hasn't time in x axis so i have made the file chart_2.py
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import dates as mpl_dates
from matplotlib.animation import FuncAnimation
from pydub import AudioSegment
import numpy as np
import datetime
import pyaudio
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# constants
self.CHUNK = int(16384/4)
self.CHUNK_TIME = 125 #msec
self.FORMAT = pyaudio.paInt16
self.CHANNELS = 1
self.RATE = 32750
self.TIME_WINDOW = 3000 #display 3 seconds on chart
self.p = pyaudio.PyAudio()
MainWindow.setObjectName("MainWindow")
MainWindow.resize(630, 200)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(0, 200))
MainWindow.setMaximumSize(QtCore.QSize(16777215, 200))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
MainWindow.setCentralWidget(self.centralwidget)
self.chart = Canvas(self)
self.chart.ax.set_facecolor((1,1,1))
self.chart.ax.tick_params(labelcolor='white')
self.stream = self.p.open(format=self.FORMAT,channels=self.CHANNELS,rate=self.RATE,input=True,output=True,frames_per_buffer=self.CHUNK,stream_callback=self.microphone_callback)
self.x_vals = np.array([])
self.y_vals = np.array([])
self.now = datetime.datetime.now()
self.stream.start_stream()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Microphone chart"))
def microphone_callback(self,in_data, frame_count, time_info, status):
data = in_data
#slice = AudioSegment(data, sample_width=2, frame_rate=self.RATE, channels=1)
#print(len(slice))
#print(len(slice.raw_data))
audio_data = np.frombuffer(data, np.int16)
time_data = np.array([])
for i in range(0,len(audio_data)):
time_data = np.append(time_data, self.now)
self.now = self.now+datetime.timedelta(milliseconds=self.CHUNK_TIME/len(audio_data))
self.x_vals = np.concatenate((self.x_vals, time_data), axis=0)
self.y_vals = np.concatenate((self.y_vals, audio_data), axis=0)
if(self.x_vals.size>audio_data.size*(self.TIME_WINDOW/self.CHUNK_TIME)):
self.x_vals = self.x_vals[audio_data.size:]
self.y_vals = self.y_vals[audio_data.size:]
self.chart.li.set_xdata(self.x_vals)
self.chart.li.set_ydata(self.y_vals)
x_ticks = []
for i in range(0,self.TIME_WINDOW+1,1000):
tick = self.x_vals[0]+datetime.timedelta(milliseconds=i)
x_ticks.append(tick)
plt.xticks(x_ticks)
self.chart.ax.set_xlim(x_ticks[0],x_ticks[-1])
self.chart.fig.canvas.draw()
self.chart.fig.canvas.flush_events()
return (data, pyaudio.paContinue)
class Canvas(FigureCanvas):
def __init__(self,parent):
self.fig , self.ax = plt.subplots(figsize=(5,4),dpi=200)
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(color=(1,1,1))
super().__init__(self.fig)
parent.verticalLayout.addWidget(self)
self.now = datetime.datetime.now()
self.chart_stop = self.now+datetime.timedelta(milliseconds=parent.TIME_WINDOW)
plt.cla()
date_format = mpl_dates.DateFormatter("%H:%M:%S")
plt.gca().xaxis.set_major_formatter(date_format)
plt.xticks(fontsize=5)
self.ax.grid(False)
self.li, = self.ax.plot([], [])
self.ax.set_ylim(-8000,8000)
x_ticks = []
for i in range(0,parent.TIME_WINDOW+1,1000):
tick = self.now+datetime.timedelta(milliseconds=i)
x_ticks.append(tick)
plt.xticks(x_ticks)
self.ax.set_xlim(x_ticks[0],x_ticks[-1])
self.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Chart 2 has time on upper x axis but it has some delay problems.
Can you please advice me to fix that?
Related
I am trying to create a gui with several live plot EEG/ECG graphs (each plot on different axes).
From what I understand, I need to create multiple PlotWidgets inside a grid layout.
I have created a live plot using pyqtgraph, below however I am unsure how to merge this into the GUI:
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import collections
import random
import time
import math
import numpy as np
class DynamicPlotter:
def __init__(self, sampleinterval=0.1, timewindow=10., size=(600, 350)):
# Data stuff
self.interval = int(sampleinterval * 1000)
self.bufsize = int(timewindow / sampleinterval)
self.databuffer = collections.deque([0.0] * self.bufsize, self.bufsize)
self.x = np.linspace(-timewindow, 0.0, self.bufsize)
self.y = np.zeros(self.bufsize, dtype=float)
# PyQtGraph stuff
self.app = QtGui.QApplication([])
self.plt = pg.plot(title='EEG/ECG Live Plot')
self.plt.resize(*size)
self.plt.showGrid(x=True, y=True)
#self.plt.setXRange(5,20, padding=0)
self.plt.setLabel('left', 'Amplitude', 'uVrms')
self.plt.setLabel('bottom', 'Time', 's')
self.curve = self.plt.plot(self.x, self.y, pen=(255, 0, 0))
# QTimer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateplot)
self.timer.start(self.interval)
def getdata(self):
frequency = 0.5
noise = random.normalvariate(0., 1.)
new = 10. * math.sin(time.time() * frequency * 2 * math.pi) + noise
return new
def updateplot(self):
self.databuffer.append(self.getdata())
self.y[:] = self.databuffer
self.curve.setData(self.x, self.y)
self.app.processEvents()
def run(self):
self.app.exec_()
if __name__ == '__main__':
livePlot = DynamicPlotter(sampleinterval=0.05, timewindow=5.)
livePlot.run()
Here is the basic GUI (3 plot widgets inside grid, and a few labels in mainWindow):
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(845, 727)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.labelTitle = QtWidgets.QLabel(self.centralwidget)
self.labelTitle.setGeometry(QtCore.QRect(280, 0, 291, 51))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.labelTitle.setFont(font)
self.labelTitle.setObjectName("labelTitle")
self.labelCh1 = QtWidgets.QLabel(self.centralwidget)
self.labelCh1.setGeometry(QtCore.QRect(20, 90, 31, 51))
self.labelCh1.setObjectName("labelCh1")
self.labelCh2 = QtWidgets.QLabel(self.centralwidget)
self.labelCh2.setGeometry(QtCore.QRect(20, 180, 31, 51))
self.labelCh2.setObjectName("labelCh2")
self.labelCh3 = QtWidgets.QLabel(self.centralwidget)
self.labelCh3.setGeometry(QtCore.QRect(20, 260, 31, 51))
self.labelCh3.setObjectName("labelCh3")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(70, 70, 741, 261))
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.ch1PlotWidget = PlotWidget(self.widget)
self.ch1PlotWidget.setObjectName("ch1PlotWidget")
self.gridLayout.addWidget(self.ch1PlotWidget, 0, 0, 1, 1)
self.ch2PlotWidget = PlotWidget(self.widget)
self.ch2PlotWidget.setObjectName("ch2PlotWidget")
self.gridLayout.addWidget(self.ch2PlotWidget, 1, 0, 1, 1)
self.ch3PlotWidget = PlotWidget(self.widget)
self.ch3PlotWidget.setObjectName("ch3PlotWidget")
self.gridLayout.addWidget(self.ch3PlotWidget, 2, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 845, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.labelTitle.setText(_translate("MainWindow", "EEG/ECG Recording GUI"))
self.labelCh1.setText(_translate("MainWindow", "Ch 1"))
self.labelCh2.setText(_translate("MainWindow", "Ch 2"))
self.labelCh3.setText(_translate("MainWindow", "Ch 3"))
from pyqtgraph import PlotWidget
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
My question is how do I integrate these two so I can plot the live graphs in each widget?
Ideally I want to use a super class so I can simply import the unedited gui.
I have tried importing the gui.Ui_MainWindow into the class and then overwriting the self.plt to self.Ch1PlotWidget
from pyqtgraph.Qt import QtGui, QtCore, QtWidgets
import gui as gui
import sys
import pyqtgraph as pg
import collections
import random
import time
import math
import numpy as np
class MainWindow(QtWidgets.QMainWindow, gui.Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.setupUi(self)
# Data stuff
self.interval = 100
self.bufsize = int(10 / self.interval)
self.databuffer = collections.deque([0.0] * self.bufsize, self.bufsize)
self.x = np.linspace(-10, 0.0, self.bufsize)
self.y = np.zeros(self.bufsize, dtype=float)
# PyQtGraph stuff
self.app = QtGui.QApplication([])
self.ch1PlotWidget = pg.plot(title='Live Plot')
self.ch1PlotWidget.resize(600, 350)
self.ch1PlotWidget.showGrid(x=True, y=True)
# self.plt.setXRange(5,20, padding=0)
self.ch1PlotWidget.setLabel('left', 'Amplitude', 'uVrms')
self.ch1PlotWidget.setLabel('bottom', 'Time', 's')
self.curve = self.ch1PlotWidget.plot(self.x, self.y, pen=(255, 0, 0))
# QTimer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateplot)
self.timer.start(self.interval)
def getdata(self):
frequency = 0.5
noise = random.normalvariate(0., 1.)
new = 10. * math.sin(time.time() * frequency * 2 * math.pi) + noise
return new
def updateplot(self):
self.databuffer.append(self.getdata())
self.y[:] = self.databuffer
self.curve.setData(self.x, self.y)
self.app.processEvents()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Sorry for all the code, I am just very confused on how to implement logic to the gui.
Here is an option where you can use both classes with minimal changes.
Change the DynamicPlotter constructor to accept a PlotWidget as a argument instead of creating a new one, since they are created and added to a layout in Ui_Mainwindow. In the MainWindow class, create a DynamicPlotter object for each plot (and keep a persistent reference, in this case I added them to a list self.plots).
class DynamicPlotter:
def __init__(self, plot, sampleinterval=0.1, timewindow=10., size=(600, 350)):
# Data stuff
self.interval = int(sampleinterval * 1000)
self.bufsize = int(timewindow / sampleinterval)
self.databuffer = collections.deque([0.0] * self.bufsize, self.bufsize)
self.x = np.linspace(-timewindow, 0.0, self.bufsize)
self.y = np.zeros(self.bufsize, dtype=float)
# PyQtGraph stuff
self.plt = plot
self.plt.setTitle('EEG/ECG Live Plot')
self.plt.resize(*size)
self.plt.showGrid(x=True, y=True)
#self.plt.setXRange(5,20, padding=0)
self.plt.setLabel('left', 'Amplitude', 'uVrms')
self.plt.setLabel('bottom', 'Time', 's')
self.curve = self.plt.plot(self.x, self.y, pen=(255, 0, 0))
# QTimer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateplot)
self.timer.start(self.interval)
def getdata(self):
frequency = 0.5
noise = random.normalvariate(0., 1.)
new = 10. * math.sin(time.time() * frequency * 2 * math.pi) + noise
return new
def updateplot(self):
self.databuffer.append(self.getdata())
self.y[:] = self.databuffer
self.curve.setData(self.x, self.y)
class MainWindow(QtWidgets.QMainWindow, gui.Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.setupUi(self)
self.plots = []
for plot in (self.ch1PlotWidget, self.ch2PlotWidget, self.ch3PlotWidget):
self.plots.append(
DynamicPlotter(plot, sampleinterval=0.05, timewindow=5.)
)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
so I just started a new project in which I need to present data I collected on a GUI. For that purpose I created a test script, that reads the data from a .mat file and then calculates the surface plots. So far everything is working. Now I need to start with the GUI. I already managed to create an other test program that can open the OpenFileName-Dialog and reads the data from the file.
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as Navi
from matplotlib.figure import Figure
import seaborn as sns
import pandas as pd
import sip
import h5py
import mat73
import numpy as np
class MatplotlibCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width = 5, height = 4, dpi = 120):
fig = Figure(figsize = (width,height))
self.axes = fig.add_subplot(111)
super(MatplotlibCanvas,self).__init__(fig)
fig.tight_layout()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1466, 910)
font = QtGui.QFont()
font.setFamily("Tahoma")
MainWindow.setFont(font)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(280, 0, 561, 441))
self.graphicsView.setObjectName("graphicsView")
self.graphicsView_2 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_2.setGeometry(QtCore.QRect(860, 0, 561, 441))
self.graphicsView_2.setObjectName("graphicsView_2")
self.graphicsView_3 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_3.setGeometry(QtCore.QRect(280, 440, 561, 441))
self.graphicsView_3.setObjectName("graphicsView_3")
self.graphicsView_4 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_4.setGeometry(QtCore.QRect(860, 440, 561, 441))
self.graphicsView_4.setObjectName("graphicsView_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 90, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.action_Open = QtWidgets.QAction(MainWindow)
self.action_Open.setObjectName("action_Open")
self.action_Save = QtWidgets.QAction(MainWindow)
self.action_Save.setObjectName("action_Save")
self.action_Export = QtWidgets.QAction(MainWindow)
self.action_Export.setObjectName("action_Export")
self.action_Exit = QtWidgets.QAction(MainWindow)
self.action_Exit.setObjectName("action_Exit")
self.filename = ''
self.canv = MatplotlibCanvas(self)
self.df = []
self.toolbar = Navi(self.canv, self.centralwidget)
self.pushButton.clicked.connect(self.getFile)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def getFile(self):
""" this function will get the adress of the mat file location
also calls a readData function
"""
self.filename = QFileDialog.getOpenFileName(filter="mat (*.mat)")[0]
print("File: ", self.filename)
self.readData()
def readData(self):
self.df = mat73.loadmat(self.filename, use_attrdict=True)
struct = self.df['DemoData']
print(struct.Nr.data)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open "))
self.action_Open.setText(_translate("MainWindow", "&Open"))
self.action_Save.setText(_translate("MainWindow", "&Save"))
self.action_Export.setText(_translate("MainWindow", "&Export"))
self.action_Exit.setText(_translate("MainWindow", "&Quit"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Since I can read the data, next step would be to create the surface plots and display the data. My idea was to use the graphicsView elements to display the four needed plots, but I just can't find how to link the figures, I used in the first test program (without GUI) to the graphicsView element. For the figure I used the following code line:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(pArray, rArray, trArray, alpha = 0.5)
surf = ax.plot_surface(pArray, rArray, tArray, cmap=cm.jet, alpha = 1)
Can someone give me a tip, how I could achieve that?
Edit: I uploaded a .mat File .mat File
I have to note that:
mat73 has trouble reading the provided .mat so I use scipy.
The data contained in the .mat are one-dimensional arrays so they could not form a surface since for this two-dimensional arrays are required so I will only show how to draw the points.
Due to the large number of dots, painting takes time and may freeze
The logic is to work with the FigureCanvas and create 3d plots:
from functools import cached_property
from PyQt5.QtWidgets import QApplication, QFileDialog, QMainWindow
from matplotlib.backends.backend_qt5agg import (
FigureCanvas,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
from matplotlib import cm
import scipy.io as sio
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ax = self.canvas.figure.add_subplot(projection="3d")
self.setCentralWidget(self.canvas)
self.addToolBar(self.toolbar)
file_menu = self.menuBar().addMenu("&File")
open_action = file_menu.addAction("&Open")
open_action.triggered.connect(self.handle_open_action_triggered)
#cached_property
def canvas(self):
return FigureCanvas()
#cached_property
def toolbar(self):
return NavigationToolbar(self.canvas, self)
def handle_open_action_triggered(self):
filename, _ = QFileDialog.getOpenFileName(self, filter="mat (*.mat)")
if filename:
self.load_mat(filename)
def load_mat(self, filename):
res = sio.loadmat(filename)
record = res["record"]
data = record["Data"]
temp_ref = data[0, 0]["TempRef"][0, 0][0, 0]["data"]
nr = data[0][0]["Nr"][0, 0][0, 0]["data"]
temp_act = data[0, 0]["TempAct"][0, 0][0, 0]["data"]
self.update_plot(temp_ref, nr, temp_act)
def update_plot(self, x, y, z):
print(x.shape, y.shape, z.shape)
self.ax.scatter(x, y, z)
self.canvas.draw()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I'm drawing a graph in the matplotlib by converting to FFT with Arduino data. However, the same error does not cause a graph. I think it's because of self in update() what should I do? I don't know how to change when there is a Typeerror in my code. If you find a problem, can you tell me?
+ I solved the error. However, the graph is not printed. The code has been modified as a whole. What happen?
from PyQt5.QtWidgets import*
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import random
from PyQt5 import QtCore, QtGui, QtWidgets
import datetime
import serial
import time
import random
import numpy as np
from matplotlib import animation
from collections import deque # import a "circular" list
from threading import Thread, Lock
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1212, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.widget = matplotlibWidget()
self.widget.setObjectName("widget")
self.gridLayout.addWidget(self.widget, 0, 0, 1, 1)
self.centralwidget.setLayout(self.gridLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
#from matplotlibwidgetFile import matplotlibWidget
class matplotlibWidget(QWidget):
def __init__(self, parent = None):
QWidget.__init__(self,parent)
self.i = 0
self.data = []
lock = Lock()
freq = 2000 # 1/T
self.guarda = 100 # 200
r = range(0, int(freq/2+1), int(freq/self.guarda))
self.frequencia = np.fft.fftfreq(self.guarda, d=1/freq)
self.acelx = deque([], maxlen=self.guarda)
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvas(self.fig)
self.right_layout = QVBoxLayout()
self.right_layout.addWidget(self.canvas)
self.setLayout(self.right_layout)
self.ax.set_xlim((0,int(freq/2)))
self.ax.set_ylim((0,1000))
self.line, = self.ax.plot([],[])
self.ax.grid(True)
def data_input():
for line in arduinoData:
try:
self.i+=1
self.acelx.append(float(line))
with lock:
if self.i > len(self.acelx):
self.data = np.fft.fft(self.acelx)
except ValueError:
pass
t = Thread(target=data_input)
t.daemon = True
t.start()
S = Scope(self.line,self.frequencia, self.guarda, self.data, self.ax, self.acelx, self.i )
timer = QtCore.QTimer()
timer.timeout.connect(S.update)
timer.start(0)
class Scope(matplotlibWidget) :
def __init__(self, line, frequencia, guarda, data, ax, acelx, i) :
self.line, = line,
self.ax = ax
self.frequencia = frequencia
self.guarda = guarda
self.data = data
self.acelx = acelx
self.i = i
def update(self) :
if self.i > len(self.acelx) :
self.line.set_data(self.frequencia[:int(self.guarda/2)], abs(np.real(self.data[:int(self.guarda/2)])))
self.ax.figure.canvas.draw()
return (self.line,)
if __name__ == "__main__":
import sys
value = [0,0,0,0,0,0,0,0,0,0]
arduinoData = serial.Serial('com5', 9600)
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
You have to create instance:
s = Scope()
timer = QtCore.QTimer()
timer.timeout.connect(s.update)
or
timer = QtCore.QTimer()
timer.timeout.connect(Scope().update)
previous question (link)
Here i want that when i move the scroll bar using mouse it will not scroll the graph but when i leave the mouse then the graph will be updated. Here every time axis limit are updating but i want it will update the axis limit when i leave the mouse moving the scroll bar at a certain position. Note : Here y -axis trick label position will be fixed and it would be visible but value will update when i scroll the graph.and i also want that scroll bar will start from right position.
Here my program :
import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QMainWindow,QVBoxLayout
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtGui, QtWidgets
import datetime
from matplotlib.dates import num2date, date2num
from mpl_finance import candlestick_ochl as candlestick
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.dates as mdates
import pylab as pl
class MainWindow_code_serarch(object):
def setup_code_serarch(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1070, 680)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget1 = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget1.setGeometry(QtCore.QRect(17, 30, 741, 13))
self.verticalLayoutWidget1.setObjectName("verticalLayoutWidget")
self.verticalLayout1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget1)
self.verticalLayout1.setContentsMargins(0, 0, 0, 0)
self.verticalLayout1.setObjectName("verticalLayout1")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(17, 10, 1040, 603))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.figure = Figure(figsize=(100,7.2), dpi=80, facecolor='k')
self.canvas = FigureCanvas(self.figure)
self.canvas.draw()
# self.widget = QtWidgets.QWidget()
# self.scroll_area = QtWidgets.QScrollArea(self.widget)
# self.scroll_area.setWidget(self.canvas)
# self.verticalLayout.addWidget(self.scroll_area)
self.scroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal)
self.axes, self.axes2 = self.figure.subplots(nrows=2, sharex=True)
self.verticalLayout.addWidget(self.canvas)
self.verticalLayout.addWidget(self.scroll)
data = {
'date': ['2018/10/29','2018/10/30', '2018/11/03', '2018/11/04', '2018/11/05', '2018/11/07', '2018/11/10', '2018/11/11','2018/11/12','2018/11/13'],
'open': [8824,8824, 8726.31, 8642.14, 8531.51, 8630.25, 8602.50, 8640.22,8202.50, 8610.22],
'high': [8858,8858, 8748.60, 8551.36, 8653.16, 8476.69, 8630, 8570.56 ,8602.50, 8640.22],
'low': [8688,8688, 8743.67, 8550.76, 8449.50, 8631.83, 8602.18, 8743.22 ,8502.50, 8540.22],
'close': [8820,8820, 8747.17, 8550.52, 8553., 8517.10, 8628.78, 8588.52 ,8602.50, 8640.22],
'volume': [17759.56,17759.56, 120000.17, 18739.52, 38599.50, 16517.10, 17723.78, 15588.52 ,28602.50, 28640.22]
}
x = date2num([datetime.datetime.strptime(d, '%Y/%m/%d').date() for d in data['date']])
t= np.arange(len(data['date']))
candle_trace = zip(t, data['open'], data['high'], data['low'], data['close'], data['volume'])
candlestick(self.axes, candle_trace, width=.75, colorup='g', colordown='r')
self.axes2.plot(t, [1, 2, 3, 4, 7, 8, 9,6,6,9])
self.axes.set_position([0.02, 0.37, 0.88, 0.6])
self.axes2.set_position([0.02, 0.15, 0.88, 0.22])
self.axes.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
self.axes.yaxis.tick_right()
self.axes2.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
self.axes2.grid(color='lightgray', linewidth=.5, linestyle=':')
self.axes.grid(color='lightgray', linewidth=.5, linestyle=':')
self.axes2.yaxis.tick_right()
self.axes.autoscale_view()
self.axes2.autoscale_view()
self.axes.set_facecolor('#041105')
self.axes2.set_facecolor('#041105')
# N = len(dates)
self.axes.set_xticks(range(0, len((x)), 1))
self.axes.set_xticklabels([mdates.num2date(d).strftime('%b-%d') for d in x])
self.axes.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
self.axes2.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
self.canvas.draw()
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 246, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# self.pushButton.clicked.connect(self.graphShowCode)
self.step = .1
self.setupSlider()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
# self.pushButton.setText(_translate("MainWindow", "OK"))
def setupSlider(self):
self.lims = np.array(self.axes2.get_xlim())
print("limit"+str(self.lims))
self.scroll.setPageStep(self.step * 100)
self.scroll.actionTriggered.connect(self.update)
self.update()
def update(self, evt=None):
r = self.scroll.value() / ((1 + self.step) * 100)
l1 = self.lims[0] + r * np.diff(self.lims)
l2 = l1 + np.diff(self.lims) * self.step
self.axes2.set_xlim(l1, l2)
self.axes.set_xlim(l1, l2)
print(self.scroll.value(), l1, l2)
self.figure.canvas.draw_idle()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = MainWindow_code_serarch()
ui.setup_code_serarch(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
QScrollBar inherits a comprehensive set of signals from QAbstractSlider.
I have used sliderReleased(). because it is emit when the user releases the slider.To start scroll bar from right position. I initiate scroll bar value (99) Because here i find scroll bar minimal value is (0) and maximum value is (99).
my program :
import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QMainWindow,QVBoxLayout
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtGui, QtWidgets
import datetime
from matplotlib.dates import num2date, date2num
from mpl_finance import candlestick_ochl as candlestick
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.dates as mdates
import pylab as pl
class MainWindow_code_serarch(object):
def setup_code_serarch(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1070, 680)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget1 = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget1.setGeometry(QtCore.QRect(17, 30, 741, 13))
self.verticalLayoutWidget1.setObjectName("verticalLayoutWidget")
self.verticalLayout1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget1)
self.verticalLayout1.setContentsMargins(0, 0, 0, 0)
self.verticalLayout1.setObjectName("verticalLayout1")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(17, 10, 1040, 603))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.figure = Figure(figsize=(100,7.2), dpi=80, facecolor='k')
self.canvas = FigureCanvas(self.figure)
self.canvas.draw()
# self.widget = QtWidgets.QWidget()
# self.scroll_area = QtWidgets.QScrollArea(self.widget)
# self.scroll_area.setWidget(self.canvas)
# self.verticalLayout.addWidget(self.scroll_area)
self.scroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal)
self.axes, self.axes2 = self.figure.subplots(nrows=2, sharex=True)
self.verticalLayout.addWidget(self.canvas)
self.verticalLayout.addWidget(self.scroll)
self.scroll.setValue(99)
data = {
'date': ['2018/10/29','2018/10/30', '2018/11/03', '2018/11/04', '2018/11/05', '2018/11/07', '2018/11/10', '2018/11/11','2018/11/12','2018/11/13'],
'open': [8824,8824, 8726.31, 8642.14, 8531.51, 8630.25, 8602.50, 8640.22,8202.50, 8610.22],
'high': [8858,8858, 8748.60, 8551.36, 8653.16, 8476.69, 8630, 8570.56 ,8602.50, 8640.22],
'low': [8688,8688, 8743.67, 8550.76, 8449.50, 8631.83, 8602.18, 8743.22 ,8502.50, 8540.22],
'close': [8820,8820, 8747.17, 8550.52, 8553., 8517.10, 8628.78, 8588.52 ,8602.50, 8640.22],
'volume': [17759.56,17759.56, 120000.17, 18739.52, 38599.50, 16517.10, 17723.78, 15588.52 ,28602.50, 28640.22]
}
x = date2num([datetime.datetime.strptime(d, '%Y/%m/%d').date() for d in data['date']])
t= np.arange(len(data['date']))
candle_trace = zip(t, data['open'], data['high'], data['low'], data['close'], data['volume'])
candlestick(self.axes, candle_trace, width=.75, colorup='g', colordown='r')
self.axes2.plot(t, [1, 2, 3, 4, 7, 8, 9,6,6,9])
self.axes.set_position([0.02, 0.37, 0.88, 0.6])
self.axes2.set_position([0.02, 0.15, 0.88, 0.22])
self.axes.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
self.axes.yaxis.tick_right()
self.axes2.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
self.axes2.grid(color='lightgray', linewidth=.5, linestyle=':')
self.axes.grid(color='lightgray', linewidth=.5, linestyle=':')
self.axes2.yaxis.tick_right()
self.axes.autoscale_view()
self.axes2.autoscale_view()
self.axes.set_facecolor('#041105')
self.axes2.set_facecolor('#041105')
# N = len(dates)
self.axes.set_xticks(range(0, len((x)), 1))
self.axes.set_xticklabels([mdates.num2date(d).strftime('%b-%d') for d in x])
self.axes.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
self.axes2.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
self.canvas.draw()
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 246, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# self.pushButton.clicked.connect(self.graphShowCode)
self.step = .1
self.setupSlider()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
# self.pushButton.setText(_translate("MainWindow", "OK"))
def setupSlider(self):
self.lims = np.array(self.axes2.get_xlim())
print("limit"+str(self.lims))
self.scroll.setPageStep(self.step * 100)
# self.scroll.actionTriggered.connect(self.update)
self.scroll.sliderReleased.connect(self.update)
self.update()
def update(self, evt=None):
r = self.scroll.value() / ((1 + self.step) * 100)
l1 = self.lims[0] + r * np.diff(self.lims)
l2 = l1 + np.diff(self.lims) * self.step
self.axes2.set_xlim(l1, l2)
self.axes.set_xlim(l1, l2)
print(self.scroll.value(), l1, l2)
self.figure.canvas.draw_idle()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = MainWindow_code_serarch()
ui.setup_code_serarch(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I have GUI developed with PyQt5 with an interactive scatterplot in a widget and 2 lineEdit. By clicking a dot, I can get the x and y values but I can't populate my two lineEdit with the two values.
Front_end code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(539, 400)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEdit.sizePolicy().hasHeightForWidth())
self.lineEdit.setSizePolicy(sizePolicy)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 1)
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setObjectName("widget")
self.gridLayout.addWidget(self.widget, 0, 1, 2, 1)
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEdit_2.sizePolicy().hasHeightForWidth())
self.lineEdit_2.setSizePolicy(sizePolicy)
self.lineEdit_2.setObjectName("lineEdit_2")
self.gridLayout.addWidget(self.lineEdit_2, 1, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Back_end code:
import sys
import matplotlib.pyplot as plt
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QSizePolicy
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from front_test import Ui_MainWindow
class Graph_init(FigureCanvas):
def __init__(self, parent=None):
fig = Figure()
fig.patch.set_facecolor("None")
self.axes = fig.add_subplot(111)
self.compute_initial_figure()
FigureCanvas.__init__(self, fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
FigureCanvas.mpl_connect(self, 'pick_event', self.onclick)
def onclick(self, event):
ind = event.ind[0]
data = event.artist.get_offsets()
xdata, ydata = data[ind,:]
print ((xdata, ydata))
index = [10,20,30].index(xdata)
x = [10,20,30]
y = [100,100,150]
size = [1000,2000,3000]
x_high = x[index]
y_high = y[index]
size_high = size[index]
del x[index]
del y[index]
del size[index]
self.axes.clear()
self.axes.scatter(x, y, s=size, color='blue', picker=1, alpha=0.3)
self.axes.scatter(x_high, y_high, s=size_high, color='red', picker=1, alpha=0.3)
self.axes.figure.canvas.draw()
#self.lineEdit.setText(xdata)
#self.lineEdit_2.setText(ydata)
class Graph_populate(Graph_init):
def compute_initial_figure(self):
x = [10,20,30]
y = [100,100,150]
size = [1000,2000,3000]
self.axes.scatter(x,y,s=size,color='blue', picker=1, alpha=0.3)
class GUI(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(GUI, self).__init__(parent)
self.setupUi(self)
self.sc = Graph_populate(self.widget)
self.gridLayout.addWidget(self.sc, 0, 1, 2, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
prog = GUI()
prog.showMaximized()
sys.exit(app.exec_())
Thank you
You can not update the QLineEdits in Graph_init since they do not exist in that context, in those cases it is advisable to send the information where the context exists through a signal, this signal must be created:
posClicked = QtCore.pyqtSignal(tuple)
And when you want to send emit() is used
self.posClicked.emit((xdata, ydata))
Then it must be connected to a slot where it is used to fill the QLineEdits as shown below:
class Graph_init(FigureCanvas):
posClicked = QtCore.pyqtSignal(tuple)
def __init__(self, parent=None):
[...]
def onclick(self, event):
ind = event.ind[0]
data = event.artist.get_offsets()
xdata, ydata = data[ind,:]
print ((xdata, ydata))
[...]
self.axes.figure.canvas.draw()
self.posClicked.emit((xdata, ydata))
class GUI(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(GUI, self).__init__(parent)
self.setupUi(self)
self.sc = Graph_populate(self.widget)
self.gridLayout.addWidget(self.sc, 0, 1, 2, 1)
self.sc.posClicked.connect(self.onPosClicked)
def onPosClicked(self, values):
xdata, ydata = values
self.lineEdit.setText(str(xdata))
self.lineEdit_2.setText(str(ydata))