简体   繁体   English

如何全屏打开matplotlib图形?

[英]How to open matplotlib graph fullscreen?

I am working on pyqt5 app and there is widget containing graph made with matplotlib.我正在开发 pyqt5 应用程序,并且有包含用 matplotlib 制作的图形的小部件。 I want to add a function which allows user to click the graph and it will be open full screen.我想添加一个允许用户单击图形的功能,它将全屏打开。 How can I do that?我怎样才能做到这一点?
The graph in the widget is built like that:小部件中的图形是这样构建的:

class CanvasUp(FigureCanvas):
    def __init__(self, parent=None, width=5, height=5, dpi=50):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        self.plot()

def plot(self):
            # obtaining data
            ...
            ax = self.figure.add_subplot(111)

            self.figure.text(0.5, 0.5, "TEST", transform=ax.transAxes,
                             fontsize=40, color='gray', alpha=0.5,
                             ha='center', va='center')
            ax.fill_between(x1, y1=y1, label='psavert', alpha=0.5, color='tab:green', linewidth=2)

            dt = ax.plot(x1, y1)
            ax.set_title(lab, loc='left')
            ax.grid()
            self.draw_idle()           

If I simplify my programe it looks like that:如果我简化我的程序,它看起来像这样:


from PyQt5.QtWidgets import QDialog, QVBoxLayout
from PyQt5.QtWidgets import QApplication
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys

class CanvasUp(FigureCanvas):
    def __init__(self, parent=None, width=5, height=5, dpi=50):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        self.plot()

    def plot(self):
        try:
            x1 = [1, 2, 3]
            y1 = [3, 2, 1]
            ax = self.figure.add_subplot(111)
            ax.set_ylim([0, max(y1)*1.15])

            self.figure.text(0.5, 0.5, "test", transform=ax.transAxes,
                             fontsize=40, color='gray', alpha=0.5,
                             ha='center', va='center')
            ax.fill_between(x1, y1=y1, label='psavert', alpha=0.5, color='tab:green', linewidth=2)
            dt = ax.plot(x1, y1)
            ax.grid()
            self.draw_idle()
        except:
            print("Bad graphs")


class MainWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.setGeometry(50, 50, 700, 700)
        layout = QVBoxLayout(self)
        plot = CanvasUp()
        layout.addWidget(plot)
        self.show()

if __name__ == '__main__':
        App = QApplication(sys.argv)
        window = MainWindow()
        sys.exit(App.exec())

If you want to show a child widget in full screen, you'll need to set its parent to None .如果要全屏显示小部件,则需要将其父小部件设置为None

Note that if you want to restore the previous state, you also need to keep track of the previous position within the layout.请注意,如果要恢复以前的状态,还需要跟踪布局内的先前位置。 In your example is not really a requirement, but if there are more widgets you have to consider that.在您的示例中并不是真正的要求,但如果有更多小部件,您必须考虑这一点。

class CanvasUp(FigureCanvas):
    toggle = pyqtSignal()
    def __init__(self, parent=None, width=5, height=5, dpi=50):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        self.plot()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # emit a signal to notify the parent that we want to toggle the mode
            self.toggle.emit()

    # ...

class MainWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.setGeometry(50, 50, 700, 700)
        self.setWindowTitle('fig test')
        layout = QVBoxLayout(self)
        self.plot = CanvasUp()
        layout.addWidget(self.plot)
        self.show()
        self.plot.toggle.connect(self.toggleFigure)

    def toggleFigure(self):
        if self.plot.parent():
            # store the current index in the layout
            self.layoutIndex = self.layout().indexOf(self.plot)
            self.plot.setParent(None)
            # manually reparenting a widget requires to explicitly show it,
            # usually by calling show() or setVisible(True), but this is
            # automatically done when calling showFullScreen()
            self.plot.showFullScreen()
        else:
            self.layout().insertWidget(self.layoutIndex, self.plot)

If you're using a grid layout, though, the index is not enough, since insertWidget only exists for QBoxLayouts, so grid coordinates must be extracted before reparenting the widget.但是,如果您使用的是网格布局,则索引是不够的,因为insertWidget仅存在于 QBoxLayouts,因此必须在重新设置窗口小部件的父级之前提取网格坐标。
Consider that, while you could store the coordinates in a variable while adding the widget to the layout, it's always better to get them only when required.考虑到这一点,虽然您可以在将小部件添加到布局时将坐标存储在变量中,但最好仅在需要时获取它们。

class MainWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.setGeometry(50, 50, 700, 700)
        self.setWindowTitle('fig test')
        layout = QGridLayout(self)
        layout.addWidget(QPushButton(), 0, 0)
        layout.addWidget(QPushButton(), 0, 1)
        self.plot = CanvasUp()
        layout.addWidget(self.plot, 1, 0, 1, 2)
        self.show()
        self.plot.toggle.connect(self.toggleFigure)

    def toggleFigure(self):
        if self.plot.parent():
            layoutIndex = self.layout().indexOf(self.plot)
            # store the position in grid coordinates:
            # row, column, horizontal span and vertical span
            self.layoutPosition = self.layout().getItemPosition(layoutIndex)
            self.plot.setParent(None)
            self.plot.showFullScreen()
        else:
            self.layout().addWidget(self.plot, *self.layoutPosition)

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

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