I found a website scikit-rf
http://scikit-rf.readthedocs.io/en/latest/tutorials/plotting.html
It can create smith plot by following code
ntwk = rf.Network("my data path")
ntwk.plot_s_smith()
Then I want to embed it to my python gui.
import sys
from PyQt4 import QtGui,QtCore
import matplotlib
import matplotlib.figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
import skrf as rf
import numpy as np
class PrettyWidget(QtGui.QMainWindow):
def __init__(self):
super(PrettyWidget, self).__init__()
self.setGeometry(100,100,1200,700)
self.center()
self.setWindowTitle('NRW')
self.initUI()
def initUI(self):
grid = QtGui.QGridLayout()
self.setLayout(grid)
self.figure = matplotlib.figure.Figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
grid.addWidget(self.canvas, 3,0,2,12)
def plot1(self):
self.figure.clf()
self.figure.tight_layout()
self.canvas.draw()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
GUI = PrettyWidget()
GUI.show()
app.exec_()
But I have no idea how to put or modify code below
ntwk = rf.Network("my data path")
ntwk.plot_s_smith()
Would anyone tell me if you have any iedas? Thanks!
Network.plot_s_smith has an ax keyword to plot on existing Axes object. So you can modify your plot function like this:
def plot1(self):
self.figure.clf()
ntwk = rf.Network("my data path")
ntwk.plot_s_smith(ax=self.figure.gca())
self.figure.tight_layout()
self.canvas.draw()
Related
I would like to plot a chart inside a pyQT GUI. I have already read a lot of tutorials, but those plot the chart in a separeted window. I need it to be ploted in the same window as the other buttons and fields.
In my main.py file, I import the Ui_MainWindow class generated with the QT designer. But I didn't figured out how to plot it inside the MainWindow
Python GUI
Matplotlib canvas class to create figure
class MplCanvas(FigureCanvas):
def __init__(self):
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
FigureCanvas.__init__(self, self.fig)
FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def atualizar(self):
global tempoInicio
tempoInicio = self.campoTempoInicio.dateTime()
print(tempoInicio.toPyDateTime())
x=range(0, 10)
y=range(0, 20, 2)
self.FigureCanvas.canvas.ax.plot(x, y)
self.FigureCanvas.canvas.draw()
I've tried as this, but it didn't worked as well (followed a tutorial)
Thank you in advance for reading this.
After looking into non-relatated tutorial, I've foud this one: https://www.pythonguis.com/tutorials/embed-pyqtgraph-custom-widgets-qt-app/
that teaches how to do what I need.
Don't now why it didn't appear before. But worked!
Here's a complete example that should help:
import sys
from PyQt5 import QtWidgets, QtCore
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
class PlotViewer(QtWidgets.QWidget):
doubleClickAction = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(PlotViewer, self).__init__(parent)
self.figure = plt.figure(figsize=(5, 5))
self.figureCanvas = FigureCanvas(self.figure)
self.navigationToolbar = NavigationToolbar(self.figureCanvas, self)
# create main layout
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.navigationToolbar)
layout.addWidget(self.figureCanvas)
self.setLayout(layout)
# create an axis
x = range(0, 10)
y = range(0, 20, 2)
ax = self.figure.add_subplot(111)
ax.plot(x, y)
# show canvas
self.figureCanvas.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
widget = PlotViewer()
widget.show()
app.exec_()
I'm trying to make an app where the matplotlib's tab widget is embedded inside another widget
import os
import matplotlib
import matplotlib.pyplot as pp
import numpy as np
from PySide2 import QtGui
from PySide2.QtCore import QTimer
from PySide2.QtWidgets import *
from layout import Ui_Form
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import sys
graphed = False
res = 180
class VentanaPrincipal(QDialog):
def __init__(self, parent=None):
super(VentanaPrincipal, self).__init__(parent)
self.ventana = Ui_Form()
self.ventana.setupUi(self)
self.timer = QTimer()
self.timer.timeout.connect(self.mainloop)
self.timer.start(20)
self.ancho = self.size().height()
self.alto = self.size().height()
self.ventana.pshBtnCalcularOrbita.clicked.connect(self.truer)
self.ventana.pshBtnCalcularOrbita.clicked.connect(self.graph)
self.oldsize = self.size()
self.figure = Figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
self.button = QPushButton('Plot')
self.button.clicked.connect(self.plot)
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
def truer(self):
global graphed
graphed = True
def graph(self):
self.ventana.graph()
def resizeEvent(self,event):
self.oldsize = event.size()
def mainloop(self):
self.ancho = self.size().width()
self.alto = self.size().height()
if self.size() != self.oldsize:
if graphed:
self.graph()
if __name__ == '__main__':
app = QApplication(sys.argv)
aplicacion = VentanaPrincipal()
aplicacion.show()
sys.exit(app.exec_())
Gives me:
TypeError: arguments did not match any overloaded call:
QToolBar(str, parent: QWidget = None): argument 1 has unexpected type 'VentanaPrincipal'
QToolBar(parent: QWidget = None): argument 1 has unexpected type 'VentanaPrincipal'
The Ui_Form is a .py file compiled from the original .ui file from QtDesigner
I've seen an identical example onto another question, the example i grabbed onto was:
import sys
from PySide2.QtWidgets import QDialog,QApplication,QPushButton, QVBoxLayout
from PySide2 import QtGui
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import random
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = Figure()
print(self)
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init__
self.canvas = FigureCanvas(self.figure)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
print(type(self))
# Just some button connected to `plot` method
self.button = QPushButton('Plot')
self.button.clicked.connect(self.plot)
# set the layout
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
def plot(self):
''' plot some random stuff '''
# random data
data = [random.random() for i in range(10)]
# create an axis
ax = self.figure.add_subplot(111)
# discards the old graph
ax.clear()
# plot data
ax.plot(data, '*-')
# refresh canvas
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
There are some prints i put inside the code to check which kind of object is accepted by the QToolbar init line inside Matplotlib's backend
I'm trying to update a matplotlib plot embeded in a pyqt5 window.
I used self.canvas.draw() (in the update function)to update the plot in a function to redraw the figure. This is working fine on Window but it doesn't work on MacOS.
I don't understand why and if it exists a solution to that?
In fact I need to click on the axes in order to the figure to be updated... weird.
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
class StimEdit(QMainWindow):
def __init__(self, parent=None):
super(StimEdit, self).__init__()
self.parent = parent
self.centralWidget = QWidget()
self.color = self.centralWidget.palette().color(QPalette.Background)
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QHBoxLayout()
self.set_Stims()
self.mainHBOX_param_scene.addWidget(self.Stimulation)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
def set_Stims(self):
self.Stimulation = QGroupBox('Stim N°1')
self.layout_Stimulation_courbe = QVBoxLayout()
self.layout_Stimulation = QHBoxLayout()
self.button = QPushButton('push')
self.masceneparam = paramViewer(self)
self.button.clicked.connect(self.button_fun)
self.layout_Stimulation_courbe.addWidget(self.masceneparam)
self.layout_Stimulation_courbe.addWidget(self.button)
self.Stimulation.setLayout(self.layout_Stimulation_courbe)
def button_fun(self):
self.masceneparam.update()
self.parent.processEvents()
class paramViewer(QGraphicsView):
def __init__(self, parent=None):
super(paramViewer, self).__init__(parent)
self.parent=parent
self.scene = QGraphicsScene(self)
self.setScene(self.scene)
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
self.axes_stim=self.figure.add_subplot(111)
self.canvas.setGeometry(0, 0, 1600, 500 )
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.show()
def update(self):
self.axes_stim.clear()
t = np.arange(1000)/100
self.axes_stim.plot(t,np.sin(2*np.pi*np.random.uniform()*100*t))
self.canvas.draw()
def main():
app = QApplication(sys.argv)
ex = StimEdit(app)
ex.setWindowTitle('St ')
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
edit
I try to use the example of matplotlib for embeded Figures in Qt (https://matplotlib.org/gallery/user_interfaces/embedding_in_qt_sgskip.html) from #ImportanceOfBeingErnest
# from PyQt5.QtGui import *
# from PyQt5.QtWidgets import *
import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class StimEdit(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(StimEdit, self).__init__()
self.parent = parent
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtWidgets.QHBoxLayout()
self.set_Stims()
self.mainHBOX_param_scene.addWidget(self.Stimulation)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
def set_Stims(self):
self.Stimulation = QtWidgets.QGroupBox('Stim N°1')
self.layout_Stimulation_courbe = QtWidgets.QVBoxLayout()
self.layout_Stimulation = QtWidgets.QHBoxLayout()
self.button = QtWidgets.QPushButton('push')
self.masceneparam = paramViewer(self)
self.button.clicked.connect(self.button_fun)
self.layout_Stimulation_courbe.addWidget(self.masceneparam)
self.layout_Stimulation_courbe.addWidget(self.button)
self.Stimulation.setLayout(self.layout_Stimulation_courbe)
def button_fun(self):
self.masceneparam.update()
self.parent.processEvents()
class paramViewer(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(paramViewer, self).__init__(parent)
self.parent=parent
self.scene = QtWidgets.QGraphicsScene(self)
self.setScene(self.scene)
self.figure = Figure()
self.canvas = FigureCanvas(self.figure )
self.toolbar = NavigationToolbar(self.canvas, self)
self.axes_stim=self.figure.add_subplot(111)
self.canvas.setGeometry(0, 0, 1600, 500 )
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.show()
def update(self):
self.axes_stim.clear()
t = np.arange(1000)/100
self.axes_stim.plot(t,np.sin(2*np.pi*np.random.uniform()*100*t))
self.canvas.figure.canvas.draw()
# self.canvas.draw()
def main():
app = QtWidgets.QApplication(sys.argv)
ex = StimEdit(app)
ex.setWindowTitle('St ')
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
But the issue still remains.
Answer from #ImportanceOfBeingErnest
Since I don't have any experience with Macs I might not be able to help further here, but a last suggestion might be to replace .draw() by .draw_idle(). (Both should work in this case, but you never know...)
I want to plot charts after clicking on rows. The signal is transmitted, but the chart isn't plotted. But if I call a plotting function (self.hist()) from MyPlot.__init__, the chart is plotted.
I used this as an example, but it didn't help. How to embed matplotib in pyqt - for Dummies
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtCore import QCoreApplication, Qt
from PyQt4.QtGui import QListWidget, QListWidgetItem, QApplication, QMessageBox
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import sqlite3
matplotlib.style.use('ggplot')
import pandas as pd
import numpy as np
# my plotting functions are in this class
class Myplot(FigureCanvas):
def __init__(self, parent=None):
self.fig = Figure()
FigureCanvas.__init__(self, self.fig)
#self.hist()
#this and next functions should plot
def compute_initial_figure(self):
self.axes = self.fig.add_subplot(1,1,1)
self.axes.hold(False)
self.axes.plot(np.random.rand(400))
self.draw()
def hist(self):
tm = pd.Series(np.random.randn(500), index=pd.date_range('1/1/2005', periods=500))
self.axes = self.fig.add_subplot(1,1,1)
self.axes.hold(False)
tm = tm.cumsum()
self.axes.plot(tm)
self.draw()
#list with rows. I want to draw charts after clicking on them
class Panel (QtGui.QListWidget):
def __init__(self, parent=None):
QtGui.QListWidget.__init__(self)
self.row1 = "COMMISSIONS & FEES"
self.addItem(self.row1)
row2 = "NET LIQUIDATING VALUE"
self.addItem(row2)
self.setFixedWidth(200)
self.itemClicked.connect(self.Clicked)
#this function sends signal to the plotting functions
def Clicked(self):
mplot=Myplot()
index=self.currentRow()
if index == 0:
print '0000'
mplot.compute_initial_figure()
if index == 1:
print '1111'
mplot.hist()
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
#menu
exitAction = QtGui.QAction(QtGui.QIcon('Stuff/exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(QtGui.qApp.quit)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
self.statusBar().showMessage('Ready')
self.showMaximized()
self.setMinimumSize(600, 400)
self.setWindowTitle('ESPA')
self.setWindowIcon(QtGui.QIcon('Stuff/icon.png.'))
#setup window widgets
self.main_widget= QtGui.QWidget(self)
#lines up widgets horizontally
layout = QtGui.QHBoxLayout(self.main_widget)
mp=Myplot(self.main_widget)
p=Panel(self.main_widget)
layout.addWidget(p)
layout.addWidget(mp)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
I am currently trying to embed a graph I want to plot in a pyqt4 user interface I designed. As I am almost completely new to programming - I do not get how people did the embedding in the examples I found - this one (at the bottom) and that one.
It would be awesome if anybody could post a step-by-step explanation or at least a very small, very simple code only creating e.g. a graph and a button in one pyqt4 GUI.
It is not that complicated actually. Relevant Qt widgets are in matplotlib.backends.backend_qt4agg. FigureCanvasQTAgg and NavigationToolbar2QT are usually what you need. These are regular Qt widgets. You treat them as any other widget. Below is a very simple example with a Figure, Navigation and a single button that draws some random data. I've added comments to explain things.
import sys
from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import random
class Window(QtGui.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = Figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init__
self.canvas = FigureCanvas(self.figure)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
# Just some button connected to `plot` method
self.button = QtGui.QPushButton('Plot')
self.button.clicked.connect(self.plot)
# set the layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
def plot(self):
''' plot some random stuff '''
# random data
data = [random.random() for i in range(10)]
# create an axis
ax = self.figure.add_subplot(111)
# discards the old graph
ax.clear()
# plot data
ax.plot(data, '*-')
# refresh canvas
self.canvas.draw()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
Edit:
Updated to reflect comments and API changes.
NavigationToolbar2QTAgg changed with NavigationToolbar2QT
Directly import Figure instead of pyplot
Replace deprecated ax.hold(False) with ax.clear()
Below is an adaptation of previous code for using under PyQt5 and Matplotlib 2.0.
There are a number of small changes: structure of PyQt submodules, other submodule from matplotlib, deprecated method has been replaced...
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
import random
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init__
self.canvas = FigureCanvas(self.figure)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
# Just some button connected to `plot` method
self.button = QPushButton('Plot')
self.button.clicked.connect(self.plot)
# set the layout
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
def plot(self):
''' plot some random stuff '''
# random data
data = [random.random() for i in range(10)]
# instead of ax.hold(False)
self.figure.clear()
# create an axis
ax = self.figure.add_subplot(111)
# discards the old graph
# ax.hold(False) # deprecated, see above
# plot data
ax.plot(data, '*-')
# refresh canvas
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
For those looking for a dynamic solution to embed Matplotlib in PyQt5 (even plot data using drag and drop). In PyQt5 you need to use super on the main window class to accept the drops. The dropevent function can be used to get the filename and rest is simple:
def dropEvent(self,e):
"""
This function will enable the drop file directly on to the
main window. The file location will be stored in the self.filename
"""
if e.mimeData().hasUrls:
e.setDropAction(QtCore.Qt.CopyAction)
e.accept()
for url in e.mimeData().urls():
if op_sys == 'Darwin':
fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
else:
fname = str(url.toLocalFile())
self.filename = fname
print("GOT ADDRESS:",self.filename)
self.readData()
else:
e.ignore() # just like above functions
For starters the reference complete code gives this output: