Search code examples
pythonpyqtpyqt5pyqtgraph

How set stretch factor for chart in Pyqtgraph?


Now the application displays two graphs with the same height:

enter image description here

CODE:

import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QListWidget, QVBoxLayout, QMainWindow
import pyqtgraph as pg


class Draw_interface(QMainWindow):
    def __init__(self):
        global time_update

        super(Draw_interface, self).__init__()
        uic.loadUi('charts.ui', self)

        # Add two charts
        self.my_draw = pg.GraphicsLayoutWidget(show=True)
        self.p1 = self.my_draw.addPlot(row=0, col=0, stretch=3)
        self.p2 = self.my_draw.addPlot(row=1, col=0, stretch=1)

        # Set widget for chart
        my_layout = QVBoxLayout()
        my_layout.addWidget(self.my_draw)
        self.frame_for_charts.setLayout(my_layout)

        # Draw charts
        y = [2.2, 3.0, 1.3, 2.5, 1.9, 2.2, 5.5, 6.6]
        y2 = [2.3, 3.3, 2.8, 2.2, 3.3, 3.1, 2.8, 4.4]
        curve1 = self.p1.plot(y)
        curve2 = self.p2.plot(y2)

        self.show()

my_app = QtWidgets.QApplication([])
my_main_window = Draw_interface()
sys.exit(my_app.exec_())

stretch=3 and stratch=1 - do not lead to the desired effect.

How to set the stretch factor correctly so that the upper graph is 75% of the height, the lower graph is 25% of the height? And it was like this:

enter image description here

Maybe:

self.my_draw.itemAt(0, 0).setGeometry(x1,y1,x2,y2)
self.my_draw.itemAt(0, 0).updateGeometry()

But this is clearly not the best option.


Solution

  • There is no parameter like "stretch" or "stratch" for addPlot method.

    If you want to use GraphicsLayoutWidget, you can add empty labels to take up spaces of the next column to serve as a reference of the grid.(kind of hacky...)

    Or you can put 2 plotwidget inside QVBoxLayout and use "stretch" parameter in addWidgets method.

    The result using QVBoxLayout is more accurate.

    GraphicsLayoutWidget solution. enter image description here

    import sys
    from PyQt5 import QtWidgets, QtCore
    import pyqtgraph as pg
    
    
    class Draw_interface(QtWidgets.QMainWindow):
        def __init__(self):
    
            super(Draw_interface, self).__init__()
      
            # Add two charts
            self.my_draw = pg.GraphicsLayoutWidget(show=True)
            self.p1 = self.my_draw.addPlot(row=0, col=0, rowspan = 3)
            self.p2 = self.my_draw.addPlot(row=3, col=0)
    
            # Add label with no text to take up spaces of the next column 
            self.p3 = self.my_draw.addLabel(text='',row=0, col=1)
            self.p4 = self.my_draw.addLabel(text='',row=1, col=1)
            self.p5 = self.my_draw.addLabel(text='',row=2, col=1)
            self.p6 = self.my_draw.addLabel(text='',row=3, col=1)
            
            # Draw charts
            y = [2.2, 3.0, 1.3, 2.5, 1.9, 2.2, 5.5, 6.6]
            y2 = [2.3, 3.3, 2.8, 2.2, 3.3, 3.1, 2.8, 4.4]
            self.p1.plot(y)
            self.p2.plot(y2)
            self.setCentralWidget(self.my_draw)
            
        
    def main():
        QtWidgets.QApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
        app = QtWidgets.QApplication(sys.argv)
        
        main = Draw_interface()
        main.show()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()
    

    QVBoxLayout solution. enter image description here

    import sys
    from PyQt5 import QtWidgets, QtCore
    import pyqtgraph as pg
    
    
    class Draw_interface(QtWidgets.QMainWindow):
        def __init__(self):
    
            super(Draw_interface, self).__init__()
      
            # Add two charts
            p1 = pg.PlotWidget(name = "Plot1")
            p2 = pg.PlotWidget(name = "Plot2")
            
            # Draw charts
            y = [2.2, 3.0, 1.3, 2.5, 1.9, 2.2, 5.5, 6.6]
            y2 = [2.3, 3.3, 2.8, 2.2, 3.3, 3.1, 2.8, 4.4]
            p1.plot(y)
            p2.plot(y2)
    
            l = QtWidgets.QVBoxLayout()
            l.addWidget(p1, stretch=3)
            l.addWidget(p2, stretch=1)
    
            w = QtWidgets.QWidget()
            w.setLayout(l)
            self.setCentralWidget(w)
            self.setStyleSheet("QWidget { background-color: black; }")
        
    def main():
        QtWidgets.QApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
        app = QtWidgets.QApplication(sys.argv)
        
        main = Draw_interface()
        main.show()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()