Matplotlib嵌套PyQt5设置

Matplotlib嵌套PyQt5子图设置

一.创建子图的方式:

# 示例1:
self.figure, self.axes = plt.subplots(2, 2)  # plt.subplots(2, 2)创建一个包含 2 行 2 列的子图网格,返回一个 Figure 对象和一个 axes 数组

# 示例2:add_subplot()的标准网格形式
self.fig = plt.figure()
self.ax1 = self.fig.add_subplot(2, 2, 1)  # 2x2 网格中的第一个位置
self.ax2 = self.fig.add_subplot(2, 2, 2)  # 2x2 网格中的第二个位置
self.ax3 = self.fig.add_subplot(2, 2, 3)  # 2x2 网格中的第三个位置
self.ax4 = self.fig.add_subplot(2, 2, 4)  # 2x2 网格中的第四个位置

# 示例3:add_subplot(),通过位置的列表或元组
self.fig = plt.figure()
self.ax1 = self.fig.add_subplot(221)  # 等价于 fig.add_subplot(2, 2, 1)
self.ax2 = self.fig.add_subplot(222)  # 等价于 fig.add_subplot(2, 2, 2)
self.ax3 = self.fig.add_subplot(223)  # 等价于 fig.add_subplot(2, 2, 3)
self.ax4 = self.fig.add_subplot(224)  # 等价于 fig.add_subplot(2, 2, 4)

# 示例4:add_subplot(),通过GridSpec对象
import matplotlib.gridspec as gridspec
self.fig = plt.figure()
gs = gridspec.GridSpec(2, 2)
self.ax1 = self.fig.add_subplot(gs[0, 0])  # 第一行第一列
self.ax2 = self.fig.add_subplot(gs[0, 1])  # 第一行第二列
self.ax3 = self.fig.add_subplot(gs[1, 0])  # 第二行第一列
self.ax4 = self.fig.add_subplot(gs[1, 1])  # 第二行第二列

1.subplots():

subplots()matplotlib.pyplot 模块的一个函数,它用于创建一个图形对象,并在其中同时创建多个子图。这个方法返回一个 Figure 对象和一个包含所有子图的 Axes 对象的数组

参数:

  • nrows(int): 子图的行数。
  • ncols(int): 子图的列数。
  • figsize(tuple): 图形的宽度和高度。
  • sharex(bool 或 str): 是否共享 x 轴。
  • sharey(bool 或 str): 是否共享 y 轴。
  • subplot_kw(dict): 传递给每个子图的参数。
  • gridspec_kw(dict): 传递给 GridSpec 的参数。

返回:

  • fig(Figure): 图形对象。
  • axes(ndarray of Axes): Axes 对象的数组。

2.add_subplot():

add_subplot() 方法是 Figure 类的一部分,它用于在一个图形对象上添加子图。每个子图都是一个 Axes 对象,提供了绘制图形的功能

参数:

  • nrows(int): 子图的行数。
  • ncols(int): 子图的列数。
  • index(int): 子图的索引,从左到右,从上到下的顺序。

返回:

  • 返回一个 Axes 对象

二.设置子图:

统一设置子图示例:

for ax in self.axes.flat:
# for ax in self.axes.flatten():
    ax.set_facecolor('lightblue')

self.ax.flatten()和self.ax.flat这两种方法都自动迭代self.axs数组中的所有Axes对象,self.axs.flat提供一个迭代器,而self.axs.flatten()返回一个一维数组。推荐使用self.axes.flat

单独设置子图示例:

self.axs[0, 0].set_facecolor('lightblue')
self.axs[0, 1].set_facecolor('gray')
self.axs[1, 0].set_facecolor('lightpink')
self.axs[1, 1].set_facecolor('green')

三.调整子图间距:

self.figure.tight_layout()用于自动调整子图参数,以便子图更好地适应图形区域。这在某些情况下是有用的,特别是当子图或图形标签重叠时。然而,不是每次都必须使用。

什么时候需要用?

  • 子图重叠或者空间不足:间距太小导致标签、标题或轴标签重叠时,tight_layout()可以自动调整子图的布局,以避免这些重叠问题
  • 动态调整布局:如果图形是动态生成的,子图内容可能会变化,tight_layout()可以确保每次生成图形时子图都能良好地适应图形区域

什么时候不需要?

  • 手动调整间距:已经使用GridSpec或其他方法手动调整了子图之间的间距,并且布局已经不需要再更改时
  • 固定布局:图形布局固定且不会因为内容变化而需要调整时

四.示例代码

plt_embed_pyqt5.py:

import sys
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.gridspec import GridSpec
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLineEdit, QLabel, QHBoxLayout

# 让图片可以显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
# 让图片可以显示负号
plt.rcParams['axes.unicode_minus'] = False

