pyqt5paddingmarginpysidepyqtgraph

How do I add padding around a PyQtGraph PlotWidget?


I am trying to add padding around a PlotWidget as the default settings are extremely tight. However, the strategies I am trying to take are not working. The default padding is seen below.

default padding for a PlotWidget in PyQt

This is generated using the following code:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from  PySide6.QtGui import QFont
import pyqtgraph as pg
import numpy as np

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create a PlotWidget
        self.graph_widget = pg.PlotWidget()
        self.graph_widget.setBackground('w')

        self.graph_widget.plotItem.setLabel('bottom', "Time(s)")
        self.graph_widget.plotItem.setLabel('left', "Speed (m/s)")

        # Setting graph styles for readability
        self.set_axis_styles('bottom')
        self.set_axis_styles('left')

        # Create a generic curve
        self.create_parabola()

        # Set the central widget of the main window
        self.setCentralWidget(self.graph_widget)

    def set_axis_styles(self, axis_name:str):
        axis_font = QFont()
        axis_font.setPointSize(12)

        axis_item = self.graph_widget.getAxis(axis_name)
        axis_item.setStyle(tickFont=axis_font, tickLength=-10)
        axis_item.label.setFont(axis_font)
        axis_item.setTextPen('k')
        axis_item.setTickPen('k')
        axis_item.setPen('k')

    def create_parabola(self):
        x = np.linspace(-10, 10, 100)
        y = x**2
        mask = y >= 0
        x = x[mask]
        y = y[mask]
        self.graph_widget.plot(x, y, pen='r')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

I tried to set the style sheet of the PlotWidget object to specify a padding of 20px, as shown in the code below:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create a PlotWidget
        self.graph_widget = pg.PlotWidget()
        self.graph_widget.setBackground('w')

        self.graph_widget.plotItem.setLabel('bottom', "Time(s)")
        self.graph_widget.plotItem.setLabel('left', "Speed (m/s)")
        
        # Set the style sheet for the graphing widget
        self.graph_widget.setStyleSheet("""
            QWidget {
                padding: 20px;
                background-color: white;
            }"""
        )

        # Setting graph styles for readability
        self.set_axis_styles('bottom')
        self.set_axis_styles('left')

        # Create a generic curve
        self.create_parabola()

        # Set the central widget of the main window
        self.setCentralWidget(self.graph_widget)

When I run the code, the padding is indeed added, but the graph becomes a scrollable object where the bottom and right of the graph are cut off. Resizing the window does not fix this issue either.

PlotWidget with padding added

I then decided to replace padding with margins to the style sheet instead, however that also cuts off the graph. Furthermore, I want the color of the margins to match the color of the graph (i.e. white), which it is not doing.
PlotWidget with margins added

How can I get padding around my graph in PyQtGraph?


Solution

  • I used @musicamante's comment to solve the issue. By using a generic QWidget as a container for my graph, I was able to set the margins around the graph without cutting anything off.

    However, since I wanted padding and not margins, I set the graphing container's background to be white using the SetStyleSheet method, which now gives the illusion of a 20px padding all around the graph.

    PlotWidget with a "padding" of 20px

    from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
    from  PySide6.QtGui import QFont, Qt
    import pyqtgraph as pg
    import numpy as np
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
    
            self.graph_container = QWidget() # Container to hold the PlotWidget
            self.graph_container.setObjectName("grapher")
    
            # Create a PlotWidget
            self.graph_widget = pg.PlotWidget()
            self.graph_widget.setBackground('w')
    
            self.graph_widget.plotItem.setLabel('bottom', "Time(s)")
            self.graph_widget.plotItem.setLabel('left', "Speed (m/s)")
    
            # Setting graph styles for readability
            self.set_axis_styles('bottom')
            self.set_axis_styles('left')
    
            # Create a generic curve
            self.create_parabola()
    
              # Style Sheet for the PlotWidget container
            self.graph_container.setStyleSheet(
            '''QWidget#grapher {
                background-color: white
            }
            ''')
    
            # Graph Widget Layout
            graph_layout = QVBoxLayout()
            graph_layout.addWidget(self.graph_widget)
            graph_layout.setContentsMargins(20,20,20,20)
            self.graph_container.setLayout(graph_layout)
    
            # Set the central widget of the main window
            self.setCentralWidget(self.graph_container)
    
        def set_axis_styles(self, axis_name:str):
            axis_font = QFont()
            axis_font.setPointSize(12)
    
            axis_item = self.graph_widget.getAxis(axis_name)
            axis_item.setStyle(tickFont=axis_font, tickLength=-10)
            axis_item.label.setFont(axis_font)
            axis_item.setTextPen('k')
            axis_item.setTickPen('k')
            axis_item.setPen('k')
    
        def create_parabola(self):
            x = np.linspace(-10, 10, 100)
            y = x**2
            mask = y >= 0
            x = x[mask]
            y = y[mask]
            self.graph_widget.plot(x, y, pen='r')
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())