Customizing the Size of a PyQtGraph Plot

Control where and how large your PyQtGraph plots appear in your PyQt5 application
Heads up! You've already completed this tutorial.

All the PyQtGraph examples I've seen use setCentralWidget to display the plot, which makes it fill the entire window. How can I control the size and placement of a PyQtGraph plot so it sits alongside other widgets in my application?

When you first start using PyQtGraph with PyQt5, most examples show you setting the plot as the central widget of your main window using self.setCentralWidget(self.graphWidget). This works great for quick demos, but it makes the plot fill the entire window — which isn't what you want when you're building a real application with buttons, labels, and other widgets alongside your graph.

In this tutorial, you'll learn how to control the size and placement of PyQtGraph plots so they fit neatly into your application layout. We'll cover how to embed plots using code-only layouts and how to use Qt Designer to get pixel-perfect control over your graph's size and position.

Why setCentralWidget Takes Over the Window

When you call self.setCentralWidget(self.graphWidget), you're telling the QMainWindow that the plot widget is the central content of the window. Everything else gets pushed aside or hidden. The plot expands to fill all available space.

That's fine for a single-purpose plotting app, but most applications need other widgets too. The solution is to place your plot widget inside a layout alongside your other widgets, just like you would with any other Qt widget.

Embedding a PyQtGraph Plot in a Layout

PyQtGraph's PlotWidget is a regular Qt widget. You can add it to any layout — QVBoxLayout, QHBoxLayout, QGridLayout — just like a QPushButton or QLabel. Here's a complete example that places a plot alongside some controls:

python
import sys

from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QVBoxLayout, QHBoxLayout, QPushButton, QLabel
)
import pyqtgraph as pg


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQtGraph in a Layout")

        # Create the central widget and main layout.
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # Add a label at the top.
        label = QLabel("My Application with a Graph")
        main_layout.addWidget(label)

        # Create the PyQtGraph plot widget and add it to the layout.
        self.graph_widget = pg.PlotWidget()
        main_layout.addWidget(self.graph_widget)

        # Add some buttons below the graph.
        button_layout = QHBoxLayout()
        button_layout.addWidget(QPushButton("Start"))
        button_layout.addWidget(QPushButton("Stop"))
        main_layout.addLayout(button_layout)

        # Plot some example data.
        self.graph_widget.plot([1, 3, 2, 5, 4, 6, 7], pen="r")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

Here we set a plain QWidget as the central widget and give it a QVBoxLayout. The PlotWidget is just one widget among several in that layout. The graph shares the window with the label and buttons.

Controlling the Plot Size with Fixed Dimensions

If you want your graph to be a specific size rather than stretching to fill available space, you can set fixed or maximum dimensions on the PlotWidget using the same methods available on any QWidget:

python
# Set a fixed size (width, height) in pixels.
self.graph_widget.setFixedSize(400, 300)

Or if you want the plot to resize but only up to a certain limit:

python
# Set minimum and maximum sizes.
self.graph_widget.setMinimumSize(300, 200)
self.graph_widget.setMaximumSize(600, 400)

Here's a complete example with a fixed-size graph:

python
import sys

from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QVBoxLayout, QHBoxLayout, QPushButton, QLabel
)
import pyqtgraph as pg


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Fixed-Size Graph")

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        label = QLabel("This graph has a fixed size of 400x300 pixels")
        main_layout.addWidget(label)

        self.graph_widget = pg.PlotWidget()
        self.graph_widget.setFixedSize(400, 300)
        main_layout.addWidget(self.graph_widget)

        button_layout = QHBoxLayout()
        button_layout.addWidget(QPushButton("Start"))
        button_layout.addWidget(QPushButton("Stop"))
        main_layout.addLayout(button_layout)

        self.graph_widget.plot([1, 3, 2, 5, 4, 6, 7], pen="g")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

The graph stays at exactly 400×300 pixels regardless of how you resize the window. The other widgets flow around it as the layout dictates.

Using Stretch Factors to Control Proportions

Another approach is to let the layout handle sizing proportionally using stretch factors. Instead of locking to exact pixel values, you can control how much of the available space each widget gets:

python
import sys

from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QVBoxLayout, QPushButton, QLabel
)
import pyqtgraph as pg


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Stretch Factor Graph")

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        label = QLabel("The graph takes up about 2/3 of the vertical space")
        main_layout.addWidget(label, stretch=0)

        self.graph_widget = pg.PlotWidget()
        main_layout.addWidget(self.graph_widget, stretch=2)

        button = QPushButton("Do something")
        main_layout.addWidget(button, stretch=0)

        # Add a second graph that gets less space.
        self.graph_widget_2 = pg.PlotWidget()
        main_layout.addWidget(self.graph_widget_2, stretch=1)

        self.graph_widget.plot([1, 3, 2, 5, 4, 6, 7], pen="r")
        self.graph_widget_2.plot([7, 6, 4, 5, 2, 3, 1], pen="b")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

The stretch=2 on the first graph and stretch=1 on the second means the first graph gets twice as much vertical space as the second. Widgets with stretch=0 take only the space they need. This gives you proportional sizing that adapts nicely when the window is resized.

Using Qt Designer to Place and Size Your Graph

Qt Designer gives you visual control over widget placement and sizing, which can be much easier than tweaking numbers in code. Since PlotWidget is a PyQtGraph class and not part of the standard Qt widget set, you'll add it to your design using widget promotion.

Setting Up the Design

Open Qt Designer and create a new Main Window. Then:

  1. Drag a Graphics View (QGraphicsView) widget from the widget box onto your form. Position and resize it however you like — this is where your graph will appear.

  2. Add any other widgets you need (buttons, labels, etc.) and arrange everything using layouts. You can right-click the main window background and select Lay Out Vertically or Lay Out Horizontally to apply a layout to the whole window.

  3. If you want the QGraphicsView to be a specific size, select it and set the minimumSize and maximumSize properties in the Property Editor. To lock it at a fixed size, set both to the same value.

Promoting the Widget to PlotWidget

Now you need to tell Qt Designer that this QGraphicsView should actually become a PyQtGraph PlotWidget at runtime:

  1. Right-click the QGraphicsView and select Promote to....

  2. In the dialog, fill in:

  3. Promoted class name: PlotWidget
  4. Header file: pyqtgraph

  5. Click Add, then click Promote.

The QGraphicsView now shows as a PlotWidget in the Object Inspector. Save your .ui file (for example, as mainwindow.ui).

Loading the Design in Python

You can load the .ui file directly using uic.loadUi. Here's a complete example assuming you saved your design as mainwindow.ui with a promoted PlotWidget whose object name is graphWidget:

python
import sys

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("mainwindow.ui", self)

        # Access the promoted PlotWidget by its object name.
        self.graphWidget.plot([1, 3, 2, 5, 4, 6, 7], pen="r")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

The graph appears exactly where you placed it in Qt Designer, at the size you specified. All the size constraints and layout behavior you set up visually are preserved at runtime.

Setting Size Constraints in Qt Designer

To get fine-grained control over the graph's size in Qt Designer, select the promoted widget and look at the Property Editor on the right. The properties you'll find most useful are:

Property What it does
minimumSize The smallest the widget can be
maximumSize The largest the widget can be
sizePolicy How the widget behaves when extra space is available

For a fixed-size graph, set minimumSize and maximumSize to the same width and height. For a graph that resizes but stays within bounds, set them to different values.

The sizePolicy property controls how eager the widget is to grow or shrink relative to its neighbors. Setting the vertical or horizontal policy to Fixed means the widget won't resize in that direction. Expanding means it will try to take extra space when available. Preferred means it'll take its preferred size but can be resized if needed.

A Complete Example

Here's a final complete example that demonstrates a more realistic application layout with a sized graph, built entirely in code:

python
import sys

from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QVBoxLayout, QHBoxLayout,
    QPushButton, QLabel, QSpinBox, QGroupBox
)
from PyQt5.QtCore import Qt
import pyqtgraph as pg
import numpy as np


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Data Viewer")
        self.resize(800, 500)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Main horizontal layout: controls on left, graph on right.
        main_layout = QHBoxLayout(central_widget)

        # Left panel with controls.
        controls_group = QGroupBox("Controls")
        controls_layout = QVBoxLayout()
        controls_group.setLayout(controls_layout)

        controls_layout.addWidget(QLabel("Number of points:"))
        self.points_spin = QSpinBox()
        self.points_spin.setRange(10, 1000)
        self.points_spin.setValue(50)
        controls_layout.addWidget(self.points_spin)

        update_button = QPushButton("Update Plot")
        update_button.clicked.connect(self.update_plot)
        controls_layout.addWidget(update_button)

        controls_layout.addStretch()

        # Set the controls panel to a fixed width.
        controls_group.setFixedWidth(200)
        main_layout.addWidget(controls_group)

        # Right side: graph takes remaining space.
        right_layout = QVBoxLayout()

        self.graph_widget = pg.PlotWidget()
        self.graph_widget.setBackground("w")
        self.graph_widget.setTitle("Random Data", color="k")
        self.graph_widget.setLabel("left", "Value")
        self.graph_widget.setLabel("bottom", "Sample")
        right_layout.addWidget(self.graph_widget)

        self.status_label = QLabel("Ready")
        self.status_label.setAlignment(Qt.AlignRight)
        right_layout.addWidget(self.status_label)

        main_layout.addLayout(right_layout, stretch=1)

        # Initial plot.
        self.update_plot()

    def update_plot(self):
        n_points = self.points_spin.value()
        data = np.random.normal(size=n_points).cumsum()
        self.graph_widget.clear()
        self.graph_widget.plot(data, pen=pg.mkPen("b", width=2))
        self.status_label.setText(f"Showing {n_points} points")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

This creates a window with a fixed-width control panel on the left and an expanding graph area on the right. The graph fills the remaining space while the controls stay at 200 pixels wide. The status label sits below the graph and takes minimal vertical space.

The same layout could be built visually in Qt Designer using the widget promotion technique described earlier — just drag your widgets into position, apply layouts, set your size constraints, and promote the QGraphicsView to PlotWidget. For a more detailed introduction to PyQtGraph plotting, see our Plotting with PyQtGraph tutorial, and for embedding promoted PyQtGraph widgets into your own custom applications, take a look at Embedding PyQtGraph custom widgets in a Qt app.

Whether you prefer code or Qt Designer, the core idea is the same: treat PlotWidget like any other Qt widget, place it in a layout, and use standard Qt sizing tools to control how much space it gets.

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Packaging Python Applications with PyInstaller by Martin Fitzpatrick

This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.

More info Get the book

Martin Fitzpatrick

Customizing the Size of a PyQtGraph Plot was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.