PyQt5 GUI与pyqtgraph绘图不更新问题及多图添加咨询
Hey there, let's work through your PyQt5 + pyqtgraph problems together!
First up, let's figure out why your curve isn't showing up even though the axes are there. Here are the most common fixes to check:
- Verify your data is valid: Before plotting, print out your
xandyarrays (e.g.,print(self.x_data, self.y_data)) to make sure they're not empty, full of NaNs, or zero-length. If you're reading from serial, double-check that the data is being parsed correctly into numerical values. - Ensure your PlotWidget is properly integrated with the UI:
- If you used Qt Designer, did you promote a QWidget to
pyqtgraph.PlotWidget? If not, you can either do that in Designer (right-click the widget > Promote to...) or manually create the PlotWidget in code and add it to your layout:self.plot_widget = pg.PlotWidget() self.your_layout_name.addWidget(self.plot_widget) # Replace with your actual layout from Qt Designer
- If you used Qt Designer, did you promote a QWidget to
- Check your plotting logic:
- When initializing, make sure you're creating a CurveItem and storing it (so you can update it later). For example:
# Inside your button click slot self.x_data = np.linspace(0, 10, 100) self.y_data = np.sin(self.x_data) # First plot: create the curve if not hasattr(self, 'curve'): self.curve = self.plot_widget.plot(self.x_data, self.y_data, pen='red') # Subsequent updates: reuse the existing curve else: self.curve.setData(self.x_data, self.y_data)
- When initializing, make sure you're creating a CurveItem and storing it (so you can update it later). For example:
- Force UI updates: Sometimes Qt needs a nudge to refresh the plot. Add
self.plot_widget.repaint()orQtWidgets.QApplication.processEvents()after setting the data. - Thread safety (if using serial): If you're reading serial data in a separate thread, never update the plot directly from the thread. Use Qt's signal-slot system to send data to the main thread, where you can safely update the curve. Example:
# In your worker thread class data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray) def run(self): # Read serial data, parse into x and y self.data_ready.emit(x_data, y_data) # In your main window class self.thread = SerialWorker() self.thread.data_ready.connect(self.update_plot) self.thread.start() def update_plot(self, x, y): self.curve.setData(x, y)
For adding multiple plots in the same window, pyqtgraph has two great options depending on your needs:
Option 1: Use pg.GraphicsLayoutWidget (Recommended)
This is pyqtgraph's built-in container for arranging multiple plots, and it's perfect for creating grids of plots or shared-axis layouts.
- If using Qt Designer: Promote a QWidget to
pyqtgraph.GraphicsLayoutWidget, then in code:# Get the promoted widget from your UI self.graphics_layout = self.your_promoted_widget # Add first plot plot1 = self.graphics_layout.addPlot(title="Sine Wave") plot1.plot(np.linspace(0,10,100), np.sin(np.linspace(0,10,100)), pen='red') # Move to next row and add second plot self.graphics_layout.nextRow() plot2 = self.graphics_layout.addPlot(title="Cosine Wave") plot2.plot(np.linspace(0,10,100), np.cos(np.linspace(0,10,100)), pen='blue') # Add a plot to the right of plot2 self.graphics_layout.nextCol() plot3 = self.graphics_layout.addPlot(title="Random Data") plot3.plot(np.random.randn(100), pen='green') - You can also share axes between plots (e.g.,
plot2.setXLink(plot1)to sync the x-axis with plot1).
Option 2: Use Qt Layouts (Flexible Customization)
If you need more control over plot sizes or positioning (e.g., different-sized plots), use Qt's standard layouts like QGridLayout or QHBoxLayout with individual pg.PlotWidgets:
# Create a grid layout grid_layout = QtWidgets.QGridLayout() self.centralwidget.setLayout(grid_layout) # Add plots to the grid plot1 = pg.PlotWidget(title="Plot 1") grid_layout.addWidget(plot1, 0, 0) plot2 = pg.PlotWidget(title="Plot 2") grid_layout.addWidget(plot2, 0, 1) plot3 = pg.PlotWidget(title="Plot 3") grid_layout.addWidget(plot3, 1, 0, 1, 2) # Span both columns
One final tip: Always avoid modifying the auto-generated code from Qt Designer directly. Instead, create a subclass that inherits from both your UI class and QMainWindow/QWidget, then set up your logic there. This makes it easier to re-generate the UI code later without losing your changes.
内容的提问来源于stack exchange,提问作者Mario Andres Gomez

