简体   繁体   中英

Matplotlib NavigationToolbar overlapping plot (within PyQt4 embedding)

I have a PyQt window that needs to have both a plot and navigation toolbar. However, I can't seem to get the two objects to mesh together; ie, with the toolbar on top of the plot, expanding the same horizontal length, scaling appropriately, and not overlapping. Below is my minimum, working example. thank you so much for taking a look!

import sys, os

from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random

class App(QtGui.QMainWindow):

    def __init__(self):
        super(App, self).__init__()
        self.left = 10
        self.top = 10
        self.title = 'Minimum, working example'
        self.width = 640
        self.height = 400
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        m = PlotCanvas(self, width=5, height=4)
        m.move(0,0)
        self.show()


class PlotCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.updateGeometry(self)

        ##########################
        #trouble seems to be here:
        fig.set_tight_layout(True)
        self.canvas = FigureCanvas(fig)
        self.toolbar = NavigationToolbar(self.canvas, self)
        ##########################

        self.plot()


    def plot(self):
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title("Is this getting overlapped by the toolbar?")
        self.draw()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

When you use self.canvas = FigureCanvas (fig) you are creating another FigureCanvas , why create another ? , it is not necessary.

Why are they overlapping?

The position of a child widget is relative to the parent, in this case it is self.toolbar is the children of self.canvas so the self.toolbar will be within the self.canvas.

In order to handle the position and size of the widgets, Qt offers the layouts, and in this case it is necessary. On the other hand, there is no need for the toolbar to be inside the PlotCanvas class. And finally when using QMainWindow you should not place the widgets directly since it has a custom layout so you must create a centralwidget.

import sys, os

from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random

class App(QtGui.QMainWindow):
    def __init__(self):
        super(App, self).__init__()
        self.left = 10
        self.top = 10
        self.title = 'Minimum, working example'
        self.width = 640
        self.height = 400
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        centralwidget = QtGui.QWidget()
        self.setCentralWidget(centralwidget)
        m = PlotCanvas(self, width=5, height=4)
        toolbar =  NavigationToolbar(m, self)
        vbl = QtGui.QVBoxLayout(centralwidget)
        vbl.addWidget(toolbar)
        vbl.addWidget(m)
        self.show()


class PlotCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        self.updateGeometry()
        fig.set_tight_layout(True)
        self.plot()

    def plot(self):
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title("Is this getting overlapped by the toolbar?")
        self.draw()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM