How Does a Pyqtgraph Export for Three Subplots Loo

2019-08-26 18:38发布

Using PyQtGraph, I would like to generate three sub plots in one chart and export this chart to a file.

As I will repeat this a lot of times, it is quite performance sensitive. Therefore I do not need to bring the chart to the screen.

The code below shows the three subplots on the screen, but the export to the file is presently not working. What do I have to pass as parameter to ImageExporter? (and if possible: what do I have to do to just do the export without bringing the chart to the screen anyhow?)

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')

results in:

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'

2条回答
Root(大扎)
2楼-- · 2019-08-26 19:16

The following small modification will work, observe the line where you define exporter:

exporter = pg.exporters.ImageExporter(view.scene())
查看更多
老娘就宠你
3楼-- · 2019-08-26 19:20

I cross referenced my question on the PyQtGraph google forum and got a suitable workaround.

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_())
查看更多
登录 后发表回答