Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在PyQt5应用程序中更改Matplotlib NavigationToolbar中的默认文件名?_Python_Qt_Python 3.x_Matplotlib_Pyqt5 - Fatal编程技术网

Python 如何在PyQt5应用程序中更改Matplotlib NavigationToolbar中的默认文件名?

Python 如何在PyQt5应用程序中更改Matplotlib NavigationToolbar中的默认文件名?,python,qt,python-3.x,matplotlib,pyqt5,Python,Qt,Python 3.x,Matplotlib,Pyqt5,我正在用Python3.5和Pyqt5编写一个应用程序。在这个应用程序中,我有一个嵌入式matplotlib画布和一个嵌入式matplotlib导航工具栏。应用程序测量一些数据,然后绘制它们。用户在某个时候想要导出绘图并将其保存到某个“.png”文件中,然后测量新的内容 为此,我一直在使用NavigationToolbar上的“软盘”/“保存”图标,效果很好。但是,当我单击它时,它会在程序的根文件夹(或上次打开的文件夹)打开一个对话框,并将保存的图像的名称预先填充为“image.png” 我想将

我正在用Python3.5和Pyqt5编写一个应用程序。在这个应用程序中,我有一个嵌入式matplotlib画布和一个嵌入式matplotlib导航工具栏。应用程序测量一些数据,然后绘制它们。用户在某个时候想要导出绘图并将其保存到某个“.png”文件中,然后测量新的内容

为此,我一直在使用NavigationToolbar上的“软盘”/“保存”图标,效果很好。但是,当我单击它时,它会在程序的根文件夹(或上次打开的文件夹)打开一个对话框,并将保存的图像的名称预先填充为“image.png”

我想将这个预先填充的默认名称更改为我的程序的自定义名称,例如“measurement_7453243.png”或“2017_01_16_measurement.png”。有没有办法让我这样做

想法#1:我发现的是使用matplotlib.rcParams['savefig.directory']的选项,并使用该选项设置对话框应该打开的目录,而不是文件名。我似乎找不到可以更改默认文件名的“savefig.XXXX”属性

想法#2:我可以在NavigationToolbar之外的应用程序中创建一个自定义按钮,该按钮将使用Qt运行一个自定义文件保存对话框,然后使用savefig()保存图形。但是,如果已经有一个很好的按钮几乎可以实现我想要的功能,为什么要这样做呢


任何提示和想法,以及使用适当来源的“这无法完成”都将不胜感激。

默认文件名由该方法提供。创建画布后,您可以直接对其进行修补:

canvas = FigureCanvas(fig)
canvas.get_default_filename = lambda: 'new_default_name.png'
我想正确的方法是子类化
FigureCanvas
,重写该方法,并可能提供一个API来设置默认文件名

下面是一个使用猴子补丁的Qt5Agg示例,改编自matplotlib文档:

from PyQt5.QtWidgets import (
    QMainWindow, QApplication, QWidget, QVBoxLayout)

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (
    FigureCanvasQTAgg as FigureCanvas,
    NavigationToolbar2QT as NavigationToolbar)


class AppForm(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        main_frame = QWidget()

        fig = Figure((5.0, 4.0), dpi=100)
        ax = fig.add_subplot(111)
        ax.plot([1, 2, 4, 8])

        canvas = FigureCanvas(fig)
        canvas.get_default_filename = lambda: 'new_default_name.png'
        mpl_toolbar = NavigationToolbar(canvas, main_frame)

        vbox = QVBoxLayout()
        vbox.addWidget(canvas)  # the matplotlib canvas
        vbox.addWidget(mpl_toolbar)
        main_frame.setLayout(vbox)
        self.setCentralWidget(main_frame)


app = QApplication(['Test'])
form = AppForm()
form.show()
app.exec_()

不确定您是否可以始终这样做,但在我的例子中,figure实例有一个canvas属性,我可以按照建议使用monkeypatch

import matplotlib.pyplot as plt
f = plt.figure()
c = f.canvas
my_adventurous_filename = 'figure-III' # irony
c.get_default_filename = lambda : '%s.%s' % (my_adventurous_filename,
                                             c.get_default_filetype())
plt.show()

Matplotlib-3文档中提到了这一点,并且对我有用(Python 3.8.5/TkAgg):

我还设定:

matplotlib.rcParams['savefig.format'] = 'svg'

我曾经遇到过同样的问题,在没有找到快速解决方案后,我完全实现了你所谓的想法2。尽管如此,我相信有一个解决方案。谢谢你的回答,我将尝试一下,看看它如何与我的程序一起工作:)。我在我的应用程序中尝试了这个,但我无法让它工作。调用成功(即不会引发异常),但在保存数字时也不会更改任何内容。你有没有可能提供一个有效的例子?@呃,我很困惑。昨天在一个平行的宇宙中
fig.set_label
做了你想要的独立交互图形。现在它是
fig.canvas.set_window\u title
,但不幸的是,它在嵌入的图形中没有任何作用,所以我不得不找到另一种方法。我准备了一份以防万一的报告,以防我再次被转移到另一个宇宙。我不完全理解这个评论,但我希望平行宇宙的问题不是我的错:)。几小时前,我在一个类似的问题上偶然发现了猴子修补方法,我迫不及待地想尝试一下。它甚至比在任何宇宙中使用set_label()更合适。偷取原始get_default_filename()的代码并将“image”更改为“measurement”…,这样我仍然可以保留在冲突等情况下重命名的好处。感谢您的帮助和示例!!在我的应用程序上试用后,我会向你汇报。它就像一个符咒,如果我不想它太花哨,它基本上就是一行。谢谢你,先生!:)
matplotlib.rcParams['savefig.format'] = 'svg'