使用PyQtGraph,我想在一个图表中生成三个子图并将该图表导出到一个文件中。
我将重复这一点很多次,它对性能非常敏感。因此,我不需要将图表带到屏幕上。
下面的代码显示了屏幕上的三个子图,但是导出到该文件目前无法正常工作。我有什么要作为参数传递给ImageExporter
? (如果可能的话:无论如何我只需做导出而不将图表带到屏幕上?)
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import pyqtgraph.exporters
import numpy as np
print("pyqtgraph.__version__:", pyqtgraph.__version__)
app = QtGui.QApplication([])
view = pg.GraphicsView()
l = pg.GraphicsLayout(border=(100, 100, 100))
view.setCentralItem(l)
view.show()
view.resize(800, 600)
# l.addLayout(colspan=1, border=(50, 0, 0))
p1 = l.addPlot()
l.nextRow()
p2 = l.addPlot()
l.nextRow()
p3 = l.addPlot()
p1.hideAxis("left")
p1.hideAxis("bottom")
p2.hideAxis("left")
p2.hideAxis("bottom")
p3.hideAxis("left")
p3.hideAxis("bottom")
p1.plot([1, 3, 2, 4, 3, 5])
p2.plot([1, 3, 2, 4, 3, 5])
p3.plot([1, 3, 2, 4, 3, 5])
# exporter = pg.exporters.ImageExporter(plt.plotItem)
exporter = pg.exporters.ImageExporter(view.currentItem)
# set export parameters if needed
exporter.parameters()['width'] = 100 # (note this also affects height parameter)
# save to file
exporter.export('fileName.png')
结果是:
pyqtgraph.__version__: 0.11.0.dev0+g9aaae8d
....
File "/home/user/PycharmProjects/0480_all_integrated/attic3.py", line 36, in <module>
exporter = pg.exporters.ImageExporter(view.currentItem)
File "/home/user/anaconda3/lib/python3.6/site-packages/pyqtgraph/exporters/ImageExporter.py", line 15, in __init__
tr = self.getTargetRect()
File "/home/user/anaconda3/lib/python3.6/site-packages/pyqtgraph/exporters/Exporter.py", line 96, in getTargetRect
return self.item.mapRectToDevice(self.item.boundingRect())
AttributeError: 'NoneType' object has no attribute 'mapRectToDevice'
我在PyQtGraph google forum上交叉引用了我的问题,得到了一个合适的解决方法。
import numpy as np
from PyQt5 import QtWidgets
import pyqtgraph as pg
import pyqtgraph.exporters
from pyqtgraph.Qt import QtCore, QtGui
from pyqtgraph import GraphicsLayoutWidget
class PyQtGraphExportTest(GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Test pyqtgraph export')
self.resize(640, 400)
# Set up a couple of stacked plots
self.plot1 = self.addPlot(row=0, col=0)
self.trace1 = self.plot1.plot(np.random.random(10))
self.plot1.enableAutoRange(pg.ViewBox.XYAxes)
self.plot2 = self.addPlot(row=1, col=0)
self.trace2 = self.plot2.plot(np.random.random(10))
self.plot2.enableAutoRange(pg.ViewBox.XYAxes)
self.plot3 = self.addPlot(row=2, col=0)
self.trace3 = self.plot3.plot(np.random.random(10))
self.plot3.enableAutoRange(pg.ViewBox.XYAxes)
self.plot1.hideAxis("left")
self.plot1.hideAxis("bottom")
self.plot2.hideAxis("left")
self.plot2.hideAxis("bottom")
self.plot3.hideAxis("left")
self.plot3.hideAxis("bottom")
# Store reference to exporter so it doesn't have to be initialised every
# time it's called. Note though the window needs to be displayed so
# mapping from plot to device coordinates is set up, that hasn't
# happened yet as this GraphicsLayoutWidget is also the Qt app window,
# so we'll create it later on.
self.exporter = None
# Configure a timer to act as trigger event for export. This could be a
# data acquisition event, button press etc.
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update_data)
self.timer.start(2000)
def update_data(self):
# Create the exporter if needed, now window is displayed on screen
if not self.exporter:
# Here we are passing the exporter the GraphicsLayout object that is
# the central item (ci) inside this GraphicsLayoutWidget. That in
# turn contains the two PlotItem objects.
self.exporter = pg.exporters.ImageExporter(self.ci)
self.exporter.parameters()['width'] = 640
# Get some new data, update plot and export
import time
my_time = time.time()
self.trace1.setData(np.random.random(10))
self.trace2.setData(np.random.random(10))
self.trace3.setData(np.random.random(10))
self.exporter.export('exported_image.png')
print("03:38 ----:", time.time() - my_time)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = PyQtGraphExportTest()
window.show()
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
sys.exit(app.exec_())