Raj Vora
Raj Vora

Reputation: 43

Interacting with MatplotlibWidget created with Qt Designer in python code

I am facing a problem interacting with the MatplotlibWidget that I creater via Qt Designer. I am unable to change the axes labels, scale, provide titles or anything. Am i doing anything wrong?

This is a sample UI code generated using Qt Designer:

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.mplwidget = MatplotlibWidget(self.centralwidget)

        self.mplwidget.setGeometry(QtCore.QRect(70, 50, 400, 300))
        self.mplwidget.setObjectName("mplwidget")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

from matplotlibwidget import MatplotlibWidget

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)

        self.setupUi(self)

This is the python code i wrote to interact with the UI python Code:

from PyQt4 import QtGui, QtCore
from TestUI2 import MainWindow

class Window(MainWindow):
    def __init__(self):
        MainWindow.__init__(self)

        x=[0,10,100]
        y=[3,4,5]

        self.mplwidget.axes.set_xscale('log') # Nothing Happens 
        self.mplwidget.axes.set_title('GRAPH') # Nothing Happens

        self.mplwidget.axes.plot(x,y) 


if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

Upvotes: 1

Views: 16085

Answers (4)

noname
noname

Reputation: 369

Based on embert's answer, regarding to the code in the original question, the following is tested and worked: Either

x=[0,10,100]
y=[3,4,5]

self.matplotlibwidget.axes.plot(x,y)

self.matplotlibwidget.axes.set_xscale('log')
self.matplotlibwidget.axes.set_title('GRAPH')

Or

x=[0,10,100]
y=[3,4,5]

self.matplotlibwidget.axes.set_xscale('log')
self.matplotlibwidget.axes.set_title('GRAPH')
self.matplotlibwidget.axes.hold(True)

self.matplotlibwidget.axes.plot(x,y)

Upvotes: 1

embert
embert

Reputation: 7592

You call self.mplwidget.axes.plot(x,y) after you set the properties.

hold (False): if False, figure will be cleared each time plot is called

Therefore change

self.mplwidget = MatplotlibWidget(self.centralwidget)

to

self.mplwidget = MatplotlibWidget(self.centralwidget, hold=True)

or set the properties after calling plot

Upvotes: 0

Elad Joseph
Elad Joseph

Reputation: 3058

You only need to add the line:

self.mplwidget.draw()

in your:

class Window(MainWindow):
    def __init__(self):

There is no need to manually define the class, you can just use the MatplotlibWidget you created with the Qt Designer.

Upvotes: 0

phil_thy
phil_thy

Reputation: 161

You need to define your own class for MatplotlibWidget first (in your main script, not the UI code) and then instantialize it in Window() definintion. To do that you also need to import FigureCanvas from _qt4agg matplotlib backend module and Figure class:

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure

Then in the Matplotlib class definition you create instances of the Figure subplots and Figure canvas, that can then be used to interact with your plot from the main window. So using your code this would look like this:

from PyQt4 import QtGui, QtCore
from TestUI2 import MainWindow

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure

class Window(MainWindow):
    def __init__(self):
        MainWindow.__init__(self)

        x=[0,10,100]
        y=[3,4,5]

        self.mplwidget = MatplotlibWidget(self.centralwidget)

        self.mplwidget.setGeometry(QtCore.QRect(70, 50, 600, 500))
        self.mplwidget.setObjectName("mplwidget")

        self.mplwidget.plotDataPoints(x,y)    

class MatplotlibWidget(Canvas):        
    def __init__(self, parent=None, title='Title', xlabel='x label', ylabel='y label', dpi=100, hold=False):
        super(MatplotlibWidget, self).__init__(Figure())

        self.setParent(parent)
        self.figure = Figure(dpi=dpi)
        self.canvas = Canvas(self.figure)
        self.theplot = self.figure.add_subplot(111)        

        self.theplot.set_title(title)
        self.theplot.set_xlabel(xlabel)
        self.theplot.set_ylabel(ylabel)

    def plotDataPoints(self, x, y):
        self.theplot.plot(x,y)
        self.draw()            

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

And the Ui script:

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)

        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")        

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)       

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)

        self.setupUi(self)

And then if you want to interact with the mpl plot, for example to change a title you do it from within the Window class, say:

self.mplwidget.theplot.set_title("New Title")

Hope that helps.

Upvotes: 1

Related Questions