class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)

        # 创建一个垂直布局
        main_layout = QVBoxLayout(self)

        # 创建一个 Matplotlib 图形对象
        self.figure = plt.figure(figsize=(10, 8))
        self.canvas = FigureCanvas(self.figure)

        main_layout.addWidget(self.canvas)

        # 调用绘制函数
        self.draw_picture1()

    def draw_picture1(self):
        # 使用gridspec_kw,手动调整子图间距
        self.axes = self.figure.subplots(2, 2, gridspec_kw={'wspace':0.4, 'hspace':0.4})

        # 绘制第一个子图:折线图
        self.axes[0, 0].plot([1, 2, 3], [4, 5, 6])
        self.axes[0, 0].set_title('折线图')

        # 绘制第二个子图:条形图
        self.axes[0, 1].bar(['A', 'B', 'C'], [7, 8, 9])
        self.axes[0, 1].set_title('条形图')

        # 绘制第三个子图:散点图
        self.axes[1, 0].scatter([1, 2, 3], [4, 5, 6])
        self.axes[1, 0].set_title('散点图')

        # 绘制第四个子图:饼图
        sizes = [15, 30, 45, 10]
        labels = ['A', 'B', 'C', 'D']
        self.axes[1, 1].pie(sizes, labels=labels, autopct='%1.1f%%')
        self.axes[1, 1].set_title('饼图')

        # 绘制图形
        self.canvas.draw()

    def draw_picture2(self):
        # 使用 GridSpec 分成四等份,手动调整子图间距
        gs = GridSpec(2, 2, figure=self.figure, wspace=0.4, hspace=0.4)
        # 创建子图数组
        self.axes = [
            self.figure.add_subplot(gs[0, 0]),
            self.figure.add_subplot(gs[0, 1]),
            self.figure.add_subplot(gs[1, 0]),
            self.figure.add_subplot(gs[1, 1])
        ]

        # 绘制第一个子图:折线图
        self.axes[0].plot([1, 2, 3], [4, 5, 6])
        self.axes[0].set_title('折线图')

        # 绘制第二个子图:条形图
        self.axes[1].bar(['A', 'B', 'C'], [7, 8, 9])
        self.axes[1].set_title('条形图')

        # 绘制第三个子图:散点图
        self.axes[2].scatter([1, 2, 3], [4, 5, 6])
        self.axes[2].set_title('散点图')

        # 绘制第四个子图:饼图
        sizes = [15, 30, 45, 10]
        labels = ['A', 'B', 'C', 'D']
        self.axes[3].pie(sizes, labels=labels, autopct='%1.1f%%')
        self.axes[3].set_title('饼图')
        # 绘制图形
        self.canvas.draw()

    def draw_picture3(self):
        # 不手动调整间距时,用self.figure.tight_layout()自动调整子图参数避免子图重叠
        self.axes = self.figure.subplots(2, 2)

        # 绘制第一个子图:折线图
        self.axes[0, 0].plot([1, 2, 3], [4, 5, 6])
        self.axes[0, 0].set_title('折线图')

        # 绘制第二个子图:条形图
        self.axes[0, 1].bar(['A', 'B', 'C'], [7, 8, 9])
        self.axes[0, 1].set_title('条形图')

        # 绘制第三个子图:散点图
        self.axes[1, 0].scatter([1, 2, 3], [4, 5, 6])
        self.axes[1, 0].set_title('散点图')

        # 绘制第四个子图:饼图
        sizes = [15, 30, 45, 10]
        labels = ['A', 'B', 'C', 'D']
        self.axes[1, 1].pie(sizes, labels=labels, autopct='%1.1f%%')
        self.axes[1, 1].set_title('饼图')

        # 绘制图形
        self.figure.tight_layout()
        self.canvas.draw()



class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        # 设置窗口标题和大小
        self.setWindowTitle('Matplotlib in PyQt5')
        self.setGeometry(100, 100, 800, 600)
        # 创建 MatplotlibWidget 实例
        self.matplotlib_widget = MatplotlibWidget(self)
        # 设置中心部件和布局
        self.setCentralWidget(self.matplotlib_widget)


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

运行效果:
在这里插入图片描述

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在PyQt5中嵌入Matplotlib图形,可以使用`FigureCanvas`类和`NavigationToolbar`类。以下是一个简单的示例代码: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.figure import Figure class MainWindow(QMainWindow): def __init__(self): super().__init__() # 创建一个Matplotlib图形 self.figure = Figure() self.canvas = FigureCanvas(self.figure) # 创建一个导航工具栏 self.toolbar = NavigationToolbar(self.canvas, self) # 创建一个垂直布局,并将图形和工具栏添加进去 layout = QVBoxLayout() layout.addWidget(self.canvas) layout.addWidget(self.toolbar) # 创建一个QWidget作为主窗口的中心部件 widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) # 绘制Matplotlib图形 self.plot() def plot(self): # 在Matplotlib图形上绘制一些内容 ax = self.figure.add_subplot(111) ax.plot([1, 2, 3, 4], [1, 4, 9, 16]) ax.set_title('Matplotlib Plot') ax.set_xlabel('X-axis') ax.set_ylabel('Y-axis') self.canvas.draw() if __name__ == '__main__': app = QApplication(sys.argv) mainWindow = MainWindow() mainWindow.show() sys.exit(app.exec_()) ``` 在这个示例中,我们创建了一个`MainWindow`类作为主窗口,并在其中嵌入了一个Matplotlib图形。我们使用`FigureCanvas`类将Matplotlib图形添加到PyQt5窗口中,并使用`NavigationToolbar`类添加一个导航工具栏。然后,我们在`plot`方法中绘制了一个简单的Matplotlib图形。 要运行这个示例,确保你已经安装了PyQt5Matplotlib库,并将以上代码保存在一个Python脚本文件中,然后运行该脚本即可看到嵌入了Matplotlib图形的PyQt5窗口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值