我正在用 Python 3.5 和 PyQT 5 编写一个应用程序。在这个应用程序中,我有一个嵌入式 matplotlib 画布和一个嵌入式 matplotlib 导航工具栏。该应用程序测量一些数据,然后绘制它们。用户有时想要导出绘图并将其保存到某个位置的“.png”文件中,然后测量新的东西。
为此,我一直使用导航工具栏上的“软盘”/“保存”图标,效果很好。但是,当我单击它时,它会在程序的根文件夹(或上次打开的文件夹)中打开一个对话框,并将保存的图像的名称预先填充为“image.png”。
我想将此预填充的默认名称更改为我的程序自定义的名称,例如“measurement_7453243.png”或“2017_01_16_measurement.png”。有没有办法让我做到这一点?
想法#1:我发现的是使用 matplotlib.rcParams['savefig.directory'] 的选项,并使用它来设置应打开对话框的目录 - 但不是文件名。我似乎找不到可以更改默认文件名的“savefig.XXXX”属性。
想法#2:我可以在导航工具栏之外的应用程序中创建一个自定义按钮,该按钮将使用 Qt 运行自定义文件保存对话框,然后使用 savefig() 保存图形。但是,如果已经有一个很好的按钮几乎可以满足我的需求,为什么还要这样做呢?
任何提示和想法,以及具有适当来源的“这是不可能完成的”,我们将不胜感激。
不确定你是否总是可以这样做,但在我的例子中,图形实例有一个canvas属性,我可以按照Goyo的建议进行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()
FigureCanvasBase.get_default_filename
提供。您可以在创建画布后对其进行猴子修补:
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_()
Matplotlib-3 文档中提到了这一点,并且对我有用(Python 3.8.5/TkAgg):
fig, axs = plt.subplots(...)
fig.canvas.manager.set_window_title(my_file_name)
我还设置了:
matplotlib.rcParams['savefig.format'] = 'svg'