tabbed window 用于 matplotlib 图形,可能吗?

Tabbed window for matplotlib figures, is it possible?

我有一个 python 项目可以输出几个 Matplotlib 图形;每个图包含几个图表。 project每运行推出15个数字(windows)的问题,我无法减少。

是否可以将所有这些数字 (windows) 连接到一个选项卡 window 以便每个选项卡代表一个数字?

非常感谢任何帮助。

提前致谢


解决方法

感谢@mobiusklein 下面的评论,他提出了一个解决方法,将图形导出为 myltipage pdf 文件,如图 here

关于上述多页 pdf 示例的重要说明.

我试过了,但在 matplotlib 中使用 LaTeX 时出现错误。因为修复这个错误超出了这个问题的范围,所以我建议如果有人遇到这种情况,设置 plt.rc('text', usetex=False) 而不是 usetex=True

我仍然希望如果有人有其他解决方案或变通方法 post 为了他人的利益。

您选择用于 matplotlib 的后端控制每个图形的显示方式。一些后端仅将图形渲染到文件,而其他后端如 tkqtgtk 后端以图形 windows 渲染图形。这些后端决定了那些 GUI windows 具有的功能。

现有后端不支持您正在寻找的标签式导航类型。其他人 使用 Qt4 实现了这个。

您也可以尝试使用 PDF 或 HTML 编写您自己的报告文件,这样您可以更轻松地使用更简单的库编写更复杂的图像排列。

功能相似的东西可以使用小部件来实现。例如,提供一行按钮,每个 "tab" 一个按钮,并重新绘制 window 的图形部分以响应每个按钮。

作为解决方法的按钮示例很有创意。正如另一个所述,您可以使用 PyQt 创建一个选项卡 window.

正是出于这个原因,我使用了PyQtGraph。 PyQtGraph 仅使用 PyQt 作为后端,因此 "natively" 支持选项卡式 windows 和 "docks"。 Docks 允许移动选项卡和拆分以及断开选项卡或拆分为新的浮动 window。

一般来说,PyQtGraph 的停靠栏提供了一种方法来组织你的 graphs/plots/images,这是我无法通过其他库获得的。

Bokeh 提供选项卡 windows through their Panels and Tabs widgets

我知道离开 matplotlib 并不总是可行的,但我觉得缺乏专门针对您的用例考虑和实施工具的库的代表性。

我为 matplotlib 编写了一个简单的包装器,它可以执行您描述的操作。你需要 pyqt5 才能正常工作。

这是代码,您构建一个 plotWindow 对象并为其提供图形句柄。它将为每个图形创建一个新选项卡。

import matplotlib
# prevent NoneType error for versions of matplotlib 3.1.0rc1+ by calling matplotlib.use()
# For more on why it's nececessary, see
# 
matplotlib.use('qt5agg')

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QTabWidget, QVBoxLayout
import matplotlib.pyplot as plt
import sys

class plotWindow():
    def __init__(self, parent=None):
        self.app = QApplication(sys.argv)
        self.MainWindow = QMainWindow()
        self.MainWindow.__init__()
        self.MainWindow.setWindowTitle("plot window")
        self.canvases = []
        self.figure_handles = []
        self.toolbar_handles = []
        self.tab_handles = []
        self.current_window = -1
        self.tabs = QTabWidget()
        self.MainWindow.setCentralWidget(self.tabs)
        self.MainWindow.resize(1280, 900)
        self.MainWindow.show()

    def addPlot(self, title, figure):
        new_tab = QWidget()
        layout = QVBoxLayout()
        new_tab.setLayout(layout)

        figure.subplots_adjust(left=0.05, right=0.99, bottom=0.05, top=0.91, wspace=0.2, hspace=0.2)
        new_canvas = FigureCanvas(figure)
        new_toolbar = NavigationToolbar(new_canvas, new_tab)

        layout.addWidget(new_canvas)
        layout.addWidget(new_toolbar)
        self.tabs.addTab(new_tab, title)

        self.toolbar_handles.append(new_toolbar)
        self.canvases.append(new_canvas)
        self.figure_handles.append(figure)
        self.tab_handles.append(new_tab)

    def show(self):
        self.app.exec_()

if __name__ == '__main__':
    import numpy as np

    pw = plotWindow()

    x = np.arange(0, 10, 0.001)

    f = plt.figure()
    ysin = np.sin(x)
    plt.plot(x, ysin, '--')
    pw.addPlot("sin", f)

    f = plt.figure()
    ycos = np.cos(x)
    plt.plot(x, ycos, '--')
    pw.addPlot("cos", f)
    pw.show()

这也发布在:https://github.com/superjax/plotWindow

希望这能成为您申请的良好起点。

我分享了我的代码,它允许使用拖放(qt 停靠系统)进行停靠和制表符。它充当 matplotlib 后端,因此很容易集成。

https://github.com/peper0/mpldock

我最近发布了一个 python 包,其中包含一个名为 DockablePlotWindow 的 class,它提供了一个类似于 superjax 的答案的解决方案,但它提供了更多的灵活性来组织绘图的方式最初显示。

我有兴趣继续改进这个包,所以请随时在 github 上打开拉取请求或问题。您可以在这里找到相关信息:https://github.com/nanthony21/mpl_qt_viz 和这里: https://nanthony21.github.io/mpl_qt_viz/