简体   繁体   English

Matplotlib NavigationToolbar 重叠图(在 PyQt4 嵌入中)

[英]Matplotlib NavigationToolbar overlapping plot (within PyQt4 embedding)

I have a PyQt window that needs to have both a plot and navigation toolbar.我有一个 PyQt 窗口,它需要一个绘图和导航工具栏。 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 ?当您使用self.canvas = FigureCanvas (fig)您正在创建另一个FigureCanvas为什么要创建另一个? , 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.子部件的位置是相对于父部件的,在这种情况下,它是 self.toolbar 是 self.canvas 的子部件,因此 self.toolbar 将在 self.canvas 内。

In order to handle the position and size of the widgets, Qt offers the layouts, and in this case it is necessary.为了处理小部件的位置和大小,Qt 提供了布局,在这种情况下是必要的。 On the other hand, there is no need for the toolbar to be inside the PlotCanvas class.另一方面,工具栏不需要位于 PlotCanvas 类中。 And finally when using QMainWindow you should not place the widgets directly since it has a custom layout so you must create a centralwidget.最后,在使用 QMainWindow 时,您不应直接放置小部件,因为它具有自定义布局,因此您必须创建一个中央小部件。

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_())

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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