Search code examples
pythonmatplotlibiopyqt5bytesio

How to use BytesIO with matplotlib and pyqt5?


I made a graph in matplotlib, and wanted to make it in to an image and use it in my pyqt5 application. Someone suggested I use BytesIO for this. This is my code so far:

Drawing my graph:

...
plt.axis('equal')
buff = io.BytesIO()
plt.savefig(buff, format="png")
print(buff)
return buff

This is then called in another script:

def minionRatioGraphSetup(self, recentMinionRatioAvg):
    image = minionRatioGraph(recentMinionRatioAvg)
    label = QtWidgets.QLabel()
    pixmap = QtGui.QPixmap(image)
    label.setPixmap(pixmap)
    label.setGeometry(QtCore.QRect(0,0,200,200))

It stops working at pixmap = QtGui.QPixmap(image) and I'm unsure why. Also: How could I place this in my MainWindow? because I doubt the code there will work lol


Solution

  • I'm sure there is a solution using a buffer. However, it seems rather complicated to get the byte format correct. So an alternative is to save the image to disk, and then load it from there.

    import sys
    from PyQt4 import QtGui
    import matplotlib.pyplot as plt
    import numpy as np
    
    def minionRatioGraph():
        plt.plot([1,3,2])
        plt.savefig(__file__+".png", format="png")
    
    
    class App(QtGui.QWidget):
    
        def __init__(self):
            super(App, self).__init__()
            self.setGeometry(300, 300, 250, 150)
            self.setLayout(QtGui.QVBoxLayout())
            label = QtGui.QLabel()
            label2 = QtGui.QLabel("Some other text label") 
    
            minionRatioGraph()
    
            qimg = QtGui.QImage(__file__+".png")  
            pixmap = QtGui.QPixmap(qimg)
    
            label.setPixmap(pixmap)
            self.layout().addWidget(label)
            self.layout().addWidget(label2)
            self.show()
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication([])
        ex = App()
        sys.exit(app.exec_